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,