virshDomainDetachInterface: Use virXPathNodeSet instead of xmlXpathEval

Refactor the XPath lookup to use the internal helper.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2022-10-18 15:00:59 +02:00
parent 601a127573
commit 4f7ecbd684
1 changed files with 23 additions and 29 deletions

View File

@ -12472,12 +12472,12 @@ virshDomainDetachInterface(char *doc,
bool printxml) bool printxml)
{ {
g_autoptr(xmlDoc) xml = NULL; g_autoptr(xmlDoc) xml = NULL;
g_autoptr(xmlXPathObject) obj = NULL;
g_autoptr(xmlXPathContext) ctxt = NULL; g_autoptr(xmlXPathContext) ctxt = NULL;
xmlNodePtr cur = NULL, matchNode = NULL;
g_autofree char *detach_xml = NULL; g_autofree char *detach_xml = NULL;
char buf[64]; g_autofree char *xpath = g_strdup_printf("/domain/devices/interface[@type='%s']", type);
int diff_mac = -1; g_autofree xmlNodePtr *nodes = NULL;
ssize_t nnodes;
xmlNodePtr matchNode = NULL;
size_t i; size_t i;
if (!(xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt))) { if (!(xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt))) {
@ -12485,34 +12485,20 @@ virshDomainDetachInterface(char *doc,
return false; return false;
} }
g_snprintf(buf, sizeof(buf), "/domain/devices/interface[@type='%s']", type); if ((nnodes = virXPathNodeSet(xpath, ctxt, &nodes)) <= 0) {
obj = xmlXPathEval(BAD_CAST buf, ctxt);
if (obj == NULL || obj->type != XPATH_NODESET ||
obj->nodesetval == NULL || obj->nodesetval->nodeNr == 0) {
vshError(ctl, _("No interface found whose type is %s"), type); vshError(ctl, _("No interface found whose type is %s"), type);
return false; return false;
} }
if (!mac && obj->nodesetval->nodeNr > 1) { if (mac) {
vshError(ctl, _("Domain has %d interfaces. Please specify which one " for (i = 0; i < nnodes; i++) {
"to detach using --mac"), obj->nodesetval->nodeNr); g_autofree char *tmp_mac = NULL;
return false;
}
if (!mac) { ctxt->node = nodes[i];
matchNode = obj->nodesetval->nodeTab[0];
goto hit;
}
/* multiple possibilities, so search for matching mac */ if ((tmp_mac = virXPathString("string(./mac/@address)", ctxt))) {
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
cur = obj->nodesetval->nodeTab[i]->children; if (virMacAddrCompare(tmp_mac, mac) == 0) {
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 (matchNode) { if (matchNode) {
/* this is the 2nd match, so it's ambiguous */ /* this is the 2nd match, so it's ambiguous */
vshError(ctl, _("Domain has multiple interfaces matching " vshError(ctl, _("Domain has multiple interfaces matching "
@ -12521,18 +12507,26 @@ virshDomainDetachInterface(char *doc,
mac); mac);
return false; 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) { if (!matchNode) {
vshError(ctl, _("No interface with MAC address %s was found"), mac); vshError(ctl, _("No interface with MAC address %s was found"), mac);
return false; return false;
} }
hit:
if (!(detach_xml = virXMLNodeToString(xml, matchNode))) { if (!(detach_xml = virXMLNodeToString(xml, matchNode))) {
vshSaveLibvirtError(); vshSaveLibvirtError();
return false; return false;