[libvirt] [PATCH v2 4/9] hostdev: Add virHostdevOnlyDetachPCIDevice()

Andrea Bolognani abologna at redhat.com
Mon Jan 25 16:20:59 UTC 2016


This function mirrors virHostdevOnlyDetachPCIDevice().

The handling of active and inactive devices is updated and made more
explicit, which means virHostdevPreparePCIDevices() has to be
updated as well.
---
 src/util/virhostdev.c | 87 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 61 insertions(+), 26 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index f40d636..6f14574 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -594,6 +594,56 @@ virHostdevOnlyReattachPCIDevice(virHostdevManagerPtr mgr,
     return ret;
 }
 
+/**
+ * virHostdevOnlyDetachPCIDevice:
+ * @mgr: hostdev manager
+ * @pci: PCI device to be detached
+ * @skipUnmanaged: whether to skip unmanaged devices
+ *
+ * Detach a PCI device from the host.
+ *
+ * This function only performs the base detach steps that are required
+ * regardless of whether the device is being attached to a domain or
+ * is simply being detached from the host for later use.
+ *
+ * The PCI related parts of @mgr (inactivePCIHostdevs, activePCIHostdevs)
+ * must have been locked beforehand using virObjectLock().
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+static int
+virHostdevOnlyDetachPCIDevice(virHostdevManagerPtr mgr,
+                              virPCIDevicePtr pci,
+                              bool skipUnmanaged)
+{
+    int ret = -1;
+
+    /* Skip unmanaged devices if asked to do so */
+    if (!virPCIDeviceGetManaged(pci) && skipUnmanaged) {
+        VIR_DEBUG("Not detaching unmanaged PCI device %s",
+                  virPCIDeviceGetName(pci));
+        ret = 0;
+        goto out;
+    }
+
+    VIR_DEBUG("Detaching PCI device %s", virPCIDeviceGetName(pci));
+    if (virPCIDeviceDetach(pci,
+                           mgr->activePCIHostdevs,
+                           mgr->inactivePCIHostdevs) < 0) {
+        virErrorPtr err = virGetLastError();
+        VIR_ERROR(_("Failed to detach PCI device %s: %s"),
+                  virPCIDeviceGetName(pci),
+                  err ? err->message : _("unknown error"));
+        virResetError(err);
+        goto out;
+    }
+
+    ret = 0;
+
+ out:
+    return ret;
+}
+
 int
 virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
                             const char *drv_name,
@@ -664,17 +714,8 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
     for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
         virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
-        if (virPCIDeviceGetManaged(dev)) {
-            VIR_DEBUG("Detaching managed PCI device %s",
-                      virPCIDeviceGetName(dev));
-            if (virPCIDeviceDetach(dev,
-                                   hostdev_mgr->activePCIHostdevs,
-                                   hostdev_mgr->inactivePCIHostdevs) < 0)
-                goto reattachdevs;
-        } else {
-            VIR_DEBUG("Not detaching unmanaged PCI device %s",
-                      virPCIDeviceGetName(dev));
-        }
+        if (virHostdevOnlyDetachPCIDevice(hostdev_mgr, dev, true) < 0)
+            goto reattachdevs;
     }
 
     /* At this point, all devices are attached to the stub driver and have
@@ -704,23 +745,21 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
          last_processed_hostdev_vf = i;
     }
 
-    /* Loop 5: Now mark all the devices as active */
+    /* Step 5: move all devices from the inactive list to the active list */
     for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
         virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
+        virPCIDevicePtr actual;
 
-        VIR_DEBUG("Adding PCI device %s to active list",
+        VIR_DEBUG("Removing PCI device %s from inactive list",
                   virPCIDeviceGetName(dev));
-        if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, dev) < 0)
+        if (!(actual = virPCIDeviceListSteal(hostdev_mgr->inactivePCIHostdevs,
+                                             dev)))
             goto inactivedevs;
-    }
-
-    /* Loop 6: Now remove the devices from inactive list. */
-    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
-        VIR_DEBUG("Removing PCI device %s from inactive list",
-                  virPCIDeviceGetName(dev));
-        virPCIDeviceListDel(hostdev_mgr->inactivePCIHostdevs, dev);
+        VIR_DEBUG("Adding PCI device %s to active list",
+                  virPCIDeviceGetName(actual));
+        if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, actual) < 0)
+            goto inactivedevs;
     }
 
     /* Loop 7: Now set the used_by_domain of the device in
@@ -771,10 +810,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
         virPCIDeviceFree(dev);
     }
 
-    /* Loop 9: Now steal all the devices from pcidevs */
-    while (virPCIDeviceListCount(pcidevs) > 0)
-        virPCIDeviceListStealIndex(pcidevs, 0);
-
     ret = 0;
     goto cleanup;
 
-- 
2.5.0




More information about the libvir-list mailing list