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

View File

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

View File

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

View File

@ -3587,7 +3587,7 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
int
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
char ***cpus)
qemuMonitorCPUDefInfoPtr **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
qemuMonitorGetCommands(qemuMonitorPtr mon,
char ***commands)

View File

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

View File

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

View File

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

View File

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

View File

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