
On Mon, Feb 23, 2009 at 11:28:39AM +0000, Mark McLoughlin wrote:
Add support for parsing node device XML descriptions.
This will be used by PCI passthrough related functions to obtain the PCI device address for a given node device.
Signed-off-by: Mark McLoughlin <markmc@redhat.com> --- src/libvirt_private.syms | 1 + src/node_device_conf.c | 687 ++++++++++++++++++++++++++++++++++++++++++++++ src/node_device_conf.h | 3 +- 3 files changed, 690 insertions(+), 1 deletions(-)
ACK, this would also be useful for the test.c driver, letting us include a pre-defined list of host devices in the XML for the driver setup.
+/* Called from SAX on parsing errors in the XML. */ +static void +catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + + if (ctxt) { + virConnectPtr conn = ctxt->_private; + + if (virGetLastError() == NULL && + ctxt->lastError.level == XML_ERR_FATAL && + ctxt->lastError.message != NULL) { + virNodeDeviceReportError(conn, VIR_ERR_XML_DETAIL, + _("at line %d: %s"), + ctxt->lastError.line, + ctxt->lastError.message); + } + } +} + +virNodeDeviceDefPtr +virNodeDeviceDefParseString(virConnectPtr conn, const char *str) +{ + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; + xmlNodePtr root; + virNodeDeviceDefPtr def = NULL; + + /* Set up a parser context so we can catch the details of XML errors. */ + pctxt = xmlNewParserCtxt (); + if (!pctxt || !pctxt->sax) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + if (conn) virResetError (&conn->err); + xml = xmlCtxtReadDoc(pctxt, BAD_CAST str, "device.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + if (conn && conn->err.code == VIR_ERR_NONE) + virNodeDeviceReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("failed to parse xml document")); + goto cleanup; + } + + if ((root = xmlDocGetRootElement(xml)) == NULL) { + virNodeDeviceReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("missing root element")); + goto cleanup; + } + + def = virNodeDeviceDefParseNode(conn, xml, root); + +cleanup: + xmlFreeParserCtxt(pctxt); + xmlFreeDoc(xml); + return def; +} +
If someone is feeling bored, I notice we've got quite alot of these top level methods for starting the XML parse across which duplicated code for setting up the XML context. We could usefully define a helper in xml.c to deal with this typedef void * (*virXMLParseHandler)(virConectPtr conn, xmlDocPtr doc, xmlNodePtr node); void * virXMLParseString(virConnectPtr conn, const char *xml, virXMLParseHandler); So this would simplify the top level string parse method to virNodeDevicePtr virNodeDeviceDefParseString(virConnectPtr conn, const char *xml) { return virXMLParseString(conn, xml, virNodeDeviceDefParseNode); } Likewise for the virXMLParseFile method Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|