virshDomainDetachInterface handles virsh interface
detach from the specified live/config domain xml.
Signed-off-by: Nitesh Konkar <nitkon12(a)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