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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list