[libvirt] [PATCH 03/41] cpu: Detect arch when parsing CPU data

Jiri Denemark jdenemar at redhat.com
Wed Jun 8 08:22:17 UTC 2016


A CPU data XML file already contains the architecture, let the parser
use it to detect which CPU driver should be used to parse the rest of
the file.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/cpu/cpu.c     | 54 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/cpu/cpu.h     |  7 +++----
 src/cpu/cpu_x86.c | 15 ++-------------
 3 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index dbd0987..8c3d39d 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -77,6 +77,21 @@ cpuGetSubDriver(virArch arch)
 }
 
 
+static struct cpuArchDriver *
+cpuGetSubDriverByName(const char *name)
+{
+    size_t i;
+
+    for (i = 0; i < NR_DRIVERS - 1; i++) {
+        if (STREQ_NULLABLE(name, drivers[i]->name))
+            return drivers[i];
+    }
+
+    /* use generic driver by default */
+    return drivers[NR_DRIVERS - 1];
+}
+
+
 /**
  * cpuCompareXML:
  *
@@ -667,7 +682,6 @@ cpuDataFormat(const virCPUData *data)
 /**
  * cpuDataParse:
  *
- * @arch: CPU architecture
  * @xmlStr: XML string produced by cpuDataFormat
  *
  * Parses XML representation of virCPUData structure for test purposes.
@@ -675,24 +689,44 @@ cpuDataFormat(const virCPUData *data)
  * Returns internal CPU data structure parsed from the XML or NULL on error.
  */
 virCPUDataPtr
-cpuDataParse(virArch arch,
-             const char *xmlStr)
+cpuDataParse(const char *xmlStr)
 {
     struct cpuArchDriver *driver;
+    xmlDocPtr xml = NULL;
+    xmlXPathContextPtr ctxt = NULL;
+    virCPUDataPtr data = NULL;
+    char *arch;
 
-    VIR_DEBUG("arch=%s, xmlStr=%s", virArchToString(arch), xmlStr);
+    VIR_DEBUG("xmlStr=%s", xmlStr);
 
-    if (!(driver = cpuGetSubDriver(arch)))
-        return NULL;
+    if (!(xml = virXMLParseStringCtxt(xmlStr, _("CPU data"), &ctxt))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("cannot parse CPU data"));
+        goto cleanup;
+    }
+
+    if (!(arch = virXPathString("string(/cpudata/@arch)", ctxt))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("missing CPU data architecture"));
+        goto cleanup;
+    }
+
+    if (!(driver = cpuGetSubDriverByName(arch)))
+        goto cleanup;
 
     if (!driver->dataParse) {
         virReportError(VIR_ERR_NO_SUPPORT,
-                       _("cannot parse %s CPU data"),
-                       virArchToString(arch));
-        return NULL;
+                       _("cannot parse %s CPU data"), arch);
+        goto cleanup;
     }
 
-    return driver->dataParse(xmlStr);
+    data = driver->dataParse(ctxt);
+
+ cleanup:
+    xmlXPathFreeContext(ctxt);
+    xmlFreeDoc(xml);
+    VIR_FREE(arch);
+    return data;
 }
 
 bool
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index f15dc16..7f66585 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -98,7 +98,7 @@ typedef char *
 (*cpuArchDataFormat)(const virCPUData *data);
 
 typedef virCPUDataPtr
-(*cpuArchDataParse) (const char *xmlStr);
+(*cpuArchDataParse) (xmlXPathContextPtr ctxt);
 
 typedef int
 (*cpuArchGetModels) (char ***models);
@@ -207,8 +207,7 @@ cpuGetModels(const char *arch, char ***models)
  */
 char *cpuDataFormat(const virCPUData *data)
     ATTRIBUTE_NONNULL(1);
-virCPUDataPtr cpuDataParse(virArch arch,
-                           const char *xmlStr)
-    ATTRIBUTE_NONNULL(2);
+virCPUDataPtr cpuDataParse(const char *xmlStr)
+    ATTRIBUTE_NONNULL(1);
 
 #endif /* __VIR_CPU_H__ */
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 65b7a56..f2492b5 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1288,10 +1288,8 @@ x86CPUDataFormat(const virCPUData *data)
 
 
 static virCPUDataPtr
-x86CPUDataParse(const char *xmlStr)
+x86CPUDataParse(xmlXPathContextPtr ctxt)
 {
-    xmlDocPtr xml = NULL;
-    xmlXPathContextPtr ctxt = NULL;
     xmlNodePtr *nodes = NULL;
     virCPUDataPtr cpuData = NULL;
     virCPUx86Data *data = NULL;
@@ -1302,14 +1300,7 @@ x86CPUDataParse(const char *xmlStr)
     if (VIR_ALLOC(data) < 0)
         goto cleanup;
 
-    if (!(xml = virXMLParseStringCtxt(xmlStr, _("CPU data"), &ctxt))) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("cannot parse CPU data"));
-        goto cleanup;
-    }
-    ctxt->node = xmlDocGetRootElement(xml);
-
-    n = virXPathNodeSet("/cpudata[@arch='x86']/cpuid", ctxt, &nodes);
+    n = virXPathNodeSet("/cpudata/cpuid", ctxt, &nodes);
     if (n <= 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("no x86 CPU data found"));
@@ -1331,8 +1322,6 @@ x86CPUDataParse(const char *xmlStr)
 
  cleanup:
     VIR_FREE(nodes);
-    xmlXPathFreeContext(ctxt);
-    xmlFreeDoc(xml);
     virCPUx86DataFree(data);
     return cpuData;
 }
-- 
2.8.3




More information about the libvir-list mailing list