mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
qemu: domain: Drop added features from migratable CPU
Features marked with added='yes' in CPU model definitions have to be removed before migration, otherwise older libvirt would complain about unknown CPU features. We only do this for features that were enabled for a given CPU model even with older libvirt, which just ignored the features. And only for features we added ourselves when updating CPU definition during domain startup, that is we do not remove features which were explicitly mentioned by a user. That said, this is not the safest thing we could do, but it's effectively the same thing we did before the affected features were added: we ignored them completely on both sides of migration. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Tim Wiederhake <twiederh@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
577c4ca414
commit
14d3517410
@ -66,6 +66,7 @@
|
|||||||
#include "backup_conf.h"
|
#include "backup_conf.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
#include "virsecureerase.h"
|
#include "virsecureerase.h"
|
||||||
|
#include "cpu/cpu_x86.h"
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -6643,10 +6644,36 @@ qemuDomainDefCopy(virQEMUDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char * const *added;
|
||||||
|
GStrv keep;
|
||||||
|
} qemuDomainDropAddedCPUFeaturesData;
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
qemuDomainDropAddedCPUFeatures(const char *name,
|
||||||
|
virCPUFeaturePolicy policy G_GNUC_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
qemuDomainDropAddedCPUFeaturesData *data = opaque;
|
||||||
|
|
||||||
|
if (!g_strv_contains(data->added, name))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (data->keep && g_strv_contains((const char **) data->keep, name))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuDomainMakeCPUMigratable(virArch arch,
|
qemuDomainMakeCPUMigratable(virArch arch,
|
||||||
virCPUDef *cpu)
|
virCPUDef *cpu,
|
||||||
|
virCPUDef *origCPU)
|
||||||
{
|
{
|
||||||
|
qemuDomainDropAddedCPUFeaturesData data = { 0 };
|
||||||
|
|
||||||
if (cpu->mode != VIR_CPU_MODE_CUSTOM ||
|
if (cpu->mode != VIR_CPU_MODE_CUSTOM ||
|
||||||
!cpu->model ||
|
!cpu->model ||
|
||||||
!ARCH_IS_X86(arch))
|
!ARCH_IS_X86(arch))
|
||||||
@ -6664,6 +6691,25 @@ qemuDomainMakeCPUMigratable(virArch arch,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virCPUx86GetAddedFeatures(cpu->model, &data.added) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Drop features marked as added in a cpu model, but only
|
||||||
|
* when they are not mentioned in origCPU, i.e., when they were not
|
||||||
|
* explicitly mentioned by the user.
|
||||||
|
*/
|
||||||
|
if (data.added) {
|
||||||
|
g_auto(GStrv) keep = NULL;
|
||||||
|
|
||||||
|
if (origCPU) {
|
||||||
|
keep = virCPUDefListExplicitFeatures(origCPU);
|
||||||
|
data.keep = keep;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virCPUDefFilterFeatures(cpu, qemuDomainDropAddedCPUFeatures, &data) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6843,7 +6889,7 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (def->cpu &&
|
if (def->cpu &&
|
||||||
qemuDomainMakeCPUMigratable(def->os.arch, def->cpu) < 0)
|
qemuDomainMakeCPUMigratable(def->os.arch, def->cpu, origCPU) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Old libvirt doesn't understand <audio> elements so
|
/* Old libvirt doesn't understand <audio> elements so
|
||||||
|
@ -1049,7 +1049,8 @@ qemuDomainSupportsCheckpointsBlockjobs(virDomainObj *vm)
|
|||||||
|
|
||||||
int
|
int
|
||||||
qemuDomainMakeCPUMigratable(virArch arch,
|
qemuDomainMakeCPUMigratable(virArch arch,
|
||||||
virCPUDef *cpu);
|
virCPUDef *cpu,
|
||||||
|
virCPUDef *origCPU);
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuDomainInitializePflashStorageSource(virDomainObj *vm,
|
qemuDomainInitializePflashStorageSource(virDomainObj *vm,
|
||||||
|
@ -540,12 +540,15 @@ static int
|
|||||||
qemuMigrationCookieAddCPU(qemuMigrationCookie *mig,
|
qemuMigrationCookieAddCPU(qemuMigrationCookie *mig,
|
||||||
virDomainObj *vm)
|
virDomainObj *vm)
|
||||||
{
|
{
|
||||||
|
qemuDomainObjPrivate *priv = vm->privateData;
|
||||||
|
|
||||||
if (mig->cpu)
|
if (mig->cpu)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mig->cpu = virCPUDefCopy(vm->def->cpu);
|
mig->cpu = virCPUDefCopy(vm->def->cpu);
|
||||||
|
|
||||||
if (qemuDomainMakeCPUMigratable(vm->def->os.arch, mig->cpu) < 0)
|
if (qemuDomainMakeCPUMigratable(vm->def->os.arch, mig->cpu,
|
||||||
|
priv->origCPU) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
mig->flags |= QEMU_MIGRATION_COOKIE_CPU;
|
mig->flags |= QEMU_MIGRATION_COOKIE_CPU;
|
||||||
|
Loading…
Reference in New Issue
Block a user