mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00: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:
parent
167280e7f6
commit
d037d8006f
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user