]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virDomainHostdevSubsysSCSIHostDefParseXML: Switch to a more modern XML parsing approach
authorPeter Krempa <pkrempa@redhat.com>
Wed, 9 Sep 2020 14:17:05 +0000 (16:17 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 15 Sep 2020 13:20:23 +0000 (15:20 +0200)
Use XPath instead of iterating through the nodes.

Few error messages were modified so that the parser can be written in a
simpler way.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/conf/domain_conf.c

index 5c96843ed61b5da050f2f7ca29286a0869fba2f5..1c802e8fae02421c7e85fb7f865a18fcaa2f5ad5 100644 (file)
@@ -8262,89 +8262,61 @@ virDomainStorageNetworkParseHosts(xmlNodePtr node,
 
 static int
 virDomainHostdevSubsysSCSIHostDefParseXML(xmlNodePtr sourcenode,
+                                          xmlXPathContextPtr ctxt,
                                           virDomainHostdevSubsysSCSIPtr scsisrc)
 {
-    bool got_address = false, got_adapter = false;
-    xmlNodePtr cur;
     virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
     g_autofree char *bus = NULL;
     g_autofree char *target = NULL;
     g_autofree char *unit = NULL;
+    xmlNodePtr addressnode = NULL;
+    VIR_XPATH_NODE_AUTORESTORE(ctxt)
 
-    cur = sourcenode->children;
-    while (cur != NULL) {
-        if (cur->type == XML_ELEMENT_NODE) {
-            if (virXMLNodeNameEqual(cur, "address")) {
-                if (got_address) {
-                    virReportError(VIR_ERR_XML_ERROR, "%s",
-                                   _("more than one source addresses is "
-                                     "specified for scsi hostdev"));
-                    return -1;
-                }
-
-                if (!(bus = virXMLPropString(cur, "bus")) ||
-                    !(target = virXMLPropString(cur, "target")) ||
-                    !(unit = virXMLPropString(cur, "unit"))) {
-                    virReportError(VIR_ERR_XML_ERROR, "%s",
-                                   _("'bus', 'target', and 'unit' must be specified "
-                                     "for scsi hostdev source address"));
-                    return -1;
-                }
+    ctxt->node = sourcenode;
 
-                if (virStrToLong_uip(bus, NULL, 0, &scsihostsrc->bus) < 0) {
-                    virReportError(VIR_ERR_INTERNAL_ERROR,
-                                   _("cannot parse bus '%s'"), bus);
-                    return -1;
-                }
+    if (!(addressnode = virXPathNode("./address", ctxt))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("'address' must be specified for scsi hostdev source"));
+        return -1;
+    }
 
-                if (virStrToLong_uip(target, NULL, 0,
-                                    &scsihostsrc->target) < 0) {
-                    virReportError(VIR_ERR_INTERNAL_ERROR,
-                                   _("cannot parse target '%s'"), target);
-                    return -1;
-                }
+    if (!(bus = virXMLPropString(addressnode, "bus")) ||
+        !(target = virXMLPropString(addressnode, "target")) ||
+        !(unit = virXMLPropString(addressnode, "unit"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("'bus', 'target', and 'unit' must be specified "
+                         "for scsi hostdev source address"));
+        return -1;
+    }
 
-                if (virStrToLong_ullp(unit, NULL, 0, &scsihostsrc->unit) < 0) {
-                    virReportError(VIR_ERR_INTERNAL_ERROR,
-                                   _("cannot parse unit '%s'"), unit);
-                    return -1;
-                }
+    if (virStrToLong_uip(bus, NULL, 0, &scsihostsrc->bus) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot parse bus '%s'"), bus);
+        return -1;
+    }
 
-                got_address = true;
-            } else if (virXMLNodeNameEqual(cur, "adapter")) {
-                if (got_adapter) {
-                    virReportError(VIR_ERR_XML_ERROR, "%s",
-                                   _("more than one adapters is specified "
-                                     "for scsi hostdev source"));
-                    return -1;
-                }
-                if (!(scsihostsrc->adapter = virXMLPropString(cur, "name"))) {
-                    virReportError(VIR_ERR_XML_ERROR, "%s",
-                                   _("'adapter' must be specified for scsi hostdev source"));
-                    return -1;
-                }
+    if (virStrToLong_uip(target, NULL, 0, &scsihostsrc->target) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot parse target '%s'"), target);
+        return -1;
+    }
 
-                got_adapter = true;
-            } else {
-                virReportError(VIR_ERR_XML_ERROR,
-                               _("unsupported element '%s' of scsi hostdev source"),
-                               cur->name);
-                return -1;
-            }
-        }
-        cur = cur->next;
+    if (virStrToLong_ullp(unit, NULL, 0, &scsihostsrc->unit) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("cannot parse unit '%s'"), unit);
+        return -1;
     }
 
-    if (!got_address || !got_adapter) {
+    if (!(scsihostsrc->adapter = virXPathString("string(./adapter/@name)", ctxt))) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("'adapter' and 'address' must be specified for scsi "
-                         "hostdev source"));
+                       _("'adapter' name must be specified for scsi hostdev source"));
         return -1;
     }
 
     return 0;
 }
 
+
 static int
 virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode,
                                            virDomainHostdevSubsysSCSIPtr def,
@@ -8441,7 +8413,7 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
 
     switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
     case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE:
-        return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc);
+        return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, ctxt, scsisrc);
 
     case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
         return virDomainHostdevSubsysSCSIiSCSIDefParseXML(sourcenode, scsisrc, ctxt,