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