[PATCH 09/21] Refactoring virDomainDiskDefParseXML() to use XPath

Kristina Hanicova khanicov at redhat.com
Thu Apr 15 14:26:24 UTC 2021


Signed-off-by: Kristina Hanicova <khanicov at redhat.com>
---
 src/conf/domain_conf.c | 241 ++++++++++++++++++++---------------------
 1 file changed, 118 insertions(+), 123 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 808169883f..2af3ec6ec3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9259,7 +9259,12 @@ virDomainDiskDefParseXML(virDomainXMLOption *xmlopt,
                          unsigned int flags)
 {
     g_autoptr(virDomainDiskDef) def = NULL;
-    xmlNodePtr cur;
+    xmlNodePtr source_node = NULL;
+    xmlNodePtr geometry_node = NULL;
+    xmlNodePtr driver_node = NULL;
+    xmlNodePtr mirror_node = NULL;
+    xmlNodePtr auth_node = NULL;
+    xmlNodePtr encryption_node = NULL;
     VIR_XPATH_NODE_AUTORESTORE(ctxt)
     bool source = false;
     g_autoptr(virStorageEncryption) encryption = NULL;
@@ -9281,6 +9286,7 @@ virDomainDiskDefParseXML(virDomainXMLOption *xmlopt,
     g_autofree char *product = NULL;
     g_autofree char *domain_name = NULL;
     g_autofree char *rotation_rate = NULL;
+    g_autofree char *index = NULL;
 
     if (!(def = virDomainDiskDefNew(xmlopt)))
         return NULL;
@@ -9320,139 +9326,128 @@ virDomainDiskDefParseXML(virDomainXMLOption *xmlopt,
     rawio = virXMLPropString(node, "rawio");
     sgio = virXMLPropString(node, "sgio");
 
-    for (cur = node->children; cur != NULL; cur = cur->next) {
-        if (cur->type != XML_ELEMENT_NODE)
-            continue;
+    if ((source_node = virXPathNode("./source", ctxt))) {
+        if (virDomainStorageSourceParse(source_node, ctxt, def->src, flags, xmlopt) < 0)
+            return NULL;
+        source = true;
+        startupPolicy = virXPathString("string(./source/@startupPolicy)", ctxt);
 
-        if (!source && virXMLNodeNameEqual(cur, "source")) {
-            if (virDomainStorageSourceParse(cur, ctxt, def->src, flags, xmlopt) < 0)
-                return NULL;
+        if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
+            (index = virXPathString("string(./source/@index)", ctxt)) &&
+            virStrToLong_uip(index, NULL, 10, &def->src->id) < 0) {
+            virReportError(VIR_ERR_XML_ERROR, _("invalid disk index '%s'"), index);
+            return NULL;
+        }
+    }
 
-            source = true;
+    target = virXPathString("string(./target/@dev)", ctxt);
+    bus = virXPathString("string(./target/@bus)", ctxt);
+    tray = virXPathString("string(./target/@tray)", ctxt);
+    removable = virXPathString("string(./target/@removable)", ctxt);
+    rotation_rate = virXPathString("string(./target/@rotation_rate)", ctxt);
+    domain_name = virXPathString("string(./backenddomain/@name)", ctxt);
 
-            startupPolicy = virXMLPropString(cur, "startupPolicy");
+    /* HACK: Work around for compat with Xen
+     * driver in previous libvirt releases */
+    if (target &&
+        STRPREFIX(target, "ioemu:"))
+        memmove(target, target+6, strlen(target)-5);
 
-            if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
-                (tmp = virXMLPropString(cur, "index")) &&
-                virStrToLong_uip(tmp, NULL, 10, &def->src->id) < 0) {
-                virReportError(VIR_ERR_XML_ERROR, _("invalid disk index '%s'"), tmp);
-                return NULL;
-            }
-            VIR_FREE(tmp);
-        } else if (!target &&
-                   virXMLNodeNameEqual(cur, "target")) {
-            target = virXMLPropString(cur, "dev");
-            bus = virXMLPropString(cur, "bus");
-            tray = virXMLPropString(cur, "tray");
-            removable = virXMLPropString(cur, "removable");
-            rotation_rate = virXMLPropString(cur, "rotation_rate");
-
-            /* HACK: Work around for compat with Xen
-             * driver in previous libvirt releases */
-            if (target &&
-                STRPREFIX(target, "ioemu:"))
-                memmove(target, target+6, strlen(target)-5);
-        } else if (!domain_name &&
-                   virXMLNodeNameEqual(cur, "backenddomain")) {
-            domain_name = virXMLPropString(cur, "name");
-        } else if (virXMLNodeNameEqual(cur, "geometry")) {
-            if (virDomainDiskDefGeometryParse(def, cur) < 0)
-                return NULL;
-        } else if (virXMLNodeNameEqual(cur, "blockio")) {
-            logical_block_size =
-                virXMLPropString(cur, "logical_block_size");
-            if (logical_block_size &&
-                virStrToLong_ui(logical_block_size, NULL, 0,
-                                &def->blockio.logical_block_size) < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("invalid logical block size '%s'"),
-                               logical_block_size);
-                return NULL;
-            }
-            physical_block_size =
-                virXMLPropString(cur, "physical_block_size");
-            if (physical_block_size &&
-                virStrToLong_ui(physical_block_size, NULL, 0,
-                                &def->blockio.physical_block_size) < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("invalid physical block size '%s'"),
-                               physical_block_size);
-                return NULL;
-            }
-        } else if (!virDomainDiskGetDriver(def) &&
-                   virXMLNodeNameEqual(cur, "driver")) {
-            if (virDomainVirtioOptionsParseXML(cur, &def->virtio) < 0)
-                return NULL;
+    if ((geometry_node = virXPathNode("./geometry", ctxt)) &&
+        (virDomainDiskDefGeometryParse(def, geometry_node) < 0))
+        return NULL;
 
-            if (virDomainDiskDefDriverParseXML(def, cur, ctxt) < 0)
-                return NULL;
-        } else if (!def->mirror &&
-                   virXMLNodeNameEqual(cur, "mirror") &&
-                   !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) {
-            if (virDomainDiskDefMirrorParse(def, cur, ctxt, flags, xmlopt) < 0)
-                return NULL;
-        } else if (!authdef &&
-                   virXMLNodeNameEqual(cur, "auth")) {
-            if (!(authdef = virStorageAuthDefParse(cur, ctxt)))
-                return NULL;
-            def->diskElementAuth = true;
-        } else if (virXMLNodeNameEqual(cur, "iotune")) {
-            if (virDomainDiskDefIotuneParse(def, ctxt) < 0)
-                return NULL;
-        } else if (virXMLNodeNameEqual(cur, "readonly")) {
-            def->src->readonly = true;
-        } else if (virXMLNodeNameEqual(cur, "shareable")) {
-            def->src->shared = true;
-        } else if (virXMLNodeNameEqual(cur, "transient")) {
-            def->transient = true;
-        } else if (!encryption &&
-                   virXMLNodeNameEqual(cur, "encryption")) {
-            if (!(encryption = virStorageEncryptionParseNode(cur, ctxt)))
-                return NULL;
+    if ((logical_block_size =
+         virXPathString("string(./blockio/@logical_block_size)", ctxt)) &&
+        (virStrToLong_ui(logical_block_size, NULL, 0,
+                         &def->blockio.logical_block_size) < 0)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid logical block size '%s'"),
+                       logical_block_size);
+        return NULL;
+    }
 
