[libvirt] [PATCH RFC 6/8] qemu: hook up qemuCapsProbeCPUModels

Lee Schermerhorn lee.schermerhorn at hp.com
Sun Mar 11 18:52:51 UTC 2012


Hook up qemuCapsProbeCPUModels capabilities api to the emulator
cache framework:

  - qemuCapsProbeCPUModels() looks up emulator in cache and
    returns the version and flags.
  - wrap the part of the original qemuCapsProbeCPUModels() with
    qemuCapsCacheCPUModels() to run the specified binary and update
    the cached CPU models supported by this binary.
---
 src/qemu/qemu_capabilities.c |  123 ++++++++++++++++++++++++++++++-------------
 src/qemu/qemu_capabilities.h |    3 +
 2 files changed, 91 insertions(+), 35 deletions(-)

Index: libvirt-0.9.10/src/qemu/qemu_capabilities.c
===================================================================
--- libvirt-0.9.10.orig/src/qemu/qemu_capabilities.c
+++ libvirt-0.9.10/src/qemu/qemu_capabilities.c
@@ -194,7 +194,7 @@ struct _qemuEmulatorCache {
     virCapsGuestMachinePtr  *machines;
     int                     nmachines;
 
-    char                    **cpus;
+    const char              **cpus;
     unsigned int            ncpus;
 };
 
@@ -480,6 +480,21 @@ qemuCapsGetOldMachines(const char *ostyp
     return 0;
 }
 
