From 4f7ecbd6840e53daad2206cfbf4ef7dcd9733ac5 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 18 Oct 2022 15:00:59 +0200 Subject: [PATCH] virshDomainDetachInterface: Use virXPathNodeSet instead of xmlXpathEval MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the XPath lookup to use the internal helper. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- 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 5fc12a768c..f7bf2f96c4 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;