[libvirt] [PATCH 4/5] Add virNodeDeviceDefParseString()

Daniel P. Berrange berrange at redhat.com
Mon Feb 23 20:19:00 UTC 2009


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 at 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 :|




More information about the libvir-list mailing list