+/*
+ * Free list of cpus returned by qemuCapsParseCPUModels()
+ */
+void
+qemuCapsFreeCPUModels(unsigned int *ncpus, const char ***cpus)
+{
+    int i;
+
+    if (*cpus)
+        return;
+    for (i = 0; i < *ncpus; i++)
+        VIR_FREE(*cpus[i]);
+    VIR_FREE(*cpus);
+    *ncpus = 0;
+}
 
 typedef int
 (*qemuCapsParseCPUModels)(const char *output,
@@ -500,7 +515,6 @@ qemuCapsParseX86Models(const char *outpu
     const char *next;
     unsigned int count = 0;
     const char **cpus = NULL;
-    int i;
 
     do {
         const char *t;
@@ -547,6 +561,11 @@ qemuCapsParseX86Models(const char *outpu
         count++;
     } while ((p = next));
 
+    /*
+     * Free any cached cpu models in case of possible cache refresh
+     */
+    qemuCapsFreeCPUModels(retcount, retcpus);
+
     if (retcount)
         *retcount = count;
     if (retcpus)
@@ -555,11 +574,7 @@ qemuCapsParseX86Models(const char *outpu
     return 0;
 
 error:
-    if (cpus) {
-        for (i = 0; i < count; i++)
-            VIR_FREE(cpus[i]);
-    }
-    VIR_FREE(cpus);
+    qemuCapsFreeCPUModels(&count, &cpus);
 
     return -1;
 }
@@ -576,7 +591,7 @@ qemuCapsParsePPCModels(const char *outpu
     const char *next;
     unsigned int count = 0;
     const char **cpus = NULL;
-    int i, ret = -1;
+    int ret = -1;
 
     do {
         const char *t;
@@ -618,6 +633,11 @@ qemuCapsParsePPCModels(const char *outpu
         count++;
     } while ((p = next));
 
+    /*
+     * Free any cached cpu models in case of possible cache refresh
+     */
+    qemuCapsFreeCPUModels(retcount, retcpus);
+
     if (retcount)
         *retcount = count;
     if (retcpus) {
@@ -627,42 +647,81 @@ qemuCapsParsePPCModels(const char *outpu
     ret = 0;
 
 cleanup:
-    if (cpus) {
-        for (i = 0; i < count; i++)
-            VIR_FREE(cpus[i]);
-        VIR_FREE(cpus);
-    }
+    qemuCapsFreeCPUModels(&count, &cpus);
     return ret;
 }
 
 int
 qemuCapsProbeCPUModels(const char *qemu,
-                       virBitmapPtr qemuCaps,
+                       virBitmapPtr qemuCaps ATTRIBUTE_UNUSED,
                        const char *arch,
                        unsigned int *count,
-                       const char ***cpus)
+                       const char ***retcpus)
 {
-    char *output = NULL;
-    int ret = -1;
-    qemuCapsParseCPUModels parse;
-    virCommandPtr cmd;
+    qemuEmulatorCachePtr emulator;
+    const char **cpus = NULL;
+    int i, ret = -1;
+    int ncpus = 0;
 
     if (count)
         *count = 0;
-    if (cpus)
-        *cpus = NULL;
+    if (retcpus)
+        *retcpus = NULL;
 
-    if (STREQ(arch, "i686") || STREQ(arch, "x86_64"))
-        parse = qemuCapsParseX86Models;
-    else if (STREQ(arch, "ppc64"))
-        parse = qemuCapsParsePPCModels;
-    else {
-        VIR_DEBUG("don't know how to parse %s CPU models", arch);
+    emulator = qemuEmulatorCachedInfoGet(QEMU_PROBE_CPU_MODELS, qemu, arch);
+    if (emulator) {
+        if (retcpus) {
+            ncpus = emulator->ncpus;
+            if (VIR_ALLOC_N(cpus, ncpus) < 0)
+                goto no_memory;
+            for (i = 0; i < ncpus; ++i) {
+                if (!(cpus[i] = strdup(emulator->cpus[i])))
+                    goto no_memory;
+            }
+            *retcpus = cpus;
+        }
+        if (count)
+            *count = emulator->ncpus;
+        ret = 0;
+    }
+    goto release;
+
+no_memory:
+    if (cpus) {
+        for (i = 0; i < ncpus; i++)
+            VIR_FREE(cpus[i]);
+        VIR_FREE(cpus);
+    }
+
+release:
+    qemuEmulatorCachedInfoRelease(emulator);
+    return ret;
+}
+
+static int
+qemuCapsCacheCPUModels(qemuEmulatorCachePtr emulator)
+{
+    char *output = NULL;
+    char *arch = emulator->arch, *qemu = emulator->path;
+    int ret = -1;
+    qemuCapsParseCPUModels parse = NULL;
+    virCommandPtr cmd;
+    VIR_DEBUG("Caching CPU Models for %s - %s", qemu, arch ?: "no-arch");
+
+    if (arch) {
+        if (STREQ(arch, "i686") || STREQ(arch, "x86_64"))
+            parse = qemuCapsParseX86Models;
+        else if (STREQ(arch, "ppc64"))
+            parse = qemuCapsParsePPCModels;
+    }
+    if (!parse) {
+        VIR_DEBUG("don't know how to parse %s CPU models",
+                   arch ?: "<nil>");
         return 0;
     }
 
     cmd = virCommandNewArgList(qemu, "-cpu", "?", NULL);
-    if (qemuCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG))
+    if (qemuCapsGet(emulator->caps, QEMU_CAPS_NODEFCONFIG))
         virCommandAddArg(cmd, "-nodefconfig");
     virCommandAddEnvPassCommon(cmd);
     virCommandSetOutputBuffer(cmd, &output);
@@ -671,7 +730,7 @@ qemuCapsProbeCPUModels(const char *qemu,
     if (virCommandRun(cmd, NULL) < 0)
         goto cleanup;
 
-    if (parse(output, count, cpus) < 0)
+    if (parse(output, &emulator->ncpus, &emulator->cpus) < 0)
         goto cleanup;
 
     ret = 0;
@@ -684,12 +743,6 @@ cleanup:
 }
 
 static int
-qemuCapsCacheCPUModels(qemuEmulatorCachePtr emulator)
-{
-	return emulator ? 0 : 1;
-}
-
-static int
 qemuCapsInitGuest(virCapsPtr caps,
                   virCapsPtr old_caps,
                   const char *hostmachine,
Index: libvirt-0.9.10/src/qemu/qemu_capabilities.h
===================================================================
--- libvirt-0.9.10.orig/src/qemu/qemu_capabilities.h
+++ libvirt-0.9.10/src/qemu/qemu_capabilities.h
@@ -151,6 +151,9 @@ int qemuCapsProbeCPUModels(const char *q
                            unsigned int *count,
                            const char ***cpus);
 
+void qemuCapsFreeCPUModels(unsigned int *count,
+                           const char ***cpus);
+
 int qemuCapsExtractVersion(virCapsPtr caps,
                            unsigned int *version);
 int qemuCapsExtractVersionInfo(const char *qemu, const char *arch,




More information about the libvir-list mailing list