[libvirt] [PATCH 5/7] hostdev: Use common detach code in virHostdevPCINodeDeviceDetach()

Andrea Bolognani abologna at redhat.com
Tue Jan 19 15:36:07 UTC 2016


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




More information about the libvir-list mailing list