mirror of
https://github.com/libvirt/libvirt.git
synced 2026-08-11 05:24:44 -05:00
qemu: fix attach/detach of netdevs with matching mac addrs
This resolves: https://bugzilla.redhat.com/show_bug.cgi?id=862515 which describes inconsistencies in dealing with duplicate mac addresses on network devices in a domain. (at any rate, it resolves *almost* everything, and prints out an informative error message for the one problem that isn't solved, but has a workaround.) A synopsis of the problems: 1) you can't do a persistent attach-interface of a device with a mac address that matches an existing device. 2) you *can* do a live attach-interface of such a device. 3) you *can* directly edit a domain and put in two devices with matching mac addresses. 4) When running virsh detach-device (live or config), only MAC address is checked when matching the device to remove, so the first device with the desired mac address will be removed. This isn't always the one that's wanted. 5) when running virsh detach-interface (live or config), the only two items that can be specified to match against are mac address and model type (virtio, etc) - if multiple netdevs match both of those attributes, it again just finds the first one added and assumes that is the only match. Since it is completely valid to have multiple network devices with the same MAC address (although it can cause problems in many cases, there *are* valid use cases), what is needed is: 1) remove the restriction that prohibits doing a persistent add of a netdev with a duplicate mac address. 2) enhance the backend of virDomainDetachDeviceFlags to check for something that *is* guaranteed unique (but still work with just mac address, as long as it yields only a single results. This patch does three things: 1) removes the check for duplicate mac address during a persistent netdev attach. 2) unifies the searching for both live and config detach of netdevices in the subordinate functions of qemuDomainModifyDeviceFlags() to use the new function virDomainNetFindIdx (which matches mac address and PCI address if available, checking for duplicates if only mac address was specified). This function returns -2 if multiple matches are found, allowing the callers to print out an appropriate message. Steps 1 & 2 are enough to fully fix the problem when using virsh attach-device and detach-device (which require an XML description of the device rather than a bunch of commandline args) 3) modifies the virsh detach-interface command to check for multiple matches of mac address and show an error message suggesting use of the detach-device command in cases where there are multiple matching mac addresses. Later we should decide how we want to input a PCI address on the virsh commandline, and enhance detach-interface to take a --address option, eliminating the need to use detach-device * src/conf/domain_conf.c * src/conf/domain_conf.h * src/libvirt_private.syms * added new virDomainNetFindIdx function * removed now unused virDomainNetIndexByMac and virDomainNetRemoveByMac * src/qemu/qemu_driver.c * remove check for duplicate max from qemuDomainAttachDeviceConfig * use virDomainNetFindIdx/virDomainNetRemove instead of virDomainNetRemoveByMac in qemuDomainDetachDeviceConfig * use virDomainNetFindIdx instead of virDomainIndexByMac in qemuDomainUpdateDeviceConfig * src/qemu/qemu_hotplug.c * use virDomainNetFindIdx instead of a homespun loop in qemuDomainDetachNetDevice. * tools/virsh-domain.c: modified detach-interface command as described above
This commit is contained in:
+19
-7
@@ -7692,7 +7692,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||
xmlDocPtr xml = NULL;
|
||||
xmlXPathObjectPtr obj=NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
xmlNodePtr cur = NULL;
|
||||
xmlNodePtr cur = NULL, matchNode = NULL;
|
||||
xmlBufferPtr xml_buf = NULL;
|
||||
const char *mac =NULL, *type = NULL;
|
||||
char *doc;
|
||||
@@ -7738,10 +7738,12 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!mac)
|
||||
if (!mac) {
|
||||
matchNode = obj->nodesetval->nodeTab[0];
|
||||
goto hit;
|
||||
}
|
||||
|
||||
/* search mac */
|
||||
/* multiple possibilities, so search for matching mac */
|
||||
for (; i < obj->nodesetval->nodeNr; i++) {
|
||||
cur = obj->nodesetval->nodeTab[i]->children;
|
||||
while (cur != NULL) {
|
||||
@@ -7751,14 +7753,24 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||
diff_mac = virMacAddrCompare(tmp_mac, mac);
|
||||
VIR_FREE(tmp_mac);
|
||||
if (!diff_mac) {
|
||||
goto hit;
|
||||
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;
|
||||
}
|
||||
}
|
||||
vshError(ctl, _("No found interface whose MAC address is %s"), mac);
|
||||
goto cleanup;
|
||||
if (!matchNode) {
|
||||
vshError(ctl, _("No interface with MAC address %s was found"), mac);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hit:
|
||||
xml_buf = xmlBufferCreate();
|
||||
@@ -7767,7 +7779,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (xmlNodeDump(xml_buf, xml, obj->nodesetval->nodeTab[i], 0, 0) < 0) {
|
||||
if (xmlNodeDump(xml_buf, xml, matchNode, 0, 0) < 0) {
|
||||
vshError(ctl, "%s", _("Failed to create XML"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user