The virsh attach virsh detach interface command fails when both live and config are set and when the interface gets attached to different pci slots on live and config xml respectively. When we attach an interface with both --live and --config, the first time they get the same PCI slots, but the second time onwards it differs and hence the virsh detach-interface --live --config command fails. This patch makes sure that when both --live --config are set , qemuDomainDetachDeviceFlags is called twice, once with config xml and once with live xml. --- Change log: v4: * Code unchanged, updated with commit message,change log and steps to reproduce the issue.. v3: * Created function vshDomainDetachInterface and called it once/twice from cmdDetachInterface depending on number of flags set (live/config/both). Passed the correct xml(live/persistent) to it. v2: * Changes only in cmdDetachInterface to pass the right domain xml depending on the flag set (live/config/both). v1: * Changes only in qemuDomainDetachDeviceFlags to set the right value in dev and dev_copy. Steps to see the issue: virsh attach-interface --domain DomainName --type network --source default --mac 52:54:00:4b:76:5f --live --config virsh detach-interface --domain DomainName --type network --mac 52:54:00:4b:76:5f --live --config virsh attach-interface --domain DomainName --type network --source default --mac 52:54:00:4b:76:5f --live --config virsh detach-interface --domain DomainName --type network --mac 52:54:00:4b:76:5f --live --config tools/virsh-domain.c | 104 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 62acecb..a6abaf5 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10801,40 +10801,21 @@ static const vshCmdOptDef opts_detach_interface[] = { {.name = NULL} }; -static bool -cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) +static bool +vshDomainDetachInterface(char *doc, unsigned int flags, virDomainPtr dom, vshControl *ctl, const vshCmd *cmd) { - virDomainPtr dom = NULL; xmlDocPtr xml = NULL; xmlXPathObjectPtr obj = NULL; xmlXPathContextPtr ctxt = NULL; xmlNodePtr cur = NULL, matchNode = NULL; - char *detach_xml = NULL; const char *mac = NULL, *type = NULL; - char *doc = NULL; + char *detach_xml = NULL; + bool current = vshCommandOptBool(cmd, "current"); char buf[64]; int diff_mac; size_t i; int ret; bool functionReturn = false; - unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; - bool current = vshCommandOptBool(cmd, "current"); - bool config = vshCommandOptBool(cmd, "config"); - bool live = vshCommandOptBool(cmd, "live"); - bool persistent = vshCommandOptBool(cmd, "persistent"); - - VSH_EXCLUSIVE_OPTIONS_VAR(persistent, current); - - VSH_EXCLUSIVE_OPTIONS_VAR(current, live); - VSH_EXCLUSIVE_OPTIONS_VAR(current, config); - - if (config || persistent) - flags |= VIR_DOMAIN_AFFECT_CONFIG; - if (live) - flags |= VIR_DOMAIN_AFFECT_LIVE; - - if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) - return false; if (vshCommandOptStringReq(ctl, cmd, "type", &type) < 0) goto cleanup; @@ -10842,15 +10823,6 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptStringReq(ctl, cmd, "mac", &mac) < 0) goto cleanup; - if (persistent && - virDomainIsActive(dom) == 1) - flags |= VIR_DOMAIN_AFFECT_LIVE; - - if (flags & VIR_DOMAIN_AFFECT_CONFIG) - doc = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE); - else - doc = virDomainGetXMLDesc(dom, 0); - if (!doc) goto cleanup; @@ -10918,23 +10890,75 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) else ret = virDomainDetachDevice(dom, detach_xml); - if (ret != 0) { - vshError(ctl, "%s", _("Failed to detach interface")); - } else { - vshPrint(ctl, "%s", _("Interface detached successfully\n")); + if (ret == 0) functionReturn = true; - } cleanup: - VIR_FREE(doc); VIR_FREE(detach_xml); - virDomainFree(dom); + xmlFreeDoc(xml); xmlXPathFreeObject(obj); xmlXPathFreeContext(ctxt); - xmlFreeDoc(xml); return functionReturn; } +static bool +cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; + char *doc_live = NULL, *doc_config = NULL; + bool current = vshCommandOptBool(cmd, "current"); + bool config = vshCommandOptBool(cmd, "config"); + bool live = vshCommandOptBool(cmd, "live"); + bool persistent = vshCommandOptBool(cmd, "persistent"); + bool functionReturn = false; + + VSH_EXCLUSIVE_OPTIONS_VAR(persistent, current); + + VSH_EXCLUSIVE_OPTIONS_VAR(current, live); + VSH_EXCLUSIVE_OPTIONS_VAR(current, config); + + if (config || persistent) + flags |= VIR_DOMAIN_AFFECT_CONFIG; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (persistent && + virDomainIsActive(dom) == 1) + flags |= VIR_DOMAIN_AFFECT_LIVE; + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { + doc_config = virDomainGetXMLDesc(dom, VIR_DOMAIN_XML_INACTIVE); + if (!(functionReturn = vshDomainDetachInterface(doc_config, flags, dom, ctl, cmd))) + goto cleanup; + } + + if (live) + flags |= VIR_DOMAIN_AFFECT_LIVE; + + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + doc_live = virDomainGetXMLDesc(dom, 0); + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) + flags &= (~VIR_DOMAIN_AFFECT_CONFIG); + + functionReturn = vshDomainDetachInterface(doc_live, flags, dom, ctl, cmd); + } + + cleanup: + if (functionReturn == false) { + vshError(ctl, "%s", _("Failed to detach interface")); + } else { + vshPrint(ctl, "%s", _("Interface detached successfully\n")); + functionReturn = true; + } + VIR_FREE(doc_live); + VIR_FREE(doc_config); + virDomainFree(dom); + return functionReturn; +} + typedef enum { VIRSH_FIND_DISK_NORMAL, VIRSH_FIND_DISK_CHANGEABLE, -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list