[libvirt] [PATCH v2 10/31] qemu: Introduce qemuMonitorCPUDefs struct

Jiri Denemark jdenemar at redhat.com
Tue Oct 15 15:34:46 UTC 2019


It is a container for a CPU models list (qemuMonitorCPUDefInfo) and a
number of elements in this list.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
Reviewed-by: Ján Tomko <jtomko at 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




More information about the libvir-list mailing list