1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-10-11 03:33:52 +03:00

qemu: Use virDomainCapsCPUModels for cpuDefinitions

The list of supported CPU models in domain capabilities is stored in
virDomainCapsCPUModels. Let's use the same object for storing CPU models
in QEMU capabilities.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Jiri Denemark
2016-04-21 12:51:01 +02:00
parent 167280e7f6
commit d037d8006f
9 changed files with 164 additions and 90 deletions

View File

@@ -378,8 +378,7 @@ struct _virQEMUCaps {
virArch arch; virArch arch;
size_t ncpuDefinitions; virDomainCapsCPUModelsPtr cpuDefinitions;
char **cpuDefinitions;
size_t nmachineTypes; size_t nmachineTypes;
struct virQEMUCapsMachineType *machineTypes; struct virQEMUCapsMachineType *machineTypes;
@@ -618,7 +617,10 @@ virQEMUCapsParseX86Models(const char *output,
{ {
const char *p = output; const char *p = output;
const char *next; const char *next;
int ret = -1; virDomainCapsCPUModelsPtr cpus;
if (!(cpus = virDomainCapsCPUModelsNew(0)))
return -1;
do { do {
const char *t; const char *t;
@@ -640,9 +642,6 @@ virQEMUCapsParseX86Models(const char *output,
if (*p == '\0' || *p == '\n') if (*p == '\0' || *p == '\n')
continue; continue;
if (VIR_EXPAND_N(qemuCaps->cpuDefinitions, qemuCaps->ncpuDefinitions, 1) < 0)
goto cleanup;
if (next) if (next)
len = next - p - 1; len = next - p - 1;
else else
@@ -653,14 +652,16 @@ virQEMUCapsParseX86Models(const char *output,
len -= 2; len -= 2;
} }
if (VIR_STRNDUP(qemuCaps->cpuDefinitions[qemuCaps->ncpuDefinitions - 1], p, len) < 0) if (virDomainCapsCPUModelsAdd(cpus, p, len) < 0)
goto cleanup; goto error;
} while ((p = next)); } while ((p = next));
ret = 0; qemuCaps->cpuDefinitions = cpus;
return 0;
cleanup: error:
return ret; virObjectUnref(cpus);
return -1;
} }
/* ppc64 parser. /* ppc64 parser.
@@ -672,11 +673,13 @@ virQEMUCapsParsePPCModels(const char *output,
{ {
const char *p = output; const char *p = output;
const char *next; const char *next;
int ret = -1; virDomainCapsCPUModelsPtr cpus;
if (!(cpus = virDomainCapsCPUModelsNew(0)))
return -1;
do { do {
const char *t; const char *t;
size_t len;
if ((next = strchr(p, '\n'))) if ((next = strchr(p, '\n')))
next++; next++;
@@ -697,19 +700,16 @@ virQEMUCapsParsePPCModels(const char *output,
if (*p == '\n') if (*p == '\n')
continue; continue;
if (VIR_EXPAND_N(qemuCaps->cpuDefinitions, qemuCaps->ncpuDefinitions, 1) < 0) if (virDomainCapsCPUModelsAdd(cpus, p, t - p - 1) < 0)
goto cleanup; goto error;
len = t - p - 1;
if (VIR_STRNDUP(qemuCaps->cpuDefinitions[qemuCaps->ncpuDefinitions - 1], p, len) < 0)
goto cleanup;
} while ((p = next)); } while ((p = next));
ret = 0; qemuCaps->cpuDefinitions = cpus;
return 0;
cleanup: error:
return ret; virObjectUnref(cpus);
return -1;
} }
static int static int
@@ -2094,11 +2094,9 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
ret->arch = qemuCaps->arch; ret->arch = qemuCaps->arch;
if (VIR_ALLOC_N(ret->cpuDefinitions, qemuCaps->ncpuDefinitions) < 0) if (qemuCaps->cpuDefinitions) {
goto error; ret->cpuDefinitions = virDomainCapsCPUModelsCopy(qemuCaps->cpuDefinitions);
ret->ncpuDefinitions = qemuCaps->ncpuDefinitions; if (!ret->cpuDefinitions)
for (i = 0; i < qemuCaps->ncpuDefinitions; i++) {
if (VIR_STRDUP(ret->cpuDefinitions[i], qemuCaps->cpuDefinitions[i]) < 0)
goto error; goto error;
} }
@@ -2138,9 +2136,7 @@ void virQEMUCapsDispose(void *obj)
} }
VIR_FREE(qemuCaps->machineTypes); VIR_FREE(qemuCaps->machineTypes);
for (i = 0; i < qemuCaps->ncpuDefinitions; i++) virObjectUnref(qemuCaps->cpuDefinitions);
VIR_FREE(qemuCaps->cpuDefinitions[i]);
VIR_FREE(qemuCaps->cpuDefinitions);
virBitmapFree(qemuCaps->flags); virBitmapFree(qemuCaps->flags);
@@ -2278,28 +2274,58 @@ const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps)
} }
int virQEMUCapsAddCPUDefinition(virQEMUCapsPtr qemuCaps, int
const char *name) virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
const char **name,
size_t count)
{ {
char *tmp; size_t i;
if (VIR_STRDUP(tmp, name) < 0) if (!qemuCaps->cpuDefinitions &&
return -1; !(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(count)))
if (VIR_EXPAND_N(qemuCaps->cpuDefinitions, qemuCaps->ncpuDefinitions, 1) < 0) {
VIR_FREE(tmp);
return -1; return -1;
for (i = 0; i < count; i++) {
if (virDomainCapsCPUModelsAdd(qemuCaps->cpuDefinitions, name[i], -1) < 0)
return -1;
} }
qemuCaps->cpuDefinitions[qemuCaps->ncpuDefinitions-1] = tmp;
return 0; return 0;
} }
size_t virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps, int
char ***names) virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
char ***names,
size_t *count)
{ {
size_t i;
char **models = NULL;
*count = 0;
if (names) if (names)
*names = qemuCaps->cpuDefinitions; *names = NULL;
return qemuCaps->ncpuDefinitions;
if (!qemuCaps->cpuDefinitions)
return 0;
if (names && VIR_ALLOC_N(models, qemuCaps->cpuDefinitions->nmodels) < 0)
return -1;
for (i = 0; i < qemuCaps->cpuDefinitions->nmodels; i++) {
virDomainCapsCPUModelPtr cpu = qemuCaps->cpuDefinitions->models + i;
if (models && VIR_STRDUP(models[i], cpu->name) < 0)
goto error;
}
if (names)
*names = models;
*count = qemuCaps->cpuDefinitions->nmodels;
return 0;
error:
virStringFreeListCount(models, i);
return -1;
} }
@@ -2615,16 +2641,30 @@ static int
virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps, virQEMUCapsProbeQMPCPUDefinitions(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon) qemuMonitorPtr mon)
{ {
int ncpuDefinitions; qemuMonitorCPUDefInfoPtr *cpus;
char **cpuDefinitions; int ncpus;
int ret = -1;
size_t i;
if ((ncpuDefinitions = qemuMonitorGetCPUDefinitions(mon, &cpuDefinitions)) < 0) if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
return -1; return -1;
qemuCaps->ncpuDefinitions = ncpuDefinitions; if (!(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(ncpus)))
qemuCaps->cpuDefinitions = cpuDefinitions; goto cleanup;
return 0; for (i = 0; i < ncpus; i++) {
if (virDomainCapsCPUModelsAddSteal(qemuCaps->cpuDefinitions,
&cpus[i]->name) < 0)
goto cleanup;
}
ret = 0;
cleanup:
for (i = 0; i < ncpus; i++)
qemuMonitorCPUDefInfoFree(cpus[i]);
VIR_FREE(cpus);
return ret;
} }
struct tpmTypeToCaps { struct tpmTypeToCaps {
@@ -2970,17 +3010,19 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemuCaps, const char *filename,
goto cleanup; goto cleanup;
} }
if (n > 0) { if (n > 0) {
qemuCaps->ncpuDefinitions = n; if (!(qemuCaps->cpuDefinitions = virDomainCapsCPUModelsNew(n)))
if (VIR_ALLOC_N(qemuCaps->cpuDefinitions,
qemuCaps->ncpuDefinitions) < 0)
goto cleanup; goto cleanup;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (!(qemuCaps->cpuDefinitions[i] = virXMLPropString(nodes[i], "name"))) { if (!(str = virXMLPropString(nodes[i], "name"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("missing cpu name in QEMU capabilities cache")); _("missing cpu name in QEMU capabilities cache"));
goto cleanup; goto cleanup;
} }
if (virDomainCapsCPUModelsAddSteal(qemuCaps->cpuDefinitions,
&str) < 0)
goto cleanup;
} }
} }
VIR_FREE(nodes); VIR_FREE(nodes);
@@ -3139,9 +3181,11 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
virBufferAsprintf(&buf, "<arch>%s</arch>\n", virBufferAsprintf(&buf, "<arch>%s</arch>\n",
virArchToString(qemuCaps->arch)); virArchToString(qemuCaps->arch));
for (i = 0; i < qemuCaps->ncpuDefinitions; i++) { if (qemuCaps->cpuDefinitions) {
virBufferEscapeString(&buf, "<cpu name='%s'/>\n", for (i = 0; i < qemuCaps->cpuDefinitions->nmodels; i++) {
qemuCaps->cpuDefinitions[i]); virDomainCapsCPUModelPtr cpu = qemuCaps->cpuDefinitions->models + i;
virBufferEscapeString(&buf, "<cpu name='%s'/>\n", cpu->name);
}
} }
for (i = 0; i < qemuCaps->nmachineTypes; i++) { for (i = 0; i < qemuCaps->nmachineTypes; i++) {
@@ -3259,10 +3303,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
qemuCaps->arch = VIR_ARCH_NONE; qemuCaps->arch = VIR_ARCH_NONE;
qemuCaps->usedQMP = false; qemuCaps->usedQMP = false;
for (i = 0; i < qemuCaps->ncpuDefinitions; i++) virObjectUnref(qemuCaps->cpuDefinitions);
VIR_FREE(qemuCaps->cpuDefinitions[i]); qemuCaps->cpuDefinitions = NULL;
VIR_FREE(qemuCaps->cpuDefinitions);
qemuCaps->ncpuDefinitions = 0;
for (i = 0; i < qemuCaps->nmachineTypes; i++) { for (i = 0; i < qemuCaps->nmachineTypes; i++) {
VIR_FREE(qemuCaps->machineTypes[i].name); VIR_FREE(qemuCaps->machineTypes[i].name);

View File

@@ -423,10 +423,12 @@ virArch virQEMUCapsGetArch(virQEMUCapsPtr qemuCaps);
unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps); unsigned int virQEMUCapsGetVersion(virQEMUCapsPtr qemuCaps);
const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps); const char *virQEMUCapsGetPackage(virQEMUCapsPtr qemuCaps);
unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps); unsigned int virQEMUCapsGetKVMVersion(virQEMUCapsPtr qemuCaps);
int virQEMUCapsAddCPUDefinition(virQEMUCapsPtr qemuCaps, int virQEMUCapsAddCPUDefinitions(virQEMUCapsPtr qemuCaps,
const char *name); const char **name,
size_t virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps, size_t count);
char ***names); int virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
char ***names,
size_t *count);
const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps, const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
const char *name); const char *name);
int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps, int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,

View File

@@ -6566,9 +6566,10 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
host = caps->host.cpu; host = caps->host.cpu;
if (!host || if (virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus, &ncpus) < 0)
!host->model || goto cleanup;
(ncpus = virQEMUCapsGetCPUDefinitions(qemuCaps, &cpus)) == 0) {
if (!host || !host->model || ncpus == 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("CPU specification not supported by hypervisor")); _("CPU specification not supported by hypervisor"));
goto cleanup; goto cleanup;
@@ -6722,6 +6723,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver,
cpuDataFree(hostData); cpuDataFree(hostData);
virCPUDefFree(guest); virCPUDefFree(guest);
virCPUDefFree(cpu); virCPUDefFree(cpu);
virStringFreeListCount(cpus, ncpus);
return ret; return ret;
} }

View File

@@ -3587,7 +3587,7 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
int int
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon, qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
char ***cpus) qemuMonitorCPUDefInfoPtr **cpus)
{ {
VIR_DEBUG("cpus=%p", cpus); VIR_DEBUG("cpus=%p", cpus);
@@ -3597,6 +3597,16 @@ qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
} }
void
qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
{
if (!cpu)
return;
VIR_FREE(cpu->name);
VIR_FREE(cpu);
}
int int
qemuMonitorGetCommands(qemuMonitorPtr mon, qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands) char ***commands)

View File

@@ -905,8 +905,16 @@ int qemuMonitorGetMachines(qemuMonitorPtr mon,
void qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine); void qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine);
typedef struct _qemuMonitorCPUDefInfo qemuMonitorCPUDefInfo;
typedef qemuMonitorCPUDefInfo *qemuMonitorCPUDefInfoPtr;
struct _qemuMonitorCPUDefInfo {
char *name;
};
int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon, int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
char ***cpus); qemuMonitorCPUDefInfoPtr **cpus);
void qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu);
int qemuMonitorGetCommands(qemuMonitorPtr mon, int qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands); char ***commands);

View File

@@ -4873,14 +4873,15 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
} }
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, int
char ***cpus) qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
qemuMonitorCPUDefInfoPtr **cpus)
{ {
int ret = -1; int ret = -1;
virJSONValuePtr cmd; virJSONValuePtr cmd;
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
virJSONValuePtr data; virJSONValuePtr data;
char **cpulist = NULL; qemuMonitorCPUDefInfoPtr *cpulist = NULL;
int n = 0; int n = 0;
size_t i; size_t i;
@@ -4916,13 +4917,18 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
goto cleanup; goto cleanup;
} }
/* null-terminated list */ if (VIR_ALLOC_N(cpulist, n) < 0)
if (VIR_ALLOC_N(cpulist, n + 1) < 0)
goto cleanup; goto cleanup;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
virJSONValuePtr child = virJSONValueArrayGet(data, i); virJSONValuePtr child = virJSONValueArrayGet(data, i);
const char *tmp; const char *tmp;
qemuMonitorCPUDefInfoPtr cpu;
if (VIR_ALLOC(cpu) < 0)
goto cleanup;
cpulist[i] = cpu;
if (!(tmp = virJSONValueObjectGetString(child, "name"))) { if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -4930,7 +4936,7 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
goto cleanup; goto cleanup;
} }
if (VIR_STRDUP(cpulist[i], tmp) < 0) if (VIR_STRDUP(cpu->name, tmp) < 0)
goto cleanup; goto cleanup;
} }
@@ -4939,7 +4945,11 @@ int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
cpulist = NULL; cpulist = NULL;
cleanup: cleanup:
virStringFreeList(cpulist); if (cpulist) {
for (i = 0; i < n; i++)
qemuMonitorCPUDefInfoFree(cpulist[i]);
VIR_FREE(cpulist);
}
virJSONValueFree(cmd); virJSONValueFree(cmd);
virJSONValueFree(reply); virJSONValueFree(reply);
return ret; return ret;

