]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Store host-model CPU in qemu capabilities
authorJiri Denemark <jdenemar@redhat.com>
Wed, 15 Jun 2016 12:35:18 +0000 (14:35 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 22 Sep 2016 13:40:08 +0000 (15:40 +0200)
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@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capspriv.h
tests/domaincapstest.c
tests/qemucapabilitiestest.c
tests/qemuxml2argvtest.c
tests/testutilsqemu.c
tests/testutilsqemu.h

index 3aa348cf6f892a8d81b603393e425acea648dbe4..8fabe8deb50258d4d7873709b78a34ff82d3ee1d 100644 (file)
@@ -385,6 +385,12 @@ struct _virQEMUCaps {
 
     size_t ngicCapabilities;
     virGICCapability *gicCapabilities;
+
+    /* Anything below is not stored in the cache since the values are
+     * re-computed from the other fields or external data sources every
+     * time we probe QEMU or load the results from the cache.
+     */
+    virCPUDefPtr hostCPUModel;
 };
 
 struct virQEMUCapsSearchData {
@@ -2113,6 +2119,10 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
             goto error;
     }
 
+    if (qemuCaps->hostCPUModel &&
+        !(ret->hostCPUModel = virCPUDefCopy(qemuCaps->hostCPUModel)))
+        goto error;
+
     if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
         goto error;
     ret->nmachineTypes = qemuCaps->nmachineTypes;
@@ -2157,6 +2167,8 @@ void virQEMUCapsDispose(void *obj)
     VIR_FREE(qemuCaps->binary);
 
     VIR_FREE(qemuCaps->gicCapabilities);
+
+    virCPUDefFree(qemuCaps->hostCPUModel);
 }
 
 void
@@ -2902,6 +2914,38 @@ 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->hostCPUModel = cpu;
+    return;
+
+ error:
+    virCPUDefFree(cpu);
+    qemuCaps->hostCPUModel = NULL;
+    virResetLastError();
+}
+
+
 /*
  * Parsing a doc that looks like
  *
@@ -2920,8 +2964,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;
@@ -3154,6 +3201,8 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
     }
     VIR_FREE(nodes);
 
+    virQEMUCapsInitHostCPUModel(qemuCaps, &caps->host);
+
     ret = 0;
  cleanup:
     VIR_FREE(str);
@@ -3344,7 +3393,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;
@@ -3386,8 +3437,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();
@@ -3871,7 +3922,7 @@ virQEMUCapsLogProbeFailure(const char *binary)
 
 
 virQEMUCapsPtr
-virQEMUCapsNewForBinaryInternal(virCapsPtr caps ATTRIBUTE_UNUSED,
+virQEMUCapsNewForBinaryInternal(virCapsPtr caps,
                                 const char *binary,
                                 const char *libDir,
                                 const char *cacheDir,
@@ -3911,7 +3962,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) {
@@ -3937,16 +3988,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
index ac3693b5caed02440943e21f629905983f993cc9..22c5a8ae5b75946b985c6bc646976d51a0377365 100644 (file)
@@ -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
index 511066d9ab1a2b3d89d9223f9c2da355c598e286..99971c27d19dade371e282dc309f3243e824c71f 100644 (file)
@@ -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)
index 3924bce811a324697a76acc56aa0bc09fe191ce2..10cfa437683d95ffd7ff66e53c554769c8d34117 100644 (file)
@@ -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)))
index 156a45a9d55952148f261e14c1eb4a783ce0109c..7080484a6e42644ea6e5b3f4819ebbb5bddcecbf 100644 (file)
@@ -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();
index 8c2c8b462482763bec3804fedafe46144a93e56c..e66903a3b02b30184c709667554cfa74cad8001f 100644 (file)
@@ -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;
 
index 6d35116f36fc851369fb446fcfb00e50235d8dd6..047a64d1acf99b96834674f1cbd0fdd71f650a3b 100644 (file)
@@ -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;