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