Currently, PCI devices will not be rebound to host drivers but attached to the stub driver when: 1) use libvirt to start a virtual machine with PCI devices assigned, then stop libvirtd process and shutdown the virtual machine. Finally, PCI devices are still bound to the stub driver instead of host drivers after libvirt start again. 2) use libvirt to shutdown a virtual machine wtih PCI devices assigned, then stop libvirtd process before libvirt try to rebind PCI devices to host drivers. Finally, PCI devices are still bound to the stub driver after libvirt start again. Notice that the comment on the top of virPCIDeviceDetach as follows: activeDevs should be a list of all PCI devices currently in use by a domain.inactiveDevs is a list of all PCI devices that libvirt has detached from the host driver + attached to the stub driver, but hasn't yet assigned to a domain. It's not reasonable that libvirt filter out devices that are either not active or not used by the current domain and driver. For devices belong to domains that has been shutdown before libvirt start, we should put them into inactiveDevs if then meet the condition that PCI devices have been detached from the host driver + attached to the stub driver. Moreover, we set orignal states of PCI devices when build PCI devices list in virHostdevGetPCIHostDeviceList if states has been set in struct virDomainHostdevDefPtr. Signed-off-by: Wu Zongyong <cordius.wu@xxxxxxxxxx> --- src/util/virhostdev.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index ca79c37..ecf95e3 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -235,6 +235,7 @@ virHostdevGetPCIHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) for (i = 0; i < nhostdevs; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci; + virDomainHostdevOrigStatesPtr origstates = &hostdev->origstates; virPCIDevicePtr pci; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) @@ -262,6 +263,10 @@ virHostdevGetPCIHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_XEN); else virPCIDeviceSetStubDriver(pci, VIR_PCI_STUB_DRIVER_KVM); + + virPCIDeviceSetUnbindFromStub(pci, origstates->states.pci.unbind_from_stub); + virPCIDeviceSetRemoveSlot(pci, origstates->states.pci.remove_slot); + virPCIDeviceSetReprobe(pci, origstates->states.pci.reprobe); } return pcidevs; @@ -1008,8 +1013,19 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr mgr, continue; } } else { - virPCIDeviceListDel(pcidevs, pci); - continue; + int stub = virPCIDeviceGetStubDriver(pci); + if (stub > VIR_PCI_STUB_DRIVER_NONE && + stub < VIR_PCI_STUB_DRIVER_LAST) { + /* The device is bound to a known stub driver: add a copy + * to the inactive list */ + VIR_DEBUG("Adding PCI device %s to inactive list", + virPCIDeviceGetName(pci)); + if (virPCIDeviceListAddCopy(mgr->inactivePCIHostdevs, pci) < 0) { + VIR_ERROR(_("Failed to add PCI device %s to the inactive list"), + virGetLastErrorMessage()); + virResetLastError(); + } + } } i++; -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list