View File

@@ -347,7 +347,7 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(2);
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon, int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
char ***cpus) qemuMonitorCPUDefInfoPtr **cpus)
ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(2);
int qemuMonitorJSONGetCommands(qemuMonitorPtr mon, int qemuMonitorJSONGetCommands(qemuMonitorPtr mon,

View File

@@ -412,7 +412,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt);
int ret = -1; int ret = -1;
char **cpus = NULL; qemuMonitorCPUDefInfoPtr *cpus = NULL;
int ncpus = 0; int ncpus = 0;
size_t i; size_t i;
@@ -447,10 +447,10 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
#define CHECK(i, wantname) \ #define CHECK(i, wantname) \
do { \ do { \
if (STRNEQ(cpus[i], (wantname))) { \ if (STRNEQ(cpus[i]->name, (wantname))) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \ virReportError(VIR_ERR_INTERNAL_ERROR, \
"name %s is not %s", \ "name %s is not %s", \
cpus[i], (wantname)); \ cpus[i]->name, (wantname)); \
goto cleanup; \ goto cleanup; \
} \ } \
} while (0) } while (0)
@@ -466,7 +466,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *data)
cleanup: cleanup:
qemuMonitorTestFree(test); qemuMonitorTestFree(test);
for (i = 0; i < ncpus; i++) for (i = 0; i < ncpus; i++)
VIR_FREE(cpus[i]); qemuMonitorCPUDefInfoFree(cpus[i]);
VIR_FREE(cpus); VIR_FREE(cpus);
return ret; return ret;
} }

View File

@@ -452,18 +452,18 @@ testAddCPUModels(virQEMUCapsPtr caps, bool skipLegacy)
"486", "coreduo", "kvm32", "qemu32", "kvm64", "486", "coreduo", "kvm32", "qemu32", "kvm64",
"core2duo", "phenom", "qemu64", "core2duo", "phenom", "qemu64",
}; };
size_t i;
for (i = 0; i < ARRAY_CARDINALITY(newModels); i++) { if (virQEMUCapsAddCPUDefinitions(caps, newModels,
if (virQEMUCapsAddCPUDefinition(caps, newModels[i]) < 0) ARRAY_CARDINALITY(newModels)) < 0)
return -1; return -1;
}
if (skipLegacy) if (skipLegacy)
return 0; return 0;
for (i = 0; i < ARRAY_CARDINALITY(legacyModels); i++) {
if (virQEMUCapsAddCPUDefinition(caps, legacyModels[i]) < 0) if (virQEMUCapsAddCPUDefinitions(caps, legacyModels,
return -1; ARRAY_CARDINALITY(legacyModels)) < 0)
} return -1;
return 0; return 0;
} }