[PATCH 02/13] virshDomainDetachInterface: Use virXPathNodeSet instead of xmlXpathEval

Peter Krempa pkrempa at redhat.com
Fri Dec 2 14:16:46 UTC 2022


Refactor the XPath lookup to use the internal helper.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 tools/virsh-domain.c | 52 ++++++++++++++++++++------------------------
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 9574a6eab6..87de3a708a 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -12472,12 +12472,12 @@ virshDomainDetachInterface(char *doc,
                            bool printxml)
 {
     g_autoptr(xmlDoc) xml = NULL;
-    g_autoptr(xmlXPathObject) obj = NULL;
     g_autoptr(xmlXPathContext) ctxt = NULL;
-    xmlNodePtr cur = NULL, matchNode = NULL;
     g_autofree char *detach_xml = NULL;
-    char buf[64];
-    int diff_mac = -1;
+    g_autofree char *xpath = g_strdup_printf("/domain/devices/interface[@type='%s']", type);
+    g_autofree xmlNodePtr *nodes = NULL;
+    ssize_t nnodes;
+    xmlNodePtr matchNode = NULL;
     size_t i;

     if (!(xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt))) {
@@ -12485,34 +12485,20 @@ virshDomainDetachInterface(char *doc,
         return false;
     }

-    g_snprintf(buf, sizeof(buf), "/domain/devices/interface[@type='%s']", type);
-    obj = xmlXPathEval(BAD_CAST buf, ctxt);
-    if (obj == NULL || obj->type != XPATH_NODESET ||
-        obj->nodesetval == NULL || obj->nodesetval->nodeNr == 0) {
+    if ((nnodes = virXPathNodeSet(xpath, ctxt, &nodes)) <= 0) {
         vshError(ctl, _("No interface found whose type is %s"), type);
         return false;
     }

-    if (!mac && obj->nodesetval->nodeNr > 1) {
-        vshError(ctl, _("Domain has %d interfaces. Please specify which one "
-                        "to detach using --mac"), obj->nodesetval->nodeNr);
-        return false;
-    }
+    if (mac) {
+        for (i = 0; i < nnodes; i++) {
+            g_autofree char *tmp_mac = NULL;

-    if (!mac) {
-        matchNode = obj->nodesetval->nodeTab[0];
-        goto hit;
-    }
+            ctxt->node = nodes[i];

-    /* multiple possibilities, so search for matching mac */
-    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
-        cur = obj->nodesetval->nodeTab[i]->children;
-        while (cur != NULL) {
-            if (cur->type == XML_ELEMENT_NODE &&
-                virXMLNodeNameEqual(cur, "mac")) {
-                g_autofree char *tmp_mac = virXMLPropString(cur, "address");
-                diff_mac = virMacAddrCompare(tmp_mac, mac);
-                if (!diff_mac) {
+            if ((tmp_mac = virXPathString("string(./mac/@address)", ctxt))) {
+
+                if (virMacAddrCompare(tmp_mac, mac) == 0) {
                     if (matchNode) {
                         /* this is the 2nd match, so it's ambiguous */
                         vshError(ctl, _("Domain has multiple interfaces matching "
@@ -12521,18 +12507,26 @@ virshDomainDetachInterface(char *doc,
                                  mac);
                         return false;
                     }
-                    matchNode = obj->nodesetval->nodeTab[i];
+
+                    matchNode = nodes[i];
                 }
             }
-            cur = cur->next;
         }
+    } else {
+        if (nnodes > 1) {
+            vshError(ctl, _("Domain has %zd interfaces. Please specify which one to detach using --mac"),
+                     nnodes);
+            return false;
+        }
+
+        matchNode = nodes[0];
     }
+
     if (!matchNode) {
         vshError(ctl, _("No interface with MAC address %s was found"), mac);
         return false;
     }

- hit:
     if (!(detach_xml = virXMLNodeToString(xml, matchNode))) {
         vshSaveLibvirtError();
         return false;
-- 
2.38.1



More information about the libvir-list mailing list