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(a)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