[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 1/2] hostdev: Detect untracked inactive devices



Unmanaged devices are attached to guests in two steps: first,
the device is detached from the host and marked as inactive;
subsequently, it is marked as active and attached to the guest.

If the daemon is restarted between these two operations, we lose
track of the inactive device.

Steps 5 and 6 of virHostdevPreparePCIDevices() already subtly
take care of this situation, but some planned changes will make
it so that's no longer the case. Plus, explicit is always better
than implicit.
---
 src/util/virhostdev.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index e0d6465..7204bd7 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -560,7 +560,8 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
         }
     }
 
-    /* Step 2: detach managed devices (i.e. bind to appropriate stub driver) */
+    /* Step 2: detach managed devices and make sure unmanaged devices
+     *         have already been taken care of */
     for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
         virPCIDevicePtr pci = virPCIDeviceListGet(pcidevs, i);
 
@@ -577,8 +578,48 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
                                    mgr->inactivePCIHostdevs) < 0)
                 goto reattachdevs;
         } else {
-            VIR_DEBUG("Not detaching unmanaged PCI device %s",
-                      virPCIDeviceGetName(pci));
+            char *driverPath;
+            char *driverName;
+            int stub;
+
+            /* Unmanaged devices should already have been marked as
+             * inactive: if that's the case, we can simply move on */
+            if (virPCIDeviceListFind(mgr->inactivePCIHostdevs, pci)) {
+                VIR_DEBUG("Not detaching unmanaged PCI device %s",
+                          virPCIDeviceGetName(pci));
+                continue;
+            }
+
+            /* If that's not the case, though, it might be because the
+             * daemon has been restarted, causing us to lose track of the
+             * device. Try and recover by marking the device as inactive
+             * if it happens to be bound to a known stub driver.
+             *
+             * FIXME Get rid of this once a proper way to keep track of
+             *       information about active / inactive device across
+             *       daemon restarts has been implemented */
+
+            if (virPCIDeviceGetDriverPathAndName(pci,
+                                                 &driverPath, &driverName) < 0)
+                goto reattachdevs;
+
+            stub = virPCIStubDriverTypeFromString(driverName);
+
+            VIR_FREE(driverPath);
+            VIR_FREE(driverName);
+
+            if (stub >= 0 &&
+                stub != VIR_PCI_STUB_DRIVER_NONE) {
+
+                /* The device is bound to a known stub driver: store this
+                 * information and add a copy to the inactive list */
+                virPCIDeviceSetStubDriver(pci, stub);
+
+                VIR_DEBUG("Adding PCI device %s to inactive list",
+                          virPCIDeviceGetName(pci));
+                if (virPCIDeviceListAddCopy(mgr->inactivePCIHostdevs, pci) < 0)
+                    goto reattachdevs;
+            }
         }
     }
 
-- 
2.5.0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]