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, -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list