virArch arch;
- size_t ncpuDefinitions;
- char **cpuDefinitions;
+ virDomainCapsCPUModelsPtr cpuDefinitions;
size_t nmachineTypes;
struct virQEMUCapsMachineType *machineTypes;
{
const char *p = output;
const char *next;
- int ret = -1;
+ virDomainCapsCPUModelsPtr cpus;
+
+ if (!(cpus = virDomainCapsCPUModelsNew(0)))
+ return -1;
do {
const char *t;
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
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.
{
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++;
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
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;
}
}
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);
}
-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 = 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 = qemuCaps->cpuDefinitions;
- return qemuCaps->ncpuDefinitions;
+ *names = models;
+ *count = qemuCaps->cpuDefinitions->nmodels;
+ return 0;
+
+ error:
+ virStringFreeListCount(models, i);
+ return -1;
}
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 {
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);
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++) {
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);
}
-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;
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",
goto cleanup;
}
- if (VIR_STRDUP(cpulist[i], tmp) < 0)
+ if (VIR_STRDUP(cpu->name, tmp) < 0)
goto cleanup;
}
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;