[libvirt] [PATCH 26/41] qemu: Store host-model CPU in qemu capabilities

Jiri Denemark jdenemar at redhat.com
Fri Aug 12 13:33:20 UTC 2016


Host capabilities provide libvirt's view of the host CPU, but for a
useful support for host-model CPUs we really need a hypervisor's view of
the CPU. And since the view can be differ with emulator, qemu
capabilities is the best place to store the host CPU model.

This patch just copies the CPU model from host capabilities, but this
will change in the future.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/qemu/qemu_capabilities.c | 63 +++++++++++++++++++++++++++++++++++++-------
 src/qemu/qemu_capspriv.h     |  7 ++++-
 tests/domaincapstest.c       | 10 +++----
 tests/qemucapabilitiestest.c |  2 +-
 tests/qemuxml2argvtest.c     |  7 +++--
 tests/testutilsqemu.c        |  5 ++--
 tests/testutilsqemu.h        |  3 ++-
 7 files changed, 76 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8f55fcc..97dc877 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -374,6 +374,7 @@ struct _virQEMUCaps {
     virArch arch;
 
     virDomainCapsCPUModelsPtr cpuDefinitions;
+    virCPUDefPtr cpuModel;
 
     size_t nmachineTypes;
     struct virQEMUCapsMachineType *machineTypes;
@@ -2052,6 +2053,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
             goto error;
     }
 
+    if (qemuCaps->cpuModel &&
+        !(ret->cpuModel = virCPUDefCopy(qemuCaps->cpuModel)))
+        goto error;
+
     if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
         goto error;
     ret->nmachineTypes = qemuCaps->nmachineTypes;
@@ -2821,6 +2826,37 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
 }
 
 
+void
+virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
+                            virCapsHostPtr host)
+{
+    virCPUDefPtr cpu = NULL;
+
+    if (!virQEMUCapsGuestIsNative(host->arch, qemuCaps->arch))
+        goto error;
+
+    if (host->cpu && host->cpu->model) {
+        if (VIR_ALLOC(cpu) < 0)
+            goto error;
+
+        cpu->sockets = cpu->cores = cpu->threads = 0;
+        cpu->type = VIR_CPU_TYPE_GUEST;
+        cpu->mode = VIR_CPU_MODE_CUSTOM;
+        cpu->match = VIR_CPU_MATCH_EXACT;
+
+        if (virCPUDefCopyModel(cpu, host->cpu, true) < 0)
+            goto error;
+    }
+
+    qemuCaps->cpuModel = cpu;
+    return;
+
+ error:
+    virCPUDefFree(cpu);
+    qemuCaps->cpuModel = NULL;
+}
+
+
 /*
  * Parsing a doc that looks like
  *
@@ -2839,8 +2875,11 @@ int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
  * </qemuCaps>
  */
 int
-virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
-                     time_t *qemuctime, time_t *selfctime,
+virQEMUCapsLoadCache(virCapsPtr caps,
+                     virQEMUCapsPtr qemuCaps,
+                     const char *filename,
+                     time_t *qemuctime,
+                     time_t *selfctime,
                      unsigned long *selfvers)
 {
     xmlDocPtr doc = NULL;
@@ -3068,6 +3107,8 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
     }
     VIR_FREE(nodes);
 
+    virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
+
     ret = 0;
  cleanup:
     VIR_FREE(str);
@@ -3256,7 +3297,9 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
 
 
 static int
-virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
+virQEMUCapsInitCached(virCapsPtr caps,
+                      virQEMUCapsPtr qemuCaps,
+                      const char *cacheDir)
 {
     char *capsdir = NULL;
     char *capsfile = NULL;
@@ -3298,8 +3341,8 @@ virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
         goto cleanup;
     }
 
-    if (virQEMUCapsLoadCache(qemuCaps, capsfile, &qemuctime, &selfctime,
-                             &selfvers) < 0) {
+    if (virQEMUCapsLoadCache(caps, qemuCaps, capsfile,
+                             &qemuctime, &selfctime, &selfvers) < 0) {
         VIR_WARN("Failed to load cached caps from '%s' for '%s': %s",
                  capsfile, qemuCaps->binary, virGetLastErrorMessage());
         virResetLastError();
@@ -3783,7 +3826,7 @@ virQEMUCapsLogProbeFailure(const char *binary)
 
 
 virQEMUCapsPtr
-virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
+virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
                                 const char *binary,
                                 const char *libDir,
                                 const char *cacheDir,
@@ -3823,7 +3866,7 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
 
     if (!cacheDir)
         rv = 0;
-    else if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir)) < 0)
+    else if ((rv = virQEMUCapsInitCached(caps, qemuCaps, cacheDir)) < 0)
         goto error;
 
     if (rv == 0) {
@@ -3849,16 +3892,18 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
         if (cacheDir &&
             virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0)
             goto error;
+
+        virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
     }
 
+ cleanup:
     VIR_FREE(qmperr);
     return qemuCaps;
 
  error:
-    VIR_FREE(qmperr);
     virObjectUnref(qemuCaps);
     qemuCaps = NULL;
