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(a)redhat.com>
---
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