We will need to keep some QEMU-specific data for each CPU model supported by a QEMU binary. Instead of complicating the generic virDomainCapsCPUModelsPtr, we can just directly store qemuMonitorCPUDefsPtr returned by the capabilities probing code. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- src/qemu/qemu_capabilities.c | 110 +++++++++++++++++------------------ 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 56b0e31c68..94d9cc3e32 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -603,8 +603,8 @@ struct _virQEMUCaps { virArch arch; virHashTablePtr domCapsCache; - virDomainCapsCPUModelsPtr kvmCPUModels; - virDomainCapsCPUModelsPtr tcgCPUModels; + qemuMonitorCPUDefsPtr kvmCPUModels; + qemuMonitorCPUDefsPtr tcgCPUModels; size_t nmachineTypes; struct virQEMUCapsMachineType *machineTypes; @@ -1617,17 +1617,9 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps) ret->arch = qemuCaps->arch; - if (qemuCaps->kvmCPUModels) { - ret->kvmCPUModels = virDomainCapsCPUModelsCopy(qemuCaps->kvmCPUModels); - if (!ret->kvmCPUModels) - goto error; - } - - if (qemuCaps->tcgCPUModels) { - ret->tcgCPUModels = virDomainCapsCPUModelsCopy(qemuCaps->tcgCPUModels); - if (!ret->tcgCPUModels) - goto error; - } + if (qemuMonitorCPUDefsCopy(&ret->kvmCPUModels, qemuCaps->kvmCPUModels) < 0 || + qemuMonitorCPUDefsCopy(&ret->tcgCPUModels, qemuCaps->tcgCPUModels) < 0) + goto error; if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 || virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0) @@ -1853,25 +1845,36 @@ virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps, virDomainCapsCPUUsable usable) { size_t i; - virDomainCapsCPUModelsPtr cpus = NULL; + size_t start; + qemuMonitorCPUDefsPtr defs = NULL; if (type == VIR_DOMAIN_VIRT_KVM && qemuCaps->kvmCPUModels) - cpus = qemuCaps->kvmCPUModels; + defs = qemuCaps->kvmCPUModels; else if (type == VIR_DOMAIN_VIRT_QEMU && qemuCaps->tcgCPUModels) - cpus = qemuCaps->tcgCPUModels; + defs = qemuCaps->tcgCPUModels; - if (!cpus) { - if (!(cpus = virDomainCapsCPUModelsNew(count))) + if (defs) { + start = defs->ncpus; + + if (VIR_EXPAND_N(defs->cpus, defs->ncpus, count) < 0) + return -1; + } else { + start = 0; + + if (!(defs = qemuMonitorCPUDefsNew(count))) return -1; if (type == VIR_DOMAIN_VIRT_KVM) - qemuCaps->kvmCPUModels = cpus; + qemuCaps->kvmCPUModels = defs; else - qemuCaps->tcgCPUModels = cpus; + qemuCaps->tcgCPUModels = defs; } for (i = 0; i < count; i++) { - if (virDomainCapsCPUModelsAdd(cpus, name[i], usable, NULL) < 0) + qemuMonitorCPUDefInfoPtr cpu = defs->cpus + start + i; + + cpu->usable = usable; + if (VIR_STRDUP(cpu->name, name[i]) < 0) return -1; } @@ -1923,20 +1926,14 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps, const char **modelWhitelist, const char **modelBlacklist) { - virDomainCapsCPUModelsPtr cpuModels; + qemuMonitorCPUDefsPtr defs; if (type == VIR_DOMAIN_VIRT_KVM) - cpuModels = qemuCaps->kvmCPUModels; + defs = qemuCaps->kvmCPUModels; else - cpuModels = qemuCaps->tcgCPUModels; + defs = qemuCaps->tcgCPUModels; - if (!cpuModels) - return NULL; - - if (modelWhitelist || modelBlacklist) - return virDomainCapsCPUModelsFilter(cpuModels, modelWhitelist, modelBlacklist); - - return virDomainCapsCPUModelsCopy(cpuModels); + return virQEMUCapsCPUDefsToModels(defs, modelWhitelist, modelBlacklist); } @@ -1996,7 +1993,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps, virDomainVirtType type, virCPUMode mode) { - virDomainCapsCPUModelsPtr cpus; + qemuMonitorCPUDefsPtr cpus; switch (mode) { case VIR_CPU_MODE_HOST_PASSTHROUGH: @@ -2012,7 +2009,7 @@ virQEMUCapsIsCPUModeSupported(virQEMUCapsPtr qemuCaps, cpus = qemuCaps->kvmCPUModels; else cpus = qemuCaps->tcgCPUModels; - return cpus && cpus->nmodels > 0; + return cpus && cpus->ncpus > 0; case VIR_CPU_MODE_LAST: break; @@ -2499,18 +2496,18 @@ virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon, bool tcg) { - virDomainCapsCPUModelsPtr models = NULL; + VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL; if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_DEFINITIONS)) return 0; - if (!(models = virQEMUCapsFetchCPUDefinitions(mon))) + if (qemuMonitorGetCPUDefinitions(mon, &defs) < 0) return -1; if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) - qemuCaps->tcgCPUModels = models; + VIR_STEAL_PTR(qemuCaps->tcgCPUModels, defs); else - qemuCaps->kvmCPUModels = models; + VIR_STEAL_PTR(qemuCaps->kvmCPUModels, defs); return 0; } @@ -3438,7 +3435,7 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt, virDomainVirtType type) { - virDomainCapsCPUModelsPtr cpus = NULL; + VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL; VIR_AUTOFREE(xmlNodePtr *) nodes = NULL; size_t i; int n; @@ -3458,20 +3455,14 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps, if (n == 0) return 0; - if (!(cpus = virDomainCapsCPUModelsNew(n))) + if (!(defs = qemuMonitorCPUDefsNew(n))) return -1; - if (type == VIR_DOMAIN_VIRT_KVM) - qemuCaps->kvmCPUModels = cpus; - else - qemuCaps->tcgCPUModels = cpus; - for (i = 0; i < n; i++) { + qemuMonitorCPUDefInfoPtr cpu = defs->cpus + i; int usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN; VIR_AUTOFREE(char *) strUsable = NULL; - VIR_AUTOFREE(char *) name = NULL; VIR_AUTOFREE(xmlNodePtr *) blockerNodes = NULL; - VIR_AUTOSTRINGLIST blockers = NULL; int nblockers; if ((strUsable = virXMLPropString(nodes[i], "usable")) && @@ -3481,8 +3472,9 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps, strUsable); return -1; } + cpu->usable = usable; - if (!(name = virXMLPropString(nodes[i], "name"))) { + if (!(cpu->name = virXMLPropString(nodes[i], "name"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing cpu name in QEMU capabilities cache")); return -1; @@ -3502,11 +3494,11 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps, if (nblockers > 0) { size_t j; - if (VIR_ALLOC_N(blockers, nblockers + 1) < 0) + if (VIR_ALLOC_N(cpu->blockers, nblockers + 1) < 0) return -1; for (j = 0; j < nblockers; j++) { - if (!(blockers[j] = virXMLPropString(blockerNodes[j], "name"))) { + if (!(cpu->blockers[j] = virXMLPropString(blockerNodes[j], "name"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing blocker name in QEMU " "capabilities cache")); @@ -3514,11 +3506,13 @@ virQEMUCapsLoadCPUModels(virQEMUCapsPtr qemuCaps, } } } - - if (virDomainCapsCPUModelsAddSteal(cpus, &name, usable, &blockers) < 0) - return -1; } + if (type == VIR_DOMAIN_VIRT_KVM) + VIR_STEAL_PTR(qemuCaps->kvmCPUModels, defs); + else + VIR_STEAL_PTR(qemuCaps->tcgCPUModels, defs); + return 0; } @@ -3928,23 +3922,23 @@ virQEMUCapsFormatCPUModels(virQEMUCapsPtr qemuCaps, virBufferPtr buf, virDomainVirtType type) { - virDomainCapsCPUModelsPtr cpus; + qemuMonitorCPUDefsPtr defs; const char *typeStr; size_t i; if (type == VIR_DOMAIN_VIRT_KVM) { typeStr = "kvm"; - cpus = qemuCaps->kvmCPUModels; + defs = qemuCaps->kvmCPUModels; } else { typeStr = "tcg"; - cpus = qemuCaps->tcgCPUModels; + defs = qemuCaps->tcgCPUModels; } - if (!cpus) + if (!defs) return; - for (i = 0; i < cpus->nmodels; i++) { - virDomainCapsCPUModelPtr cpu = cpus->models + i; + for (i = 0; i < defs->ncpus; i++) { + qemuMonitorCPUDefInfoPtr cpu = defs->cpus + i; virBufferAsprintf(buf, "<cpu type='%s' ", typeStr); virBufferEscapeString(buf, "name='%s'", cpu->name); -- 2.23.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list