1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

cpu: Detect arch when parsing CPU data

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@redhat.com>
This commit is contained in:
Jiri Denemark 2015-06-29 11:08:30 +02:00
parent a68ab347d5
commit 7ab88767a7
3 changed files with 51 additions and 27 deletions

View File

@ -77,6 +77,23 @@ 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];
}
virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU driver '%s' does not exist"),
name);
return NULL;
}
/** /**
* cpuCompareXML: * cpuCompareXML:
* *
@ -667,7 +684,6 @@ cpuDataFormat(const virCPUData *data)
/** /**
* cpuDataParse: * cpuDataParse:
* *
* @arch: CPU architecture
* @xmlStr: XML string produced by cpuDataFormat * @xmlStr: XML string produced by cpuDataFormat
* *
* Parses XML representation of virCPUData structure for test purposes. * Parses XML representation of virCPUData structure for test purposes.
@ -675,24 +691,44 @@ cpuDataFormat(const virCPUData *data)
* Returns internal CPU data structure parsed from the XML or NULL on error. * Returns internal CPU data structure parsed from the XML or NULL on error.
*/ */
virCPUDataPtr virCPUDataPtr
cpuDataParse(virArch arch, cpuDataParse(const char *xmlStr)
const char *xmlStr)
{ {
struct cpuArchDriver *driver; struct cpuArchDriver *driver;
xmlDocPtr xml = NULL;
xmlXPathContextPtr ctxt = NULL;
virCPUDataPtr data = NULL;
char *arch = NULL;
VIR_DEBUG("arch=%s, xmlStr=%s", virArchToString(arch), xmlStr); VIR_DEBUG("xmlStr=%s", xmlStr);
if (!(driver = cpuGetSubDriver(arch))) if (!(xml = virXMLParseStringCtxt(xmlStr, _("CPU data"), &ctxt))) {
return NULL; 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) { if (!driver->dataParse) {
virReportError(VIR_ERR_NO_SUPPORT, virReportError(VIR_ERR_NO_SUPPORT,
_("cannot parse %s CPU data"), _("cannot parse %s CPU data"), arch);
virArchToString(arch)); goto cleanup;
return NULL;
} }
return driver->dataParse(xmlStr); data = driver->dataParse(ctxt);
cleanup:
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml);
VIR_FREE(arch);
return data;
} }
bool bool

View File

@ -98,7 +98,7 @@ typedef char *
(*cpuArchDataFormat)(const virCPUData *data); (*cpuArchDataFormat)(const virCPUData *data);
typedef virCPUDataPtr typedef virCPUDataPtr
(*cpuArchDataParse) (const char *xmlStr); (*cpuArchDataParse) (xmlXPathContextPtr ctxt);
typedef int typedef int
(*cpuArchGetModels) (char ***models); (*cpuArchGetModels) (char ***models);
@ -207,8 +207,7 @@ cpuGetModels(const char *arch, char ***models)
*/ */
char *cpuDataFormat(const virCPUData *data) char *cpuDataFormat(const virCPUData *data)
ATTRIBUTE_NONNULL(1); ATTRIBUTE_NONNULL(1);
virCPUDataPtr cpuDataParse(virArch arch, virCPUDataPtr cpuDataParse(const char *xmlStr)
const char *xmlStr) ATTRIBUTE_NONNULL(1);
ATTRIBUTE_NONNULL(2);
#endif /* __VIR_CPU_H__ */ #endif /* __VIR_CPU_H__ */

View File

@ -1288,10 +1288,8 @@ x86CPUDataFormat(const virCPUData *data)
static virCPUDataPtr static virCPUDataPtr
x86CPUDataParse(const char *xmlStr) x86CPUDataParse(xmlXPathContextPtr ctxt)
{ {
xmlDocPtr xml = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlNodePtr *nodes = NULL; xmlNodePtr *nodes = NULL;
virCPUDataPtr cpuData = NULL; virCPUDataPtr cpuData = NULL;
virCPUx86Data *data = NULL; virCPUx86Data *data = NULL;
@ -1302,14 +1300,7 @@ x86CPUDataParse(const char *xmlStr)
if (VIR_ALLOC(data) < 0) if (VIR_ALLOC(data) < 0)
goto cleanup; goto cleanup;
if (!(xml = virXMLParseStringCtxt(xmlStr, _("CPU data"), &ctxt))) { n = virXPathNodeSet("/cpudata/cpuid", ctxt, &nodes);
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot parse CPU data"));
goto cleanup;
}
ctxt->node = xmlDocGetRootElement(xml);
n = virXPathNodeSet("/cpudata[@arch='x86']/cpuid", ctxt, &nodes);
if (n <= 0) { if (n <= 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("no x86 CPU data found")); _("no x86 CPU data found"));
@ -1331,8 +1322,6 @@ x86CPUDataParse(const char *xmlStr)
cleanup: cleanup:
VIR_FREE(nodes); VIR_FREE(nodes);
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml);
virCPUx86DataFree(data); virCPUx86DataFree(data);
return cpuData; return cpuData;
} }