This is valid for some network drives, for example: <source protocol='nbd'> <host name='foo' port='1234'/> </source> We pass an empty string as path to the guestfs_add_drive_opts API in this case. --- src/libvirt-domain.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index a041e8f..414e996 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -504,26 +504,29 @@ for_each_disk (guestfs_h *g, debug (g, _("disk[%zu]: network device"), i); xpathCtx->node = nodes->nodeTab[i]; - xpfilename = xmlXPathEvalExpression (BAD_CAST "./source/@name", - xpathCtx); - if (xpfilename == NULL || - xpfilename->nodesetval == NULL || - xpfilename->nodesetval->nodeNr == 0) - continue; + /* Get the protocol (e.g. "rbd"). Required. */ xpprotocol = xmlXPathEvalExpression (BAD_CAST "./source/@protocol", xpathCtx); - /* Get the protocol (e.g. "rbd"). */ if (xpprotocol == NULL || xpprotocol->nodesetval == NULL || xpprotocol->nodesetval->nodeNr == 0) continue; assert (xpprotocol->nodesetval->nodeTab[0]); - assert (xpprotocol->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE); + assert (xpprotocol->nodesetval->nodeTab[0]->type == + XML_ATTRIBUTE_NODE); attr = (xmlAttrPtr) xpprotocol->nodesetval->nodeTab[0]; protocol = (char *) xmlNodeListGetString (doc, attr->children, 1); debug (g, _("disk[%zu]: protocol: %s"), i, protocol); + /* <source name="..."> is the path/exportname. Optional. */ + xpfilename = xmlXPathEvalExpression (BAD_CAST "./source/@name", + xpathCtx); + if (xpfilename == NULL || + xpfilename->nodesetval == NULL) + continue; + + /* <auth username="...">. Optional. */ xpusername = xmlXPathEvalExpression (BAD_CAST "./auth/@username", xpathCtx); if (xpusername != NULL && @@ -571,15 +574,21 @@ for_each_disk (guestfs_h *g, * ./auth/secret/@usage || ./auth/secret/@uuid */ } else - continue; /* type <> "file", "block", or "network", skip it */ + continue; /* type <> "file", "block", or "network", skip it */ assert (xpfilename); assert (xpfilename->nodesetval); - assert (xpfilename->nodesetval->nodeTab[0]); - assert (xpfilename->nodesetval->nodeTab[0]->type == XML_ATTRIBUTE_NODE); - attr = (xmlAttrPtr) xpfilename->nodesetval->nodeTab[0]; - filename = (char *) xmlNodeListGetString (doc, attr->children, 1); - debug (g, _("disk[%zu]: filename: %s"), i, filename); + if (xpfilename->nodesetval->nodeNr > 0) { + assert (xpfilename->nodesetval->nodeTab[0]); + assert (xpfilename->nodesetval->nodeTab[0]->type == + XML_ATTRIBUTE_NODE); + attr = (xmlAttrPtr) xpfilename->nodesetval->nodeTab[0]; + filename = (char *) xmlNodeListGetString (doc, attr->children, 1); + debug (g, _("disk[%zu]: filename: %s"), i, filename); + } + else + /* For network protocols (eg. nbd), name may be omitted. */ + filename = safe_strdup (g, ""); /* Get the disk format (may not be set). */ xpathCtx->node = nodes->nodeTab[i]; -- 1.8.4.2