-            def->diskElementEnc = true;
+    if ((physical_block_size =
+         virXPathString("string(./blockio/@physical_block_size)", ctxt)) &&
+        (virStrToLong_ui(physical_block_size, NULL, 0,
+                         &def->blockio.physical_block_size) < 0)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid physical block size '%s'"),
+                       physical_block_size);
+        return NULL;
+    }
 
-        } else if (!serial &&
-                   virXMLNodeNameEqual(cur, "serial")) {
-            if (!(serial = virXMLNodeContentString(cur)))
-                return NULL;
-        } else if (!wwn &&
-                   virXMLNodeNameEqual(cur, "wwn")) {
-            if (!(wwn = virXMLNodeContentString(cur)))
-                return NULL;
+    if ((driver_node = virXPathNode("./driver", ctxt))) {
+        if (virDomainVirtioOptionsParseXML(driver_node, &def->virtio) < 0)
+            return NULL;
+        if (virDomainDiskDefDriverParseXML(def, driver_node, ctxt) < 0)
+            return NULL;
+    }
 
-            if (!virValidateWWN(wwn))
-                return NULL;
-        } else if (!vendor &&
-                   virXMLNodeNameEqual(cur, "vendor")) {
-            if (!(vendor = virXMLNodeContentString(cur)))
-                return NULL;
+    if ((mirror_node = virXPathNode("./mirror", ctxt)) &&
+        !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
+        (virDomainDiskDefMirrorParse(def, mirror_node, ctxt, flags, xmlopt) < 0))
+        return NULL;
 
-            if (!virStringIsPrintable(vendor)) {
-                virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("disk vendor is not printable string"));
-                return NULL;
-            }
-        } else if (!product &&
-                   virXMLNodeNameEqual(cur, "product")) {
-            if (!(product = virXMLNodeContentString(cur)))
-                return NULL;
+    if ((auth_node = virXPathNode("./auth", ctxt))) {
+        if (!(authdef = virStorageAuthDefParse(auth_node, ctxt)))
+            return NULL;
+        def->diskElementAuth = true;
+    }
 
-            if (!virStringIsPrintable(product)) {
-                virReportError(VIR_ERR_XML_ERROR, "%s",
-                               _("disk product is not printable string"));
-                return NULL;
-            }
-        } else if (virXMLNodeNameEqual(cur, "boot")) {
-            /* boot is parsed as part of virDomainDeviceInfoParseXML */
-        } else if ((flags & VIR_DOMAIN_DEF_PARSE_STATUS) &&
-                   virXMLNodeNameEqual(cur, "diskSecretsPlacement")) {
-            g_autofree char *secretAuth = virXMLPropString(cur, "auth");
-            g_autofree char *secretEnc = virXMLPropString(cur, "enc");
+    if (virXPathNode("./iotune", ctxt) &&
+        (virDomainDiskDefIotuneParse(def, ctxt) < 0))
+        return NULL;
 
-            def->diskElementAuth = !!secretAuth;
-            def->diskElementEnc = !!secretEnc;
-        }
+    if (virXPathNode("./readonly", ctxt))
+        def->src->readonly = true;
+
+    if (virXPathNode("./shareable", ctxt))
+        def->src->shared = true;
+
+    if (virXPathNode("./transient", ctxt))
+        def->transient = true;
+
+    if ((encryption_node = virXPathNode("./encryption", ctxt))) {
+        if (!(encryption = virStorageEncryptionParseNode(encryption_node, ctxt)))
+            return NULL;
+        def->diskElementEnc = true;
+    }
+
+    if (virXPathNode("./serial", ctxt) &&
+        !(serial = virXPathString("string(./serial)", ctxt)))
+        return NULL;
+
+    if (virXPathNode("./wwn", ctxt)) {
+        if (!(wwn = virXPathString("string(./wwn)", ctxt)))
+            return NULL;
+        if (!virValidateWWN(wwn))
+            return NULL;
+    }
+
+    if ((vendor = virXPathString("string(./vendor)", ctxt)) &&
+        !virStringIsPrintable(vendor)) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("disk vendor is not printable string"));
+        return NULL;
+    }
+
+    if ((product = virXPathString("string(./product)", ctxt)) &&
+        !virStringIsPrintable(product)) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("disk product is not printable string"));
+        return NULL;
+    }
+
+    if ((flags & VIR_DOMAIN_DEF_PARSE_STATUS) &&
+        virXPathNode("./diskSecretsPlacement", ctxt)) {
+        g_autofree char *secretAuth =
+            virXPathString("string(./diskSecretsPlacement/@auth)", ctxt);
+        g_autofree char *secretEnc =
+            virXPathString("string(./diskSecretsPlacement/@enc)", ctxt);
+
+        def->diskElementAuth = !!secretAuth;
+        def->diskElementEnc = !!secretEnc;
     }
 
     /* Reset def->src->type in case when 'source' was not present */
-- 
2.30.2




More information about the libvir-list mailing list