It is a container for a CPU models list (qemuMonitorCPUDefInfo) and a
number of elements in this list.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
Reviewed-by: Ján Tomko <jtomko(a)redhat.com>
---
Notes:
Version 2:
- v1 reviewed by Ján Tomko, but the patch had to be changed because
of the previous patch
src/qemu/qemu_capabilities.c | 30 +++++++++----------
src/qemu/qemu_monitor.c | 39 +++++++++++++++++++------
src/qemu/qemu_monitor.h | 14 +++++++--
src/qemu/qemu_monitor_json.c | 56 ++++++++++++++----------------------
src/qemu/qemu_monitor_json.h | 2 +-
tests/qemumonitorjsontest.c | 38 +++++++++---------------
6 files changed, 93 insertions(+), 86 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6fa5e06edb..59af3ab6d3 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2457,18 +2457,17 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
virArch arch,
virDomainCapsCPUModelsPtr *cpuModels)
{
+ VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL;
virDomainCapsCPUModelsPtr models = NULL;
- qemuMonitorCPUDefInfoPtr *cpus = NULL;
- int ncpus = 0;
size_t i;
int ret = -1;
*cpuModels = NULL;
- if ((ncpus = qemuMonitorGetCPUDefinitions(mon, &cpus)) < 0)
+ if (qemuMonitorGetCPUDefinitions(mon, &defs) < 0)
return -1;
- if (ncpus == 0) {
+ if (!defs) {
ret = 0;
goto cleanup;
}
@@ -2483,30 +2482,30 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
goto cleanup;
for (name = libvirtModels; name && *name; name++) {
- for (i = 0; i < ncpus; i++) {
- if (STRCASENEQ(cpus[i]->name, *name))
+ for (i = 0; i < defs->ncpus; i++) {
+ if (STRCASENEQ(defs->cpus[i]->name, *name))
continue;
- VIR_FREE(cpus[i]->name);
- if (VIR_STRDUP(cpus[i]->name, *name) < 0)
+ VIR_FREE(defs->cpus[i]->name);
+ if (VIR_STRDUP(defs->cpus[i]->name, *name) < 0)
goto cleanup;
}
}
}
- if (!(models = virDomainCapsCPUModelsNew(ncpus)))
+ if (!(models = virDomainCapsCPUModelsNew(defs->ncpus)))
goto cleanup;
- for (i = 0; i < ncpus; i++) {
+ for (i = 0; i < defs->ncpus; i++) {
virDomainCapsCPUUsable usable = VIR_DOMCAPS_CPU_USABLE_UNKNOWN;
- if (cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
+ if (defs->cpus[i]->usable == VIR_TRISTATE_BOOL_YES)
usable = VIR_DOMCAPS_CPU_USABLE_YES;
- else if (cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
+ else if (defs->cpus[i]->usable == VIR_TRISTATE_BOOL_NO)
usable = VIR_DOMCAPS_CPU_USABLE_NO;
- if (virDomainCapsCPUModelsAddSteal(models, &cpus[i]->name, usable,
- &cpus[i]->blockers) < 0)
+ if (virDomainCapsCPUModelsAddSteal(models, &defs->cpus[i]->name,
usable,
+ &defs->cpus[i]->blockers) < 0)
goto cleanup;
}
@@ -2514,9 +2513,6 @@ virQEMUCapsFetchCPUDefinitions(qemuMonitorPtr mon,
ret = 0;
cleanup:
- for (i = 0; i < ncpus; i++)
- qemuMonitorCPUDefInfoFree(cpus[i]);
- VIR_FREE(cpus);
virObjectUnref(models);
return ret;
}
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 49f9159315..d17387d27f 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3538,25 +3538,48 @@ qemuMonitorMachineInfoFree(qemuMonitorMachineInfoPtr machine)
int
qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
- qemuMonitorCPUDefInfoPtr **cpus)
+ qemuMonitorCPUDefsPtr *cpuDefs)
{
- VIR_DEBUG("cpus=%p", cpus);
+ VIR_DEBUG("cpuDefs=%p", cpuDefs);
QEMU_CHECK_MONITOR(mon);
- return qemuMonitorJSONGetCPUDefinitions(mon, cpus);
+ return qemuMonitorJSONGetCPUDefinitions(mon, cpuDefs);
}
void
-qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu)
+qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs)
{
- if (!cpu)
+ size_t i;
+
+ if (!defs)
return;
- virStringListFree(cpu->blockers);
- VIR_FREE(cpu->name);
- VIR_FREE(cpu);
+ for (i = 0; i < defs->ncpus; i++) {
+ virStringListFree(defs->cpus[i]->blockers);
+ VIR_FREE(defs->cpus[i]->name);
+ VIR_FREE(defs->cpus[i]);
+ }
+
+ VIR_FREE(defs->cpus);
+ VIR_FREE(defs);
+}
+
+
+qemuMonitorCPUDefsPtr
+qemuMonitorCPUDefsNew(size_t count)
+{
+ VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL;
+
+ if (VIR_ALLOC(defs) < 0)
+ return NULL;
+
+ if (count > 0 && VIR_ALLOC_N(defs->cpus, count) < 0)
+ return NULL;
+
+ defs->ncpus = count;
+ VIR_RETURN_PTR(defs);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 536ba7893b..359bbfca7f 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1101,9 +1101,19 @@ struct _qemuMonitorCPUDefInfo {
char **blockers; /* NULL-terminated string list */
};
+typedef struct _qemuMonitorCPUDefs qemuMonitorCPUDefs;
+typedef qemuMonitorCPUDefs *qemuMonitorCPUDefsPtr;
+struct _qemuMonitorCPUDefs {
+ size_t ncpus;
+ qemuMonitorCPUDefInfoPtr *cpus;
+};
+
int qemuMonitorGetCPUDefinitions(qemuMonitorPtr mon,
- qemuMonitorCPUDefInfoPtr **cpus);
-void qemuMonitorCPUDefInfoFree(qemuMonitorCPUDefInfoPtr cpu);
+ qemuMonitorCPUDefsPtr *cpuDefs);
+qemuMonitorCPUDefsPtr qemuMonitorCPUDefsNew(size_t count);
+void qemuMonitorCPUDefsFree(qemuMonitorCPUDefsPtr defs);
+VIR_DEFINE_AUTOPTR_FUNC(qemuMonitorCPUDefs, qemuMonitorCPUDefsFree);
+
typedef enum {
QEMU_MONITOR_CPU_PROPERTY_BOOLEAN,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 418bdcec92..664f1b225e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -5524,60 +5524,57 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
int
qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
- qemuMonitorCPUDefInfoPtr **cpus)
+ qemuMonitorCPUDefsPtr *cpuDefs)
{
- int ret = -1;
+ VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL;
VIR_AUTOPTR(virJSONValue) cmd = NULL;
VIR_AUTOPTR(virJSONValue) reply = NULL;
virJSONValuePtr data;
- qemuMonitorCPUDefInfoPtr *cpulist = NULL;
- size_t n = 0;
+ size_t ncpus;
size_t i;
- *cpus = NULL;
+ *cpuDefs = NULL;
if (!(cmd = qemuMonitorJSONMakeCommand("query-cpu-definitions", NULL)))
return -1;
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
- goto cleanup;
+ return -1;
/* Urgh, some QEMU architectures have the query-cpu-definitions
* command, but return 'GenericError' with string "Not supported",
* instead of simply omitting the command entirely :-(
*/
- if (qemuMonitorJSONHasError(reply, "GenericError")) {
- ret = 0;
- goto cleanup;
- }
+ if (qemuMonitorJSONHasError(reply, "GenericError"))
+ return 0;
if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0)
- goto cleanup;
+ return -1;
data = virJSONValueObjectGetArray(reply, "return");
- n = virJSONValueArraySize(data);
+ ncpus = virJSONValueArraySize(data);
- if (VIR_ALLOC_N(cpulist, n) < 0)
- goto cleanup;
+ if (!(defs = qemuMonitorCPUDefsNew(ncpus)))
+ return -1;
- for (i = 0; i < n; i++) {
+ for (i = 0; i < defs->ncpus; i++) {
virJSONValuePtr child = virJSONValueArrayGet(data, i);
const char *tmp;
qemuMonitorCPUDefInfoPtr cpu;
if (VIR_ALLOC(cpu) < 0)
- goto cleanup;
+ return -1;
- cpulist[i] = cpu;
+ defs->cpus[i] = cpu;
if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("query-cpu-definitions reply data was missing
'name'"));
- goto cleanup;
+ return -1;
}
if (VIR_STRDUP(cpu->name, tmp) < 0)
- goto cleanup;
+ return -1;
if (virJSONValueObjectHasKey(child, "unavailable-features")) {
virJSONValuePtr blockers;
@@ -5590,7 +5587,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unavailable-features in query-cpu-definitions
"
"reply data was not an array"));
- goto cleanup;
+ return -1;
}
len = virJSONValueArraySize(blockers);
@@ -5602,7 +5599,7 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
cpu->usable = VIR_TRISTATE_BOOL_NO;
if (VIR_ALLOC_N(cpu->blockers, len + 1) < 0)
- goto cleanup;
+ return -1;
for (j = 0; j < len; j++) {
virJSONValuePtr blocker = virJSONValueArrayGet(blockers, j);
@@ -5611,26 +5608,17 @@ qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unexpected value in unavailable-features
"
"array"));
- goto cleanup;
+ return -1;
}
if (VIR_STRDUP(cpu->blockers[j], virJSONValueGetString(blocker)) <
0)
- goto cleanup;
+ return -1;
}
}
}
- ret = n;
- *cpus = cpulist;
- cpulist = NULL;
-
- cleanup:
- if (cpulist) {
- for (i = 0; i < n; i++)
- qemuMonitorCPUDefInfoFree(cpulist[i]);
- VIR_FREE(cpulist);
- }
- return ret;
+ VIR_STEAL_PTR(*cpuDefs, defs);
+ return 0;
}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 975de3759a..1b4b3abd72 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -376,7 +376,7 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
ATTRIBUTE_NONNULL(2);
int qemuMonitorJSONGetCPUDefinitions(qemuMonitorPtr mon,
- qemuMonitorCPUDefInfoPtr **cpus)
+ qemuMonitorCPUDefsPtr *cpuDefs)
ATTRIBUTE_NONNULL(2);
int qemuMonitorJSONGetCPUModelExpansion(qemuMonitorPtr mon,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 1248db59f2..7b8f63b11e 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -428,10 +428,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
{
const testGenericData *data = opaque;
virDomainXMLOptionPtr xmlopt = data->xmlopt;
- int ret = -1;
- qemuMonitorCPUDefInfoPtr *cpus = NULL;
- int ncpus = 0;
- size_t i;
+ VIR_AUTOPTR(qemuMonitorCPUDefs) defs = NULL;
VIR_AUTOPTR(qemuMonitorTest) test = NULL;
if (!(test = qemuMonitorTestNewSchema(xmlopt, data->schema)))
@@ -453,31 +450,30 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
" } "
" ]"
"}") < 0)
- goto cleanup;
+ return -1;
- if ((ncpus = qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test),
- &cpus)) < 0)
- goto cleanup;
+ if (qemuMonitorGetCPUDefinitions(qemuMonitorTestGetMonitor(test), &defs) < 0)
+ return -1;
- if (ncpus != 3) {
+ if (defs->ncpus != 3) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- "ncpus %d is not 3", ncpus);
- goto cleanup;
+ "ncpus %zu is not 3", defs->ncpus);
+ return -1;
}
#define CHECK_FULL(i, wantname, Usable) \
do { \
- if (STRNEQ(cpus[i]->name, (wantname))) { \
+ if (STRNEQ(defs->cpus[i]->name, (wantname))) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \
"name %s is not %s", \
- cpus[i]->name, (wantname)); \
- goto cleanup; \
+ defs->cpus[i]->name, (wantname)); \
+ return -1; \
} \
- if (cpus[i]->usable != (Usable)) { \
+ if (defs->cpus[i]->usable != (Usable)) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \
"%s: expecting usable flag %d, got %d", \
- cpus[i]->name, Usable, cpus[i]->usable); \
- goto cleanup; \
+ defs->cpus[i]->name, Usable,
defs->cpus[i]->usable); \
+ return -1; \
} \
} while (0)
@@ -496,13 +492,7 @@ testQemuMonitorJSONGetCPUDefinitions(const void *opaque)
#undef CHECK_USABLE
#undef CHECK_FULL
- ret = 0;
-
- cleanup:
- for (i = 0; i < ncpus; i++)
- qemuMonitorCPUDefInfoFree(cpus[i]);
- VIR_FREE(cpus);
- return ret;
+ return 0;
}
--
2.23.0