render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
Pablo Greco 40546a
From 728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0 Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <728231dcbbf2a4ab8a4bfe03fdf43d78bdeccbb0@dist-git>
Pablo Greco 40546a
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Pablo Greco 40546a
Date: Fri, 21 Jun 2019 09:24:46 +0200
Pablo Greco 40546a
Subject: [PATCH] cpu: push more parsing logic into common code
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
The x86 and ppc impls both duplicate some logic when parsing CPU
Pablo Greco 40546a
features. Change the callback signature so that this duplication can be
Pablo Greco 40546a
pushed up a level to common code.
Pablo Greco 40546a
Pablo Greco 40546a
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 0815f519784a7c565c543498777dc25f129620f9)
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1686895
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Message-Id: <c770b678131dc5e207cbe84d276a2774e0c807c7.1561068591.git.jdenemar@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/cpu/cpu_map.c   |  98 +++++++++++++---------
Pablo Greco 40546a
 src/cpu/cpu_map.h   |  22 ++---
Pablo Greco 40546a
 src/cpu/cpu_ppc64.c | 112 ++++++-------------------
Pablo Greco 40546a
 src/cpu/cpu_x86.c   | 196 +++++++++++++-------------------------------
Pablo Greco 40546a
 4 files changed, 143 insertions(+), 285 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/cpu/cpu_map.c b/src/cpu/cpu_map.c
Pablo Greco 40546a
index 333c7ef24f..ac7e58037a 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_map.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_map.c
Pablo Greco 40546a
@@ -35,31 +35,47 @@
Pablo Greco 40546a
 
Pablo Greco 40546a
 VIR_LOG_INIT("cpu.cpu_map");
Pablo Greco 40546a
 
Pablo Greco 40546a
-VIR_ENUM_IMPL(cpuMapElement, CPU_MAP_ELEMENT_LAST,
Pablo Greco 40546a
-    "vendor",
Pablo Greco 40546a
-    "feature",
Pablo Greco 40546a
-    "model")
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
-static int load(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                cpuMapElement element,
Pablo Greco 40546a
-                cpuMapLoadCallback callback,
Pablo Greco 40546a
-                void *data)
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+loadData(const char *mapfile,
Pablo Greco 40546a
+         xmlXPathContextPtr ctxt,
Pablo Greco 40546a
+         const char *element,
Pablo Greco 40546a
+         cpuMapLoadCallback callback,
Pablo Greco 40546a
+         void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
     xmlNodePtr ctxt_node;
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+    int rv;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ctxt_node = ctxt->node;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    n = virXPathNodeSet(cpuMapElementTypeToString(element), ctxt, &nodes);
Pablo Greco 40546a
-    if (n < 0)
Pablo Greco 40546a
+    if ((n = virXPathNodeSet(element, ctxt, &nodes)) < 0)
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (n > 0 &&
Pablo Greco 40546a
-        callback(element, ctxt, nodes, n, data) < 0)
Pablo Greco 40546a
+    if (n > 0 && !callback) {
Pablo Greco 40546a
+        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
+                       _("Unexpected element '%s' in CPU map '%s'"), element, mapfile);
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < n; i++) {
Pablo Greco 40546a
+        xmlNodePtr old = ctxt->node;
Pablo Greco 40546a
+        char *name = virXMLPropString(nodes[i], "name");
Pablo Greco 40546a
+        if (!name) {
Pablo Greco 40546a
+            virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
+                           _("cannot find %s name in CPU map '%s'"), element, mapfile);
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+        VIR_DEBUG("Load %s name %s", element, name);
Pablo Greco 40546a
+        ctxt->node = nodes[i];
Pablo Greco 40546a
+        rv = callback(ctxt, name, data);
Pablo Greco 40546a
+        ctxt->node = old;
Pablo Greco 40546a
+        VIR_FREE(name);
Pablo Greco 40546a
+        if (rv < 0)
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -72,13 +88,14 @@ static int load(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 cpuMapLoadInclude(const char *filename,
Pablo Greco 40546a
-                  cpuMapLoadCallback cb,
Pablo Greco 40546a
+                  cpuMapLoadCallback vendorCB,
Pablo Greco 40546a
+                  cpuMapLoadCallback featureCB,
Pablo Greco 40546a
+                  cpuMapLoadCallback modelCB,
Pablo Greco 40546a
                   void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     xmlDocPtr xml = NULL;
Pablo Greco 40546a
     xmlXPathContextPtr ctxt = NULL;
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
-    int element;
Pablo Greco 40546a
     char *mapfile;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(mapfile = virFileFindResource(filename,
Pablo Greco 40546a
@@ -93,13 +110,14 @@ cpuMapLoadInclude(const char *filename,
Pablo Greco 40546a
 
Pablo Greco 40546a
     ctxt->node = xmlDocGetRootElement(xml);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) {
Pablo Greco 40546a
-        if (load(ctxt, element, cb, data) < 0) {
Pablo Greco 40546a
-            virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                           _("cannot parse CPU map '%s'"), mapfile);
Pablo Greco 40546a
-            goto cleanup;
Pablo Greco 40546a
-        }
Pablo Greco 40546a
-    }
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "model", modelCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -114,7 +132,9 @@ cpuMapLoadInclude(const char *filename,
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 loadIncludes(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-             cpuMapLoadCallback callback,
Pablo Greco 40546a
+             cpuMapLoadCallback vendorCB,
Pablo Greco 40546a
+             cpuMapLoadCallback featureCB,
Pablo Greco 40546a
+             cpuMapLoadCallback modelCB,
Pablo Greco 40546a
              void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
@@ -137,7 +157,7 @@ loadIncludes(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
         VIR_DEBUG("Finding CPU map include '%s'", filename);
Pablo Greco 40546a
-        if (cpuMapLoadInclude(filename, callback, data) < 0) {
Pablo Greco 40546a
+        if (cpuMapLoadInclude(filename, vendorCB, featureCB, modelCB, data) < 0) {
Pablo Greco 40546a
             VIR_FREE(filename);
Pablo Greco 40546a
             goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
@@ -155,7 +175,9 @@ loadIncludes(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 int cpuMapLoad(const char *arch,
Pablo Greco 40546a
-               cpuMapLoadCallback cb,
Pablo Greco 40546a
+               cpuMapLoadCallback vendorCB,
Pablo Greco 40546a
+               cpuMapLoadCallback featureCB,
Pablo Greco 40546a
+               cpuMapLoadCallback modelCB,
Pablo Greco 40546a
                void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     xmlDocPtr xml = NULL;
Pablo Greco 40546a
@@ -163,7 +185,6 @@ int cpuMapLoad(const char *arch,
Pablo Greco 40546a
     virBuffer buf = VIR_BUFFER_INITIALIZER;
Pablo Greco 40546a
     char *xpath = NULL;
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
-    int element;
Pablo Greco 40546a
     char *mapfile;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(mapfile = virFileFindResource("cpu_map.xml",
Pablo Greco 40546a
@@ -179,12 +200,6 @@ int cpuMapLoad(const char *arch,
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (cb == NULL) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                       "%s", _("no callback provided"));
Pablo Greco 40546a
-        goto cleanup;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
     if (!(xml = virXMLParseFileCtxt(mapfile, &ctxt)))
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -202,15 +217,16 @@ int cpuMapLoad(const char *arch,
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    for (element = 0; element < CPU_MAP_ELEMENT_LAST; element++) {
Pablo Greco 40546a
-        if (load(ctxt, element, cb, data) < 0) {
Pablo Greco 40546a
-            virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                           _("cannot parse CPU map '%s'"), mapfile);
Pablo Greco 40546a
-            goto cleanup;
Pablo Greco 40546a
-        }
Pablo Greco 40546a
-    }
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "vendor", vendorCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (loadIncludes(ctxt, cb, data) < 0)
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "feature", featureCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (loadData(mapfile, ctxt, "model", modelCB, data) < 0)
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (loadIncludes(ctxt, vendorCB, featureCB, modelCB, data) < 0)
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
diff --git a/src/cpu/cpu_map.h b/src/cpu/cpu_map.h
Pablo Greco 40546a
index 0c7507e98f..4596987150 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_map.h
Pablo Greco 40546a
+++ b/src/cpu/cpu_map.h
Pablo Greco 40546a
@@ -26,28 +26,16 @@
Pablo Greco 40546a
 
Pablo Greco 40546a
 # include "virxml.h"
Pablo Greco 40546a
 
Pablo Greco 40546a
-
Pablo Greco 40546a
-typedef enum {
Pablo Greco 40546a
-    CPU_MAP_ELEMENT_VENDOR,
Pablo Greco 40546a
-    CPU_MAP_ELEMENT_FEATURE,
Pablo Greco 40546a
-    CPU_MAP_ELEMENT_MODEL,
Pablo Greco 40546a
-
Pablo Greco 40546a
-    CPU_MAP_ELEMENT_LAST
Pablo Greco 40546a
-} cpuMapElement;
Pablo Greco 40546a
-
Pablo Greco 40546a
-VIR_ENUM_DECL(cpuMapElement)
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 typedef int
Pablo Greco 40546a
-(*cpuMapLoadCallback)  (cpuMapElement element,
Pablo Greco 40546a
-                        xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                        xmlNodePtr *nodes,
Pablo Greco 40546a
-                        int n,
Pablo Greco 40546a
+(*cpuMapLoadCallback)  (xmlXPathContextPtr ctxt,
Pablo Greco 40546a
+                        const char *name,
Pablo Greco 40546a
                         void *data);
Pablo Greco 40546a
 
Pablo Greco 40546a
 int
Pablo Greco 40546a
 cpuMapLoad(const char *arch,
Pablo Greco 40546a
-           cpuMapLoadCallback cb,
Pablo Greco 40546a
+           cpuMapLoadCallback vendorCB,
Pablo Greco 40546a
+           cpuMapLoadCallback featureCB,
Pablo Greco 40546a
+           cpuMapLoadCallback modelCB,
Pablo Greco 40546a
            void *data);
Pablo Greco 40546a
 
Pablo Greco 40546a
 #endif /* __VIR_CPU_MAP_H__ */
Pablo Greco 40546a
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
index d562677fa3..75da5b77d8 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
@@ -281,21 +281,19 @@ ppc64MapFree(struct ppc64_map *map)
Pablo Greco 40546a
     VIR_FREE(map);
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
-static struct ppc64_vendor *
Pablo Greco 40546a
-ppc64VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                 struct ppc64_map *map)
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+ppc64VendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
Pablo Greco 40546a
+                 const char *name,
Pablo Greco 40546a
+                 void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    struct ppc64_map *map = data;
Pablo Greco 40546a
     struct ppc64_vendor *vendor;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(vendor) < 0)
Pablo Greco 40546a
-        return NULL;
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    vendor->name = virXPathString("string(@name)", ctxt);
Pablo Greco 40546a
-    if (!vendor->name) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                       "%s", _("Missing CPU vendor name"));
Pablo Greco 40546a
+    if (VIR_STRDUP(vendor->name, name) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (ppc64VendorFind(map, vendor->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
@@ -303,57 +301,36 @@ ppc64VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
-    return vendor;
Pablo Greco 40546a
+    if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
  error:
Pablo Greco 40546a
     ppc64VendorFree(vendor);
Pablo Greco 40546a
-    return NULL;
Pablo Greco 40546a
+    return -1;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
 static int
Pablo Greco 40546a
-ppc64VendorsLoad(struct ppc64_map *map,
Pablo Greco 40546a
-                 xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                 xmlNodePtr *nodes,
Pablo Greco 40546a
-                 int n)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    struct ppc64_vendor *vendor;
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    if (VIR_ALLOC_N(map->vendors, n) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < n; i++) {
Pablo Greco 40546a
-        ctxt->node = nodes[i];
Pablo Greco 40546a
-        if (!(vendor = ppc64VendorParse(ctxt, map)))
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-        map->vendors[map->nvendors++] = vendor;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
-static struct ppc64_model *
Pablo Greco 40546a
 ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                struct ppc64_map *map)
Pablo Greco 40546a
+                const char *name,
Pablo Greco 40546a
+                void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    struct ppc64_map *map = data;
Pablo Greco 40546a
     struct ppc64_model *model;
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     char *vendor = NULL;
Pablo Greco 40546a
     unsigned long pvr;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
+    int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(model) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    model->name = virXPathString("string(@name)", ctxt);
Pablo Greco 40546a
-    if (!model->name) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                       "%s", _("Missing CPU model name"));
Pablo Greco 40546a
+    if (VIR_STRDUP(model->name, name) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (ppc64ModelFind(map, model->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
@@ -410,63 +387,22 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         model->data.pvr[i].mask = pvr;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
+    if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    ret = 0;
Pablo Greco 40546a
+
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
     VIR_FREE(vendor);
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
-    return model;
Pablo Greco 40546a
+    return ret;
Pablo Greco 40546a
 
Pablo Greco 40546a
  error:
Pablo Greco 40546a
     ppc64ModelFree(model);
Pablo Greco 40546a
-    model = NULL;
Pablo Greco 40546a
     goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-ppc64ModelsLoad(struct ppc64_map *map,
Pablo Greco 40546a
-                xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                xmlNodePtr *nodes,
Pablo Greco 40546a
-                int n)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    struct ppc64_model *model;
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    if (VIR_ALLOC_N(map->models, n) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < n; i++) {
Pablo Greco 40546a
-        ctxt->node = nodes[i];
Pablo Greco 40546a
-        if (!(model = ppc64ModelParse(ctxt, map)))
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-        map->models[map->nmodels++] = model;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-ppc64MapLoadCallback(cpuMapElement element,
Pablo Greco 40546a
-                     xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                     xmlNodePtr *nodes,
Pablo Greco 40546a
-                     int n,
Pablo Greco 40546a
-                     void *data)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    struct ppc64_map *map = data;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    switch (element) {
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_VENDOR:
Pablo Greco 40546a
-        return ppc64VendorsLoad(map, ctxt, nodes, n);
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_MODEL:
Pablo Greco 40546a
-        return ppc64ModelsLoad(map, ctxt, nodes, n);
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_FEATURE:
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_LAST:
Pablo Greco 40546a
-        break;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
 static struct ppc64_map *
Pablo Greco 40546a
 ppc64LoadMap(void)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -475,7 +411,7 @@ ppc64LoadMap(void)
Pablo Greco 40546a
     if (VIR_ALLOC(map) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (cpuMapLoad("ppc64", ppc64MapLoadCallback, map) < 0)
Pablo Greco 40546a
+    if (cpuMapLoad("ppc64", ppc64VendorParse, NULL, ppc64ModelParse, map) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
     return map;
Pablo Greco 40546a
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
Pablo Greco 40546a
index 124aa5fd5e..11dbd1e757 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_x86.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_x86.c
Pablo Greco 40546a
@@ -720,22 +720,21 @@ x86VendorFind(virCPUx86MapPtr map,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static virCPUx86VendorPtr
Pablo Greco 40546a
+static int
Pablo Greco 40546a
 x86VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-               virCPUx86MapPtr map)
Pablo Greco 40546a
+               const char *name,
Pablo Greco 40546a
+               void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86MapPtr map = data;
Pablo Greco 40546a
     virCPUx86VendorPtr vendor = NULL;
Pablo Greco 40546a
     char *string = NULL;
Pablo Greco 40546a
+    int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(vendor) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    vendor->name = virXPathString("string(@name)", ctxt);
Pablo Greco 40546a
-    if (!vendor->name) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
Pablo Greco 40546a
-                       _("Missing CPU vendor name"));
Pablo Greco 40546a
+    if (VIR_STRDUP(vendor->name, name) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (x86VendorFind(map, vendor->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
@@ -754,40 +753,21 @@ x86VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
+    if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    ret = 0;
Pablo Greco 40546a
+
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
     VIR_FREE(string);
Pablo Greco 40546a
-    return vendor;
Pablo Greco 40546a
+    return ret;
Pablo Greco 40546a
 
Pablo Greco 40546a
  error:
Pablo Greco 40546a
     x86VendorFree(vendor);
Pablo Greco 40546a
-    vendor = NULL;
Pablo Greco 40546a
     goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-x86VendorsLoad(virCPUx86MapPtr map,
Pablo Greco 40546a
-               xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-               xmlNodePtr *nodes,
Pablo Greco 40546a
-               int n)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    virCPUx86VendorPtr vendor;
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    if (VIR_ALLOC_N(map->vendors, n) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < n; i++) {
Pablo Greco 40546a
-        ctxt->node = nodes[i];
Pablo Greco 40546a
-        if (!(vendor = x86VendorParse(ctxt, map)))
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-        map->vendors[map->nvendors++] = vendor;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 static virCPUx86FeaturePtr
Pablo Greco 40546a
 x86FeatureNew(void)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -909,27 +889,27 @@ x86ParseCPUID(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static virCPUx86FeaturePtr
Pablo Greco 40546a
+static int
Pablo Greco 40546a
 x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                virCPUx86MapPtr map)
Pablo Greco 40546a
+                const char *name,
Pablo Greco 40546a
+                void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86MapPtr map = data;
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     virCPUx86FeaturePtr feature;
Pablo Greco 40546a
     virCPUx86CPUID cpuid;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
     char *str = NULL;
Pablo Greco 40546a
+    int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(feature = x86FeatureNew()))
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
     feature->migratable = true;
Pablo Greco 40546a
-    feature->name = virXPathString("string(@name)", ctxt);
Pablo Greco 40546a
-    if (!feature->name) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                       "%s", _("Missing CPU feature name"));
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (VIR_STRDUP(feature->name, name) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (x86FeatureFind(map, feature->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
@@ -957,46 +937,28 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
+    if (!feature->migratable &&
Pablo Greco 40546a
+        VIR_APPEND_ELEMENT_COPY(map->migrate_blockers,
Pablo Greco 40546a
+                                map->nblockers,
Pablo Greco 40546a
+                                feature) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    ret = 0;
Pablo Greco 40546a
+
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
     VIR_FREE(str);
Pablo Greco 40546a
-    return feature;
Pablo Greco 40546a
+    return ret;
Pablo Greco 40546a
 
Pablo Greco 40546a
  error:
Pablo Greco 40546a
     x86FeatureFree(feature);
Pablo Greco 40546a
-    feature = NULL;
Pablo Greco 40546a
     goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-x86FeaturesLoad(virCPUx86MapPtr map,
Pablo Greco 40546a
-                xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                xmlNodePtr *nodes,
Pablo Greco 40546a
-                int n)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    virCPUx86FeaturePtr feature;
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    if (VIR_ALLOC_N(map->features, n) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < n; i++) {
Pablo Greco 40546a
-        ctxt->node = nodes[i];
Pablo Greco 40546a
-        if (!(feature = x86FeatureParse(ctxt, map)))
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-        map->features[map->nfeatures++] = feature;
Pablo Greco 40546a
-        if (!feature->migratable &&
Pablo Greco 40546a
-            VIR_APPEND_ELEMENT(map->migrate_blockers,
Pablo Greco 40546a
-                               map->nblockers,
Pablo Greco 40546a
-                               feature) < 0)
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 static virCPUx86ModelPtr
Pablo Greco 40546a
 x86ModelNew(void)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -1192,47 +1154,46 @@ x86ModelCompare(virCPUx86ModelPtr model1,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static virCPUx86ModelPtr
Pablo Greco 40546a
+static int
Pablo Greco 40546a
 x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-              virCPUx86MapPtr map)
Pablo Greco 40546a
+              const char *name,
Pablo Greco 40546a
+              void *data)
Pablo Greco 40546a
 {
Pablo Greco 40546a
+    virCPUx86MapPtr map = data;
Pablo Greco 40546a
     xmlNodePtr *nodes = NULL;
Pablo Greco 40546a
     virCPUx86ModelPtr model;
Pablo Greco 40546a
     char *vendor = NULL;
Pablo Greco 40546a
     size_t i;
Pablo Greco 40546a
     int n;
Pablo Greco 40546a
+    int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(model = x86ModelNew()))
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    model->name = virXPathString("string(@name)", ctxt);
Pablo Greco 40546a
-    if (!model->name) {
Pablo Greco 40546a
-        virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
-                       "%s", _("Missing CPU model name"));
Pablo Greco 40546a
+    if (VIR_STRDUP(model->name, name) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virXPathNode("./model", ctxt)) {
Pablo Greco 40546a
         virCPUx86ModelPtr ancestor;
Pablo Greco 40546a
-        char *name;
Pablo Greco 40546a
+        char *anname;
Pablo Greco 40546a
 
Pablo Greco 40546a
-        name = virXPathString("string(./model/@name)", ctxt);
Pablo Greco 40546a
-        if (!name) {
Pablo Greco 40546a
+        anname = virXPathString("string(./model/@name)", ctxt);
Pablo Greco 40546a
+        if (!anname) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing ancestor's name in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
-        if (!(ancestor = x86ModelFind(map, name))) {
Pablo Greco 40546a
+        if (!(ancestor = x86ModelFind(map, anname))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Ancestor model %s not found for CPU model %s"),
Pablo Greco 40546a
-                           name, model->name);
Pablo Greco 40546a
-            VIR_FREE(name);
Pablo Greco 40546a
+                           anname, model->name);
Pablo Greco 40546a
+            VIR_FREE(anname);
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
-        VIR_FREE(name);
Pablo Greco 40546a
+        VIR_FREE(anname);
Pablo Greco 40546a
 
Pablo Greco 40546a
         model->vendor = ancestor->vendor;
Pablo Greco 40546a
         model->signature = ancestor->signature;
Pablo Greco 40546a
@@ -1287,62 +1248,43 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < n; i++) {
Pablo Greco 40546a
         virCPUx86FeaturePtr feature;
Pablo Greco 40546a
-        char *name;
Pablo Greco 40546a
+        char *ftname;
Pablo Greco 40546a
 
Pablo Greco 40546a
-        if (!(name = virXMLPropString(nodes[i], "name"))) {
Pablo Greco 40546a
+        if (!(ftname = virXMLPropString(nodes[i], "name"))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing feature name for CPU model %s"), model->name);
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
-        if (!(feature = x86FeatureFind(map, name))) {
Pablo Greco 40546a
+        if (!(feature = x86FeatureFind(map, ftname))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Feature %s required by CPU model %s not found"),
Pablo Greco 40546a
-                           name, model->name);
Pablo Greco 40546a
-            VIR_FREE(name);
Pablo Greco 40546a
+                           ftname, model->name);
Pablo Greco 40546a
+            VIR_FREE(ftname);
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
         }
Pablo Greco 40546a
-        VIR_FREE(name);
Pablo Greco 40546a
+        VIR_FREE(ftname);
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (x86DataAdd(&model->data, &feature->data))
Pablo Greco 40546a
             goto error;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
+    if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
Pablo Greco 40546a
+        goto error;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    ret = 0;
Pablo Greco 40546a
+
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
     VIR_FREE(vendor);
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
-    return model;
Pablo Greco 40546a
+    return ret;
Pablo Greco 40546a
 
Pablo Greco 40546a
  error:
Pablo Greco 40546a
     x86ModelFree(model);
Pablo Greco 40546a
-    model = NULL;
Pablo Greco 40546a
     goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-x86ModelsLoad(virCPUx86MapPtr map,
Pablo Greco 40546a
-              xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-              xmlNodePtr *nodes,
Pablo Greco 40546a
-              int n)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    virCPUx86ModelPtr model;
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    if (VIR_ALLOC_N(map->models, n) < 0)
Pablo Greco 40546a
-        return -1;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < n; i++) {
Pablo Greco 40546a
-        ctxt->node = nodes[i];
Pablo Greco 40546a
-        if (!(model = x86ModelParse(ctxt, map)))
Pablo Greco 40546a
-            return -1;
Pablo Greco 40546a
-        map->models[map->nmodels++] = model;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 static void
Pablo Greco 40546a
 x86MapFree(virCPUx86MapPtr map)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -1372,30 +1314,6 @@ x86MapFree(virCPUx86MapPtr map)
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-x86MapLoadCallback(cpuMapElement element,
Pablo Greco 40546a
-                   xmlXPathContextPtr ctxt,
Pablo Greco 40546a
-                   xmlNodePtr *nodes,
Pablo Greco 40546a
-                   int n,
Pablo Greco 40546a
-                   void *data)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    virCPUx86MapPtr map = data;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    switch (element) {
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_VENDOR:
Pablo Greco 40546a
-        return x86VendorsLoad(map, ctxt, nodes, n);
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_FEATURE:
Pablo Greco 40546a
-        return x86FeaturesLoad(map, ctxt, nodes, n);
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_MODEL:
Pablo Greco 40546a
-        return x86ModelsLoad(map, ctxt, nodes, n);
Pablo Greco 40546a
-    case CPU_MAP_ELEMENT_LAST:
Pablo Greco 40546a
-        break;
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 static virCPUx86MapPtr
Pablo Greco 40546a
 virCPUx86LoadMap(void)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -1404,7 +1322,7 @@ virCPUx86LoadMap(void)
Pablo Greco 40546a
     if (VIR_ALLOC(map) < 0)
Pablo Greco 40546a
         return NULL;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0)
Pablo Greco 40546a
+    if (cpuMapLoad("x86", x86VendorParse, x86FeatureParse, x86ModelParse, map) < 0)
Pablo Greco 40546a
         goto error;
Pablo Greco 40546a
 
Pablo Greco 40546a
     return map;
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a