[libvirt] [PATCH 12/14] cpu: Introduce virCPUConvertLegacy API

Jiri Denemark jdenemar at redhat.com
Thu Nov 10 22:39:37 UTC 2016


PPC driver needs to convert POWERx_v* legacy CPU model names into POWERx
to maintain backward compatibility with existing domains. This patch
adds a new step into the guest CPU configuration work flow which CPU
drivers can use to convert legacy CPU definitions.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/cpu/cpu.c            | 35 +++++++++++++++++++++++++++++++++++
 src/cpu/cpu.h            |  8 ++++++++
 src/cpu/cpu_ppc64.c      | 30 ++++++++++++------------------
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_process.c  |  3 +++
 tests/cputest.c          |  5 ++++-
 6 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 9d34206..4a5fbb1 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -934,3 +934,38 @@ virCPUTranslate(virArch arch,
     VIR_DEBUG("model=%s", NULLSTR(cpu->model));
     return 0;
 }
+
+
+/**
+ * virCPUConvertLegacy:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to be converted
+ *
+ * Convert legacy CPU definition into one that the corresponding cpu driver
+ * will be able to work with. Currently this is only implemented by the PPC
+ * driver, which needs to convert legacy POWERx_v* names into POWERx.
+ *
+ * Returns -1 on error, 0 on success.
+ */
+int
+virCPUConvertLegacy(virArch arch,
+                    virCPUDefPtr cpu)
+{
+    struct cpuArchDriver *driver;
+
+    VIR_DEBUG("arch=%s, cpu=%p, model=%s",
+              virArchToString(arch), cpu, NULLSTR(cpu->model));
+
+    if (!(driver = cpuGetSubDriver(arch)))
+        return -1;
+
+    if (!driver->convertLegacy)
+        return 0;
+
+    if (driver->convertLegacy(cpu) < 0)
+        return -1;
+
+    VIR_DEBUG("model=%s", NULLSTR(cpu->model));
+    return 0;
+}
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 5ad8112..ff48fb5 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -112,6 +112,9 @@ typedef int
                        const char **models,
                        unsigned int nmodels);
 
+typedef int
+(*virCPUArchConvertLegacy)(virCPUDefPtr cpu);
+
 struct cpuArchDriver {
     const char *name;
     const virArch *arch;
@@ -130,6 +133,7 @@ struct cpuArchDriver {
     virCPUArchDataParse dataParse;
     virCPUArchGetModels getModels;
     virCPUArchTranslate translate;
+    virCPUArchConvertLegacy convertLegacy;
 };
 
 
@@ -229,6 +233,10 @@ virCPUTranslate(virArch arch,
                 unsigned int nmodels)
     ATTRIBUTE_NONNULL(2);
 
+int
+virCPUConvertLegacy(virArch arch,
+                    virCPUDefPtr cpu)
+    ATTRIBUTE_NONNULL(2);
 
 /* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
  * have no real-life usage
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
index bdb026b..8b71ef5 100644
--- a/src/cpu/cpu_ppc64.c
+++ b/src/cpu/cpu_ppc64.c
@@ -63,26 +63,18 @@ struct ppc64_map {
  *   POWER7_v2.3  => POWER7
  *   POWER7+_v2.1 => POWER7
  *   POWER8_v1.0  => POWER8 */
-static virCPUDefPtr
-ppc64ConvertLegacyCPUDef(const virCPUDef *legacy)
+static int
+virCPUppc64ConvertLegacy(virCPUDefPtr cpu)
 {
-    virCPUDefPtr cpu;
-
-    if (!(cpu = virCPUDefCopy(legacy)))
-        goto out;
-
-    if (!cpu->model ||
-        !(STREQ(cpu->model, "POWER7_v2.1") ||
-          STREQ(cpu->model, "POWER7_v2.3") ||
-          STREQ(cpu->model, "POWER7+_v2.1") ||
-          STREQ(cpu->model, "POWER8_v1.0"))) {
-        goto out;
+    if (cpu->model &&
+        (STREQ(cpu->model, "POWER7_v2.1") ||
+         STREQ(cpu->model, "POWER7_v2.3") ||
+         STREQ(cpu->model, "POWER7+_v2.1") ||
+         STREQ(cpu->model, "POWER8_v1.0"))) {
+        cpu->model[strlen("POWERx")] = 0;
     }
 
-    cpu->model[strlen("POWERx")] = 0;
-
- out:
-    return cpu;
+    return 0;
 }
 
 /* Some hosts can run guests in compatibility mode, but not all
@@ -519,7 +511,8 @@ ppc64Compute(virCPUDefPtr host,
     size_t i;
 
     /* Ensure existing configurations are handled correctly */
-    if (!(cpu = ppc64ConvertLegacyCPUDef(other)))
+    if (!(cpu = virCPUDefCopy(other)) ||
+        virCPUppc64ConvertLegacy(cpu) < 0)
         goto cleanup;
 
     if (cpu->arch != VIR_ARCH_NONE) {
@@ -922,4 +915,5 @@ struct cpuArchDriver cpuDriverPPC64 = {
     .baseline   = ppc64DriverBaseline,
     .update     = virCPUppc64Update,
     .getModels  = virCPUppc64DriverGetModels,
+    .convertLegacy = virCPUppc64ConvertLegacy,
 };
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 41b674d..38f8ecb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -983,6 +983,7 @@ cpuNodeData;
 virCPUCheckFeature;
 virCPUCompare;
 virCPUCompareXML;
+virCPUConvertLegacy;
 virCPUDataCheckFeature;
 virCPUDataFormat;
 virCPUDataParse;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 14c799e..3552a31 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5066,6 +5066,9 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
         return -1;
     }
 
+    if (virCPUConvertLegacy(caps->host.arch, def->cpu) < 0)
+        return -1;
+
     /* nothing to update for host-passthrough */
     if (def->cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
         return 0;
diff --git a/tests/cputest.c b/tests/cputest.c
index 1d7f6bc..8612e92 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -251,6 +251,9 @@ cpuTestGuestCPU(const void *arg)
         !(cpu = cpuTestLoadXML(data->arch, data->name)))
         goto cleanup;
 
+    if (virCPUConvertLegacy(host->arch, cpu) < 0)
+        goto cleanup;
+
     cmpResult = virCPUCompare(host->arch, host, cpu, false);
     if (cmpResult == VIR_CPU_COMPARE_ERROR ||
         cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE) {
@@ -794,7 +797,7 @@ mymain(void)
 
     DO_TEST_GUESTCPU("ppc64", "host", "guest", ppc_models, 0);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-nofallback", ppc_models, -1);
-    DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, /*0*/ -1);
+    DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy", ppc_models, 0);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-incompatible", ppc_models, -1);
     DO_TEST_GUESTCPU("ppc64", "host", "guest-legacy-invalid", ppc_models, -1);
 
-- 
2.10.2




More information about the libvir-list mailing list