[libvirt] [PATCH v2 3/9] hostdev: Use common reattach code in virHostdevPCINodeDeviceReAttach()

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


This ensures the behavior for reattach is consistent, no matter how it
was triggered (eg. 'virsh nodedev-reattach', 'virsh detach-device' or
shutdown of a domain that is configured to use hostdevs).
---
 src/util/virhostdev.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 586937e..f40d636 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -1637,10 +1637,24 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
     return ret;
 }
 
+/**
+ * virHostdevPCINodeDeviceReAttach:
+ * @hostdev_mgr: hostdev manager
+ * @pci: PCI device
+ *
+ * Reattach a specific PCI device to the host.
+ *
+ * This function makes sure the device is not in use before reattaching it
+ * to the host; if the device has already been reattached to the host, the
+ * operation is considered successful.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
 int
 virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
                                 virPCIDevicePtr pci)
 {
+    virPCIDevicePtr actual;
     struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, NULL,
                                                      false};
     int ret = -1;
@@ -1651,10 +1665,23 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
     if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
         goto out;
 
-    virPCIDeviceReattachInit(pci);
+    /* We want this function to be idempotent, so if the device has already
+     * been removed from the inactive list (and is not active either, as
+     * per the check above) just return right away. We also need to retrieve
+     * the actual device from the inactive list because that's the one that
+     * contains state information such as the stub driver */
+    if (!(actual = virPCIDeviceListFind(hostdev_mgr->inactivePCIHostdevs,
+                                        pci))) {
+        VIR_DEBUG("PCI device %s is already attached to the host",
+                  virPCIDeviceGetName(pci));
+        ret = 0;
+        goto out;
+    }
 
-    if (virPCIDeviceReattach(pci, hostdev_mgr->activePCIHostdevs,
-                             hostdev_mgr->inactivePCIHostdevs) < 0)
+    /* Reattach the device. We don't want to skip unmanaged devices in
+     * this case, because the user explicitly asked for the device to
+     * be reattached to the host driver */
+    if (virHostdevOnlyReattachPCIDevice(hostdev_mgr, actual, false) < 0)
         goto out;
 
     ret = 0;
-- 
2.5.0




More information about the libvir-list mailing list