[libvirt] [PATCH 1/2] virsh: Introduce virshDomainDetachInterface function.

Nitesh Konkar niteshkonkar.libvirt at gmail.com
Thu Apr 28 09:11:42 UTC 2016


virshDomainDetachInterface handles virsh interface
detach from the specified live/config domain xml.

Signed-off-by: Nitesh Konkar <nitkon12 at linux.vnet.ibm.com>
---
 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




More information about the libvir-list mailing list