void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver, const char *name, virDomainHostdevDefPtr *hostdevs, int nhostdevs) { pciDeviceList *pcidevs; int i; if (!(pcidevs = qemuGetActivePciHostDeviceList(driver, hostdevs, nhostdevs))) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to allocate pciDeviceList: %s"), err ? err->message : _("unknown error")); virResetError(err); return; } /* Again 3 loops; mark all devices as inactive before reset * them and reset all the devices before re-attach */ for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); pciDevice *activeDev = NULL; /* Never delete the dev from list driver->activePciHostdevs * if it's used by other domain. */ activeDev = pciDeviceListFind(driver->activePciHostdevs, dev); if (activeDev && STRNEQ_NULLABLE(name, pciDeviceGetUsedBy(activeDev))) { pciDeviceListSteal(pcidevs, dev); continue; } /* pciDeviceListFree() will take care of freeing the dev. */ pciDeviceListSteal(driver->activePciHostdevs, dev); } for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); if (pciResetDevice(dev, driver->activePciHostdevs, driver->inactivePciHostdevs) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to reset PCI device: %s"), err ? err->message : _("unknown error")); virResetError(err); } } for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); qemuReattachPciDevice(dev, driver); } pciDeviceListFree(pcidevs); }
void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver, const char *name, virDomainHostdevDefPtr *hostdevs, int nhostdevs) { pciDeviceList *pcidevs; int i; if (!(pcidevs = qemuGetActivePciHostDeviceList(driver, hostdevs, nhostdevs))) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to allocate pciDeviceList: %s"), err ? err->message : _("unknown error")); virResetError(err); return; } /* Again 4 loops; mark all devices as inactive before reset * them and reset all the devices before re-attach. * Attach mac and port profile parameters to devices */ for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); pciDevice *activeDev = NULL; /* Never delete the dev from list driver->activePciHostdevs * if it's used by other domain. */ activeDev = pciDeviceListFind(driver->activePciHostdevs, dev); if (activeDev && STRNEQ_NULLABLE(name, pciDeviceGetUsedBy(activeDev))) { pciDeviceListSteal(pcidevs, dev); continue; } /* pciDeviceListFree() will take care of freeing the dev. */ pciDeviceListSteal(driver->activePciHostdevs, dev); } /* * For SRIOV net host devices, unset mac and port profile before * reset and reattach device */ for (i = 0; i < nhostdevs; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && hostdev->parent.data.net) { qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir); } } for (i = 0; i < pciDeviceListCount(pcidevs); i++) { pciDevice *dev = pciDeviceListGet(pcidevs, i); if (pciResetDevice(dev, driver->activePciHostdevs, driver->inactivePciHostdevs) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to reset PCI device: %s"), err ? err->message : _("unknown error")); virResetError(err); } } while (pciDeviceListCount(pcidevs) > 0) { pciDevice *dev = pciDeviceListStealIndex(pcidevs, 0); qemuReattachPciDevice(dev, driver); } pciDeviceListFree(pcidevs); }
void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver, const char *name, virDomainHostdevDefPtr *hostdevs, int nhostdevs) { virPCIDeviceListPtr pcidevs; size_t i; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virObjectLock(driver->activePciHostdevs); virObjectLock(driver->inactivePciHostdevs); if (!(pcidevs = qemuGetActivePciHostDeviceList(driver, hostdevs, nhostdevs))) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to allocate PCI device list: %s"), err ? err->message : _("unknown error")); virResetError(err); goto cleanup; } /* Again 4 loops; mark all devices as inactive before reset * them and reset all the devices before re-attach. * Attach mac and port profile parameters to devices */ for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) { virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i); virPCIDevicePtr activeDev = NULL; /* delete the copy of the dev from pcidevs if it's used by * other domain. Or delete it from activePciHostDevs if it had * been used by this domain. */ activeDev = virPCIDeviceListFind(driver->activePciHostdevs, dev); if (activeDev && STRNEQ_NULLABLE(name, virPCIDeviceGetUsedBy(activeDev))) { virPCIDeviceListDel(pcidevs, dev); continue; } virPCIDeviceListDel(driver->activePciHostdevs, dev); } /* At this point, any device that had been used by the guest is in * pcidevs, but has been removed from activePciHostdevs. */ /* * For SRIOV net host devices, unset mac and port profile before * reset and reattach device */ for (i = 0; i < nhostdevs; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET && hostdev->parent.data.net) { qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir); } } for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) { virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i); if (virPCIDeviceReset(dev, driver->activePciHostdevs, driver->inactivePciHostdevs) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to reset PCI device: %s"), err ? err->message : _("unknown error")); virResetError(err); } } while (virPCIDeviceListCount(pcidevs) > 0) { virPCIDevicePtr dev = virPCIDeviceListStealIndex(pcidevs, 0); qemuReattachPciDevice(dev, driver); } virObjectUnref(pcidevs); cleanup: virObjectUnlock(driver->activePciHostdevs); virObjectUnlock(driver->inactivePciHostdevs); virObjectUnref(cfg); }