virshDomainDetachInterface handles virsh interface detach from the specified live/config domain xml. Signed-off-by: Nitesh Konkar <nitkon12@xxxxxxxxxxxxxxxxxx> --- tools/virsh-domain.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 36d0353..7cb042b 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -11118,6 +11118,105 @@ static const vshCmdOptDef opts_detach_interface[] = { }; static bool +virshDomainDetachInterface(char *doc, unsigned int flags, virDomainPtr dom, vshControl *ctl, const vshCmd *cmd) +{ + xmlDocPtr xml = NULL; + xmlXPathObjectPtr obj = NULL; + xmlXPathContextPtr ctxt = NULL; + xmlNodePtr cur = NULL, matchNode = NULL; + const char *mac = NULL, *type = NULL; + char *detach_xml = NULL, buf[64]; + bool current = vshCommandOptBool(cmd, "current"); + int diff_mac,ret; + size_t i; + bool functionReturn = false; + + if (vshCommandOptStringReq(ctl, cmd, "type", &type) < 0) + goto cleanup; + + if (vshCommandOptStringReq(ctl, cmd, "mac", &mac) < 0) + goto cleanup; + + if (!doc) + goto cleanup; + + if (!(xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt))) { + vshError(ctl, "%s", _("Failed to get interface information")); + goto cleanup; + } + + 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) { + vshError(ctl, _("No interface found whose type is %s"), type); + goto cleanup; + } + + if (!mac && obj->nodesetval->nodeNr > 1) { + vshError(ctl, _("Domain has %d interfaces. Please specify which one " + "to detach using --mac"), obj->nodesetval->nodeNr); + goto cleanup; + } + + if (!mac) { + matchNode = obj->nodesetval->nodeTab[0]; + goto hit; + } + + /* 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 && + xmlStrEqual(cur->name, BAD_CAST "mac")) { + char *tmp_mac = virXMLPropString(cur, "address"); + diff_mac = virMacAddrCompare(tmp_mac, mac); + VIR_FREE(tmp_mac); + if (!diff_mac) { + if (matchNode) { + /* this is the 2nd match, so it's ambiguous */ + vshError(ctl, _("Domain has multiple interfaces matching " + "MAC address %s. You must use detach-device and " + "specify the device pci address to remove it."), + mac); + goto cleanup; + } + matchNode = obj->nodesetval->nodeTab[i]; + } + } + cur = cur->next; + } + } + if (!matchNode) { + vshError(ctl, _("No interface with MAC address %s was found"), mac); + goto cleanup; + } + + hit: + if (!(detach_xml = virXMLNodeToString(xml, matchNode))) { + vshSaveLibvirtError(); + goto cleanup; + } + + if (flags != 0 || current) + ret = virDomainDetachDeviceFlags(dom, detach_xml, flags); + else + ret = virDomainDetachDevice(dom, detach_xml); + + if (ret == 0) + functionReturn = true; + + cleanup: + VIR_FREE(detach_xml); + xmlFreeDoc(xml); + xmlXPathFreeObject(obj); + xmlXPathFreeContext(ctxt); + return functionReturn; +} + + +static bool cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom = NULL; -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list