211 lines
6.6 KiB
Diff
211 lines
6.6 KiB
Diff
|
From: Jiri Denemark <jdenemar@redhat.com>
|
||
|
Date: Wed, 29 Mar 2017 15:31:17 +0200
|
||
|
Subject: [PATCH] qemu: Pass migratable host CPU model to virCPUUpdate
|
||
|
|
||
|
We already know from QEMU which CPU features will block migration. Let's
|
||
|
use this information to make a migratable copy of the host CPU model and
|
||
|
use it for updating guest CPU specification. This will allow us to drop
|
||
|
feature filtering from virCPUUpdate where it was just a hack.
|
||
|
|
||
|
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
||
|
(cherry picked from commit 56bd7edcb5dc878beffb80d4e6a9cfb812378ded)
|
||
|
---
|
||
|
src/qemu/qemu_capabilities.c | 57 +++++++++++++++++++++++++++++++++++++-------
|
||
|
src/qemu/qemu_capabilities.h | 2 ++
|
||
|
src/qemu/qemu_process.c | 2 +-
|
||
|
tests/cputest.c | 7 +++++-
|
||
|
4 files changed, 57 insertions(+), 11 deletions(-)
|
||
|
|
||
|
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
||
|
index a6324a398..7fc577546 100644
|
||
|
--- a/src/qemu/qemu_capabilities.c
|
||
|
+++ b/src/qemu/qemu_capabilities.c
|
||
|
@@ -384,6 +384,8 @@ struct _virQEMUCapsHostCPUData {
|
||
|
qemuMonitorCPUModelInfoPtr info;
|
||
|
/* Host CPU definition reported in domain capabilities. */
|
||
|
virCPUDefPtr reported;
|
||
|
+ /* Migratable host CPU definition used for updating guest CPU. */
|
||
|
+ virCPUDefPtr migratable;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
@@ -2100,6 +2102,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
|
||
|
!(dst->reported = virCPUDefCopy(src->reported)))
|
||
|
return -1;
|
||
|
|
||
|
+ if (src->migratable &&
|
||
|
+ !(dst->migratable = virCPUDefCopy(src->migratable)))
|
||
|
+ return -1;
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -2109,6 +2115,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
|
||
|
{
|
||
|
qemuMonitorCPUModelInfoFree(cpuData->info);
|
||
|
virCPUDefFree(cpuData->reported);
|
||
|
+ virCPUDefFree(cpuData->migratable);
|
||
|
|
||
|
memset(cpuData, 0, sizeof(*cpuData));
|
||
|
}
|
||
|
@@ -2447,6 +2454,9 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
||
|
switch (cpuType) {
|
||
|
case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
|
||
|
return cpuData->reported;
|
||
|
+
|
||
|
+ case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
|
||
|
+ return cpuData->migratable;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
@@ -2456,11 +2466,13 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
||
|
static void
|
||
|
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
|
||
|
virDomainVirtType type,
|
||
|
- virCPUDefPtr cpu)
|
||
|
+ virCPUDefPtr reported,
|
||
|
+ virCPUDefPtr migratable)
|
||
|
{
|
||
|
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
|
||
|
|
||
|
- cpuData->reported = cpu;
|
||
|
+ cpuData->reported = reported;
|
||
|
+ cpuData->migratable = migratable;
|
||
|
}
|
||
|
|
||
|
|
||
|
@@ -3307,26 +3319,39 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
|
||
|
}
|
||
|
|
||
|
|
||
|
+static virCPUDefPtr
|
||
|
+virQEMUCapsNewHostCPUModel(void)
|
||
|
+{
|
||
|
+ virCPUDefPtr cpu;
|
||
|
+
|
||
|
+ if (VIR_ALLOC(cpu) < 0)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ cpu->type = VIR_CPU_TYPE_GUEST;
|
||
|
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
|
||
|
+ cpu->match = VIR_CPU_MATCH_EXACT;
|
||
|
+ cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
|
||
|
+
|
||
|
+ return cpu;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
void
|
||
|
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
||
|
virCapsPtr caps,
|
||
|
virDomainVirtType type)
|
||
|
{
|
||
|
virCPUDefPtr cpu = NULL;
|
||
|
+ virCPUDefPtr migCPU = NULL;
|
||
|
virCPUDefPtr hostCPU = NULL;
|
||
|
int rc;
|
||
|
|
||
|
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
|
||
|
return;
|
||
|
|
||
|
- if (VIR_ALLOC(cpu) < 0)
|
||
|
+ if (!(cpu = virQEMUCapsNewHostCPUModel()))
|
||
|
goto error;
|
||
|
|
||
|
- cpu->type = VIR_CPU_TYPE_GUEST;
|
||
|
- cpu->mode = VIR_CPU_MODE_CUSTOM;
|
||
|
- cpu->match = VIR_CPU_MATCH_EXACT;
|
||
|
- cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
|
||
|
-
|
||
|
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
|
||
|
goto error;
|
||
|
} else if (rc == 1) {
|
||
|
@@ -3340,7 +3365,20 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
- virQEMUCapsSetHostModel(qemuCaps, type, cpu);
|
||
|
+ if (!(migCPU = virQEMUCapsNewHostCPUModel()))
|
||
|
+ goto error;
|
||
|
+
|
||
|
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
|
||
|
+ goto error;
|
||
|
+ } else if (rc == 1) {
|
||
|
+ VIR_DEBUG("CPU migratability not provided by QEMU");
|
||
|
+
|
||
|
+ virCPUDefFree(migCPU);
|
||
|
+ if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
|
||
|
|
||
|
cleanup:
|
||
|
virCPUDefFree(hostCPU);
|
||
|
@@ -3348,6 +3386,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
||
|
|
||
|
error:
|
||
|
virCPUDefFree(cpu);
|
||
|
+ virCPUDefFree(migCPU);
|
||
|
virResetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
||
|
index 88e27855b..31818c940 100644
|
||
|
--- a/src/qemu/qemu_capabilities.h
|
||
|
+++ b/src/qemu/qemu_capabilities.h
|
||
|
@@ -453,6 +453,8 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
|
||
|
typedef enum {
|
||
|
/* Host CPU definition reported in domain capabilities. */
|
||
|
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
|
||
|
+ /* Migratable host CPU definition used for updating guest CPU. */
|
||
|
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
|
||
|
} virQEMUCapsHostCPUType;
|
||
|
|
||
|
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
||
|
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||
|
index 07a88a3a7..e67736638 100644
|
||
|
--- a/src/qemu/qemu_process.c
|
||
|
+++ b/src/qemu/qemu_process.c
|
||
|
@@ -5306,7 +5306,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
|
||
|
|
||
|
if (virCPUUpdate(def->os.arch, def->cpu,
|
||
|
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
|
||
|
- VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
|
||
|
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
|
||
|
goto cleanup;
|
||
|
|
||
|
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
|
||
|
diff --git a/tests/cputest.c b/tests/cputest.c
|
||
|
index 8c07cf4f6..efa891dc1 100644
|
||
|
--- a/tests/cputest.c
|
||
|
+++ b/tests/cputest.c
|
||
|
@@ -393,6 +393,7 @@ cpuTestUpdate(const void *arg)
|
||
|
const struct data *data = arg;
|
||
|
int ret = -1;
|
||
|
virCPUDefPtr host = NULL;
|
||
|
+ virCPUDefPtr migHost = NULL;
|
||
|
virCPUDefPtr cpu = NULL;
|
||
|
char *result = NULL;
|
||
|
|
||
|
@@ -400,7 +401,10 @@ cpuTestUpdate(const void *arg)
|
||
|
!(cpu = cpuTestLoadXML(data->arch, data->name)))
|
||
|
goto cleanup;
|
||
|
|
||
|
- if (virCPUUpdate(host->arch, cpu, host) < 0)
|
||
|
+ if (!(migHost = virCPUCopyMigratable(data->arch, host)))
|
||
|
+ goto cleanup;
|
||
|
+
|
||
|
+ if (virCPUUpdate(host->arch, cpu, migHost) < 0)
|
||
|
goto cleanup;
|
||
|
|
||
|
if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
|
||
|
@@ -411,6 +415,7 @@ cpuTestUpdate(const void *arg)
|
||
|
cleanup:
|
||
|
virCPUDefFree(host);
|
||
|
virCPUDefFree(cpu);
|
||
|
+ virCPUDefFree(migHost);
|
||
|
VIR_FREE(result);
|
||
|
return ret;
|
||
|
}
|