[libvirt] Restart: [PATCH RFC 0/8] qemu: Cache results of parsing qemu help output

Send of series failed at patch 6. Attempting to restart here rather than resend entire series.

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,

Use qemuCapsFreeCPUModels() in qemuBuildCpuArgStr(). Because it's there. --- src/qemu/qemu_command.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) Index: libvirt-0.9.10/src/qemu/qemu_command.c =================================================================== --- libvirt-0.9.10.orig/src/qemu/qemu_command.c +++ libvirt-0.9.10/src/qemu/qemu_command.c @@ -3651,11 +3651,7 @@ cleanup: virCPUDefFree(guest); virCPUDefFree(cpu); - if (cpus) { - for (i = 0; i < ncpus; i++) - VIR_FREE(cpus[i]); - VIR_FREE(cpus); - } + qemuCapsFreeCPUModels(&ncpus, &cpus); return ret;
participants (1)
-
Lee Schermerhorn