|
|
3e5111 |
From ea1a18cc0a5722b64c37c79bee7b9ed3c220ca01 Mon Sep 17 00:00:00 2001
|
|
|
3e5111 |
Message-Id: <ea1a18cc0a5722b64c37c79bee7b9ed3c220ca01@dist-git>
|
|
|
3e5111 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
Date: Wed, 29 Mar 2017 15:31:17 +0200
|
|
|
3e5111 |
Subject: [PATCH] qemu: Pass migratable host CPU model to virCPUUpdate
|
|
|
3e5111 |
|
|
|
3e5111 |
We already know from QEMU which CPU features will block migration. Let's
|
|
|
3e5111 |
use this information to make a migratable copy of the host CPU model and
|
|
|
3e5111 |
use it for updating guest CPU specification. This will allow us to drop
|
|
|
3e5111 |
feature filtering from virCPUUpdate where it was just a hack.
|
|
|
3e5111 |
|
|
|
3e5111 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
(cherry picked from commit 56bd7edcb5dc878beffb80d4e6a9cfb812378ded)
|
|
|
3e5111 |
|
|
|
3e5111 |
https://bugzilla.redhat.com/show_bug.cgi?id=1444421
|
|
|
3e5111 |
|
|
|
3e5111 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
3e5111 |
---
|
|
|
3e5111 |
src/qemu/qemu_capabilities.c | 57 +++++++++++++++++++++++++++++++++++++-------
|
|
|
3e5111 |
src/qemu/qemu_capabilities.h | 2 ++
|
|
|
3e5111 |
src/qemu/qemu_process.c | 2 +-
|
|
|
3e5111 |
tests/cputest.c | 7 +++++-
|
|
|
3e5111 |
4 files changed, 57 insertions(+), 11 deletions(-)
|
|
|
3e5111 |
|
|
|
3e5111 |
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
|
|
3e5111 |
index e84de9f5b..ec773971e 100644
|
|
|
3e5111 |
--- a/src/qemu/qemu_capabilities.c
|
|
|
3e5111 |
+++ b/src/qemu/qemu_capabilities.c
|
|
|
3e5111 |
@@ -385,6 +385,8 @@ struct _virQEMUCapsHostCPUData {
|
|
|
3e5111 |
qemuMonitorCPUModelInfoPtr info;
|
|
|
3e5111 |
/* Host CPU definition reported in domain capabilities. */
|
|
|
3e5111 |
virCPUDefPtr reported;
|
|
|
3e5111 |
+ /* Migratable host CPU definition used for updating guest CPU. */
|
|
|
3e5111 |
+ virCPUDefPtr migratable;
|
|
|
3e5111 |
};
|
|
|
3e5111 |
|
|
|
3e5111 |
/*
|
|
|
3e5111 |
@@ -2106,6 +2108,10 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
|
|
|
3e5111 |
!(dst->reported = virCPUDefCopy(src->reported)))
|
|
|
3e5111 |
return -1;
|
|
|
3e5111 |
|
|
|
3e5111 |
+ if (src->migratable &&
|
|
|
3e5111 |
+ !(dst->migratable = virCPUDefCopy(src->migratable)))
|
|
|
3e5111 |
+ return -1;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
return 0;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -2115,6 +2121,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
qemuMonitorCPUModelInfoFree(cpuData->info);
|
|
|
3e5111 |
virCPUDefFree(cpuData->reported);
|
|
|
3e5111 |
+ virCPUDefFree(cpuData->migratable);
|
|
|
3e5111 |
|
|
|
3e5111 |
memset(cpuData, 0, sizeof(*cpuData));
|
|
|
3e5111 |
}
|
|
|
3e5111 |
@@ -2453,6 +2460,9 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
switch (cpuType) {
|
|
|
3e5111 |
case VIR_QEMU_CAPS_HOST_CPU_REPORTED:
|
|
|
3e5111 |
return cpuData->reported;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ case VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE:
|
|
|
3e5111 |
+ return cpuData->migratable;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
return NULL;
|
|
|
3e5111 |
@@ -2462,11 +2472,13 @@ virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
static void
|
|
|
3e5111 |
virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
virDomainVirtType type,
|
|
|
3e5111 |
- virCPUDefPtr cpu)
|
|
|
3e5111 |
+ virCPUDefPtr reported,
|
|
|
3e5111 |
+ virCPUDefPtr migratable)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
|
|
|
3e5111 |
|
|
|
3e5111 |
- cpuData->reported = cpu;
|
|
|
3e5111 |
+ cpuData->reported = reported;
|
|
|
3e5111 |
+ cpuData->migratable = migratable;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -3313,26 +3325,39 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
|
|
|
3e5111 |
+static virCPUDefPtr
|
|
|
3e5111 |
+virQEMUCapsNewHostCPUModel(void)
|
|
|
3e5111 |
+{
|
|
|
3e5111 |
+ virCPUDefPtr cpu;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if (VIR_ALLOC(cpu) < 0)
|
|
|
3e5111 |
+ return NULL;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ cpu->type = VIR_CPU_TYPE_GUEST;
|
|
|
3e5111 |
+ cpu->mode = VIR_CPU_MODE_CUSTOM;
|
|
|
3e5111 |
+ cpu->match = VIR_CPU_MATCH_EXACT;
|
|
|
3e5111 |
+ cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ return cpu;
|
|
|
3e5111 |
+}
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+
|
|
|
3e5111 |
void
|
|
|
3e5111 |
virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
virCapsPtr caps,
|
|
|
3e5111 |
virDomainVirtType type)
|
|
|
3e5111 |
{
|
|
|
3e5111 |
virCPUDefPtr cpu = NULL;
|
|
|
3e5111 |
+ virCPUDefPtr migCPU = NULL;
|
|
|
3e5111 |
virCPUDefPtr hostCPU = NULL;
|
|
|
3e5111 |
int rc;
|
|
|
3e5111 |
|
|
|
3e5111 |
if (!caps || !virQEMUCapsGuestIsNative(caps->host.arch, qemuCaps->arch))
|
|
|
3e5111 |
return;
|
|
|
3e5111 |
|
|
|
3e5111 |
- if (VIR_ALLOC(cpu) < 0)
|
|
|
3e5111 |
+ if (!(cpu = virQEMUCapsNewHostCPUModel()))
|
|
|
3e5111 |
goto error;
|
|
|
3e5111 |
|
|
|
3e5111 |
- cpu->type = VIR_CPU_TYPE_GUEST;
|
|
|
3e5111 |
- cpu->mode = VIR_CPU_MODE_CUSTOM;
|
|
|
3e5111 |
- cpu->match = VIR_CPU_MATCH_EXACT;
|
|
|
3e5111 |
- cpu->fallback = VIR_CPU_FALLBACK_ALLOW;
|
|
|
3e5111 |
-
|
|
|
3e5111 |
if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
|
|
|
3e5111 |
goto error;
|
|
|
3e5111 |
} else if (rc == 1) {
|
|
|
3e5111 |
@@ -3346,7 +3371,20 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
goto error;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
|
|
|
3e5111 |
- virQEMUCapsSetHostModel(qemuCaps, type, cpu);
|
|
|
3e5111 |
+ if (!(migCPU = virQEMUCapsNewHostCPUModel()))
|
|
|
3e5111 |
+ goto error;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
|
|
|
3e5111 |
+ goto error;
|
|
|
3e5111 |
+ } else if (rc == 1) {
|
|
|
3e5111 |
+ VIR_DEBUG("CPU migratability not provided by QEMU");
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ virCPUDefFree(migCPU);
|
|
|
3e5111 |
+ if (!(migCPU = virCPUCopyMigratable(qemuCaps->arch, cpu)))
|
|
|
3e5111 |
+ goto error;
|
|
|
3e5111 |
+ }
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ virQEMUCapsSetHostModel(qemuCaps, type, cpu, migCPU);
|
|
|
3e5111 |
|
|
|
3e5111 |
cleanup:
|
|
|
3e5111 |
virCPUDefFree(hostCPU);
|
|
|
3e5111 |
@@ -3354,6 +3392,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
|
|
|
3e5111 |
error:
|
|
|
3e5111 |
virCPUDefFree(cpu);
|
|
|
3e5111 |
+ virCPUDefFree(migCPU);
|
|
|
3e5111 |
virResetLastError();
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
|
|
3e5111 |
index 50333fc26..16fe044cc 100644
|
|
|
3e5111 |
--- a/src/qemu/qemu_capabilities.h
|
|
|
3e5111 |
+++ b/src/qemu/qemu_capabilities.h
|
|
|
3e5111 |
@@ -454,6 +454,8 @@ int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
typedef enum {
|
|
|
3e5111 |
/* Host CPU definition reported in domain capabilities. */
|
|
|
3e5111 |
VIR_QEMU_CAPS_HOST_CPU_REPORTED,
|
|
|
3e5111 |
+ /* Migratable host CPU definition used for updating guest CPU. */
|
|
|
3e5111 |
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE,
|
|
|
3e5111 |
} virQEMUCapsHostCPUType;
|
|
|
3e5111 |
|
|
|
3e5111 |
virCPUDefPtr virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
|
|
|
3e5111 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
3e5111 |
index dc073891a..c81389ef2 100644
|
|
|
3e5111 |
--- a/src/qemu/qemu_process.c
|
|
|
3e5111 |
+++ b/src/qemu/qemu_process.c
|
|
|
3e5111 |
@@ -5313,7 +5313,7 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
|
|
|
3e5111 |
|
|
|
3e5111 |
if (virCPUUpdate(def->os.arch, def->cpu,
|
|
|
3e5111 |
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
|
|
|
3e5111 |
- VIR_QEMU_CAPS_HOST_CPU_REPORTED)) < 0)
|
|
|
3e5111 |
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
if (virQEMUCapsGetCPUDefinitions(qemuCaps, def->virtType,
|
|
|
3e5111 |
diff --git a/tests/cputest.c b/tests/cputest.c
|
|
|
3e5111 |
index 8c07cf4f6..efa891dc1 100644
|
|
|
3e5111 |
--- a/tests/cputest.c
|
|
|
3e5111 |
+++ b/tests/cputest.c
|
|
|
3e5111 |
@@ -393,6 +393,7 @@ cpuTestUpdate(const void *arg)
|
|
|
3e5111 |
const struct data *data = arg;
|
|
|
3e5111 |
int ret = -1;
|
|
|
3e5111 |
virCPUDefPtr host = NULL;
|
|
|
3e5111 |
+ virCPUDefPtr migHost = NULL;
|
|
|
3e5111 |
virCPUDefPtr cpu = NULL;
|
|
|
3e5111 |
char *result = NULL;
|
|
|
3e5111 |
|
|
|
3e5111 |
@@ -400,7 +401,10 @@ cpuTestUpdate(const void *arg)
|
|
|
3e5111 |
!(cpu = cpuTestLoadXML(data->arch, data->name)))
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
- if (virCPUUpdate(host->arch, cpu, host) < 0)
|
|
|
3e5111 |
+ if (!(migHost = virCPUCopyMigratable(data->arch, host)))
|
|
|
3e5111 |
+ goto cleanup;
|
|
|
3e5111 |
+
|
|
|
3e5111 |
+ if (virCPUUpdate(host->arch, cpu, migHost) < 0)
|
|
|
3e5111 |
goto cleanup;
|
|
|
3e5111 |
|
|
|
3e5111 |
if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
|
|
|
3e5111 |
@@ -411,6 +415,7 @@ cpuTestUpdate(const void *arg)
|
|
|
3e5111 |
cleanup:
|
|
|
3e5111 |
virCPUDefFree(host);
|
|
|
3e5111 |
virCPUDefFree(cpu);
|
|
|
3e5111 |
+ virCPUDefFree(migHost);
|
|
|
3e5111 |
VIR_FREE(result);
|
|
|
3e5111 |
return ret;
|
|
|
3e5111 |
}
|
|
|
3e5111 |
--
|
|
|
3e5111 |
2.12.2
|
|
|
3e5111 |
|