-    return NULL;
+    goto cleanup;
 }
 
 static virQEMUCapsPtr
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index ac3693b..22c5a8a 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -48,7 +48,8 @@ virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
                                 gid_t runGid,
                                 bool qmpOnly);
 
-int virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps,
+int virQEMUCapsLoadCache(virCapsPtr caps,
+                         virQEMUCapsPtr qemuCaps,
                          const char *filename,
                          time_t *qemuctime,
                          time_t *selfctime,
@@ -60,4 +61,8 @@ char *virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
 void
 virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
                    virArch arch);
+
+void
+virQEMUCapsInitHostCPUModel(virQEMUCapsPtr qemuCaps,
+                            virCapsHostPtr host);
 #endif
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 511066d..99971c2 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -173,9 +173,13 @@ fillQemuCaps(virDomainCapsPtr domCaps,
     virQEMUCapsPtr qemuCaps = NULL;
     virDomainCapsLoaderPtr loader = &domCaps->os.loader;
 
+    if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
+        fakeHostCPU(caps, domCaps->arch) < 0)
+        goto cleanup;
+
     if (virAsprintf(&path, "%s/qemucapabilitiesdata/%s.%s.xml",
                     abs_srcdir, name, arch) < 0 ||
-        !(qemuCaps = qemuTestParseCapabilities(path)))
+        !(qemuCaps = qemuTestParseCapabilities(caps, path)))
         goto cleanup;
 
     if (machine &&
@@ -188,10 +192,6 @@ fillQemuCaps(virDomainCapsPtr domCaps,
                    virQEMUCapsGetDefaultMachine(qemuCaps)) < 0)
         goto cleanup;
 
-    if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
-        fakeHostCPU(caps, domCaps->arch) < 0)
-        goto cleanup;
-
     if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
                                   cfg->firmwares,
                                   cfg->nfirmwares) < 0)
diff --git a/tests/qemucapabilitiestest.c b/tests/qemucapabilitiestest.c
index 3924bce..10cfa43 100644
--- a/tests/qemucapabilitiestest.c
+++ b/tests/qemucapabilitiestest.c
@@ -97,7 +97,7 @@ testQemuCapsCopy(const void *opaque)
                                     false, false)))
         goto cleanup;
 
-    if (!(orig = qemuTestParseCapabilities(capsFile)))
+    if (!(orig = qemuTestParseCapabilities(caps, capsFile)))
         goto cleanup;
 
     if (!(copy = virQEMUCapsNewCopy(orig)))
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 59be0ea..e801424 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -347,7 +347,8 @@ testInitQEMUCaps(struct testInfo *info,
 
 static int
 testUpdateQEMUCaps(const struct testInfo *info,
-                   virDomainObjPtr vm)
+                   virDomainObjPtr vm,
+                   virCapsPtr caps)
 {
     int ret = -1;
 
@@ -356,6 +357,8 @@ testUpdateQEMUCaps(const struct testInfo *info,
     if (testAddCPUModels(info->qemuCaps, info->skipLegacyCPUs) < 0)
         goto cleanup;
 
+    virQEMUCapsInitHostCPUModel(info->qemuCaps, &caps->host);
+
     virQEMUCapsFilterByMachineType(info->qemuCaps, vm->def->os.machine);
 
     if (ARCH_IS_X86(vm->def->os.arch))
@@ -448,7 +451,7 @@ testCompareXMLToArgv(const void *data)
             goto cleanup;
     }
 
-    if (testUpdateQEMUCaps(info, vm) < 0)
+    if (testUpdateQEMUCaps(info, vm, driver.caps) < 0)
         goto cleanup;
 
     log = virTestLogContentAndReset();
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 1f0db16..e2b4db4 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -491,7 +491,8 @@ qemuTestSetHostCPU(virCapsPtr caps,
 
 
 virQEMUCapsPtr
-qemuTestParseCapabilities(const char *capsFile)
+qemuTestParseCapabilities(virCapsPtr caps,
+                          const char *capsFile)
 {
     virQEMUCapsPtr qemuCaps = NULL;
     time_t qemuctime;
@@ -499,7 +500,7 @@ qemuTestParseCapabilities(const char *capsFile)
     unsigned long version;
 
     if (!(qemuCaps = virQEMUCapsNew()) ||
-        virQEMUCapsLoadCache(qemuCaps, capsFile,
+        virQEMUCapsLoadCache(caps, qemuCaps, capsFile,
                              &qemuctime, &selfctime, &version) < 0)
         goto error;
 
diff --git a/tests/testutilsqemu.h b/tests/testutilsqemu.h
index 6d35116f..047a64d 100644
--- a/tests/testutilsqemu.h
+++ b/tests/testutilsqemu.h
@@ -15,7 +15,8 @@ enum {
 virCapsPtr testQemuCapsInit(void);
 virDomainXMLOptionPtr testQemuXMLConfInit(void);
 
-virQEMUCapsPtr qemuTestParseCapabilities(const char *capsFile);
+virQEMUCapsPtr qemuTestParseCapabilities(virCapsPtr caps,
+                                         const char *capsFile);
 
 extern virCPUDefPtr cpuDefault;
 extern virCPUDefPtr cpuHaswell;
-- 
2.9.2




More information about the libvir-list mailing list