This ensures the behavior for detach is consistent, no matter how it was triggered (eg. 'virsh nodedev-detach', 'virsh attach-device' or startup of a domain that is configured to use hostdevs). --- src/util/virhostdev.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index 2d219dd..bc7dd77 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -1630,6 +1630,7 @@ int virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr, virPCIDevicePtr pci) { + virPCIDeviceListPtr pcidevs = NULL; struct virHostdevIsPCINodeDeviceUsedData data = { hostdev_mgr, NULL, false }; int ret = -1; @@ -1638,17 +1639,37 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr, virObjectLock(hostdev_mgr->inactivePCIHostdevs); if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data)) - goto out; + goto cleanup; - if (virPCIDeviceDetach(pci, hostdev_mgr->activePCIHostdevs, - hostdev_mgr->inactivePCIHostdevs) < 0) { - goto out; + /* We want this function to be idempotent, so if the device has already + * been added to the inactive list (and is not active, as per the check + * above) just return right away */ + if (virPCIDeviceListFind(hostdev_mgr->inactivePCIHostdevs, pci)) { + VIR_DEBUG("PCI device %s is already detached from the host", + virPCIDeviceGetName(pci)); + ret = 0; + goto cleanup; } + /* Create a temporary device list */ + if (!(pcidevs = virPCIDeviceListNew())) + goto cleanup; + if (virPCIDeviceListAddCopy(pcidevs, pci) < 0) + goto cleanup; + + /* Detach the device. We don't want to skip unmanaged devices in + * this case, because the user explicitly asked for the device to + * be detached from the host driver */ + if (detachPCIDevices(hostdev_mgr, pcidevs, false) < 0) + goto cleanup; + ret = 0; - out: + + cleanup: + virObjectUnref(pcidevs); virObjectUnlock(hostdev_mgr->inactivePCIHostdevs); virObjectUnlock(hostdev_mgr->activePCIHostdevs); + return ret; } -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list