render / rpms / libvirt

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