mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
virsh-domain-monitor: Refactor cmdDomIfGetLink
The domif-getlink command did not terminate successfully when the interface state was found. As the code used old and too complex approach to do the job, this patch refactors it and fixes the bug.
This commit is contained in:
parent
6bd94a1b59
commit
1f0cac3543
@ -663,26 +663,24 @@ cmdDomIfGetLink(vshControl *ctl, const vshCmd *cmd)
|
|||||||
{
|
{
|
||||||
virDomainPtr dom;
|
virDomainPtr dom;
|
||||||
const char *iface = NULL;
|
const char *iface = NULL;
|
||||||
int flags = 0;
|
|
||||||
char *state = NULL;
|
char *state = NULL;
|
||||||
char *value = NULL;
|
char *xpath = NULL;
|
||||||
virMacAddr macaddr;
|
virMacAddr macaddr;
|
||||||
const char *element;
|
char macstr[VIR_MAC_STRING_BUFLEN] = "";
|
||||||
const char *attr;
|
char *desc = NULL;
|
||||||
bool ret = false;
|
|
||||||
int i;
|
|
||||||
char *desc;
|
|
||||||
xmlDocPtr xml = NULL;
|
xmlDocPtr xml = NULL;
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
xmlNodePtr cur = NULL;
|
xmlNodePtr *interfaces = NULL;
|
||||||
xmlXPathObjectPtr obj = NULL;
|
int ninterfaces;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
if (vshCommandOptStringReq(ctl, cmd, "interface", &iface) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (vshCommandOptStringReq(ctl, cmd, "interface", &iface) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (vshCommandOptBool(cmd, "config"))
|
if (vshCommandOptBool(cmd, "config"))
|
||||||
flags = VIR_DOMAIN_XML_INACTIVE;
|
flags = VIR_DOMAIN_XML_INACTIVE;
|
||||||
|
|
||||||
@ -691,72 +689,50 @@ cmdDomIfGetLink(vshControl *ctl, const vshCmd *cmd)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
xml = virXMLParseStringCtxt(desc, _("(domain_definition)"), &ctxt);
|
if (!(xml = virXMLParseStringCtxt(desc, _("(domain_definition)"), &ctxt))) {
|
||||||
VIR_FREE(desc);
|
|
||||||
if (!xml) {
|
|
||||||
vshError(ctl, _("Failed to parse domain description xml"));
|
vshError(ctl, _("Failed to parse domain description xml"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt);
|
/* normalize the mac addr */
|
||||||
if (obj == NULL || obj->type != XPATH_NODESET ||
|
if (virMacAddrParse(iface, &macaddr) == 0)
|
||||||
obj->nodesetval == NULL || obj->nodesetval->nodeNr == 0) {
|
virMacAddrFormat(&macaddr, macstr);
|
||||||
vshError(ctl, _("Failed to extract interface information or no interfaces found"));
|
|
||||||
|
if (virAsprintf(&xpath, "/domain/devices/interface[(mac/@address = '%s') or "
|
||||||
|
" (target/@dev = '%s')]",
|
||||||
|
macstr, iface) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virMacAddrParse(iface, &macaddr) == 0) {
|
if ((ninterfaces = virXPathNodeSet(xpath, ctxt, &interfaces)) < 0) {
|
||||||
element = "mac";
|
vshError(ctl, _("Failed to extract interface information"));
|
||||||
attr = "address";
|
|
||||||
} else {
|
|
||||||
element = "target";
|
|
||||||
attr = "dev";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find interface with matching mac addr */
|
|
||||||
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
|
||||||
cur = obj->nodesetval->nodeTab[i]->children;
|
|
||||||
|
|
||||||
while (cur) {
|
|
||||||
if (cur->type == XML_ELEMENT_NODE &&
|
|
||||||
xmlStrEqual(cur->name, BAD_CAST element)) {
|
|
||||||
|
|
||||||
value = virXMLPropString(cur, attr);
|
|
||||||
|
|
||||||
if (STRCASEEQ(value, iface)) {
|
|
||||||
VIR_FREE(value);
|
|
||||||
goto hit;
|
|
||||||
}
|
|
||||||
VIR_FREE(value);
|
|
||||||
}
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vshError(ctl, _("Interface (%s: %s) not found."), element, iface);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
hit:
|
if (ninterfaces != 1) {
|
||||||
cur = obj->nodesetval->nodeTab[i]->children;
|
if (macstr[0])
|
||||||
while (cur) {
|
vshError(ctl, _("Interface (mac: %s) not found."), macstr);
|
||||||
if (cur->type == XML_ELEMENT_NODE &&
|
else
|
||||||
xmlStrEqual(cur->name, BAD_CAST "link")) {
|
vshError(ctl, _("Interface (dev: %s) not found."), iface);
|
||||||
|
|
||||||
state = virXMLPropString(cur, "state");
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->node = interfaces[0];
|
||||||
|
|
||||||
|
if ((state = virXPathString("string(./link/@state)", ctxt)))
|
||||||
vshPrint(ctl, "%s %s", iface, state);
|
vshPrint(ctl, "%s %s", iface, state);
|
||||||
VIR_FREE(state);
|
else
|
||||||
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attribute not found */
|
|
||||||
vshPrint(ctl, "%s default", iface);
|
vshPrint(ctl, "%s default", iface);
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
xmlXPathFreeObject(obj);
|
VIR_FREE(desc);
|
||||||
|
VIR_FREE(state);
|
||||||
|
VIR_FREE(interfaces);
|
||||||
|
VIR_FREE(xpath);
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
virDomainFree(dom);
|
virDomainFree(dom);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user