diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cf857bbe15afaac4ce5602d95698e8e8c5258caf..2533ec84d1850021d4f21414a1b416b0a7c789ab 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10575,10 +10575,10 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev, unsigned int flags) { virQEMUDriverPtr driver = dev->conn->privateData; - virPCIDevicePtr pci; + virPCIDevicePtr pci = NULL; unsigned domain, bus, slot, function; int ret = -1; - bool in_inactive_list = false; + bool in_inactive_list = true; virNodeDeviceDefPtr def = NULL; char *xml = NULL; @@ -10603,13 +10603,15 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev, goto cleanup; if (!driverName || STREQ(driverName, "kvm")) { - virPCIDeviceSetStubDriver(pci, "pci-stub"); + if (virPCIDeviceSetStubDriver(pci, "pci-stub") < 0) + goto cleanup; } else if (STREQ(driverName, "vfio")) { - virPCIDeviceSetStubDriver(pci, "vfio-pci"); + if (virPCIDeviceSetStubDriver(pci, "vfio-pci") < 0) + goto cleanup; } else { virReportError(VIR_ERR_INVALID_ARG, _("unknown driver name '%s'"), driverName); - goto out; + goto cleanup; } virObjectLock(driver->activePciHostdevs); @@ -10624,9 +10626,9 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev, out: virObjectUnlock(driver->inactivePciHostdevs); virObjectUnlock(driver->activePciHostdevs); +cleanup: if (in_inactive_list) virPCIDeviceFree(pci); -cleanup: virNodeDeviceDefFree(def); VIR_FREE(xml); return ret; diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 9013f60afba4ebb2612ebb32c28c533475970a35..7a9e6eba05c46a3af34da8d22c001827e6f25851 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -70,9 +70,15 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) virPCIDeviceSetManaged(dev, hostdev->managed); if (hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { - virPCIDeviceSetStubDriver(dev, "vfio-pci"); + if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0) { + virObjectUnref(list); + return NULL; + } } else { - virPCIDeviceSetStubDriver(dev, "pci-stub"); + if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) { + virObjectUnref(list); + return NULL; + } } } @@ -130,6 +136,7 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver, virDomainDefPtr def) { virDomainHostdevDefPtr hostdev = NULL; + virPCIDevicePtr dev = NULL; int i; int ret = -1; @@ -140,7 +147,6 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver, virObjectLock(driver->inactivePciHostdevs); for (i = 0; i < def->nhostdevs; i++) { - virPCIDevicePtr dev = NULL; hostdev = def->hostdevs[i]; if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) @@ -159,9 +165,12 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver, virPCIDeviceSetManaged(dev, hostdev->managed); if (hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { - virPCIDeviceSetStubDriver(dev, "vfio-pci"); + if (virPCIDeviceSetStubDriver(dev, "vfio-pci") < 0) + goto cleanup; } else { - virPCIDeviceSetStubDriver(dev, "pci-stub"); + if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0) + goto cleanup; + } virPCIDeviceSetUsedBy(dev, def->name); @@ -170,14 +179,14 @@ int qemuUpdateActivePciHostdevs(virQEMUDriverPtr driver, virPCIDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot); virPCIDeviceSetReprobe(dev, hostdev->origstates.states.pci.reprobe); - if (virPCIDeviceListAdd(driver->activePciHostdevs, dev) < 0) { - virPCIDeviceFree(dev); + if (virPCIDeviceListAdd(driver->activePciHostdevs, dev) < 0) goto cleanup; - } + dev = NULL; } ret = 0; cleanup: + virPCIDeviceFree(dev); virObjectUnlock(driver->activePciHostdevs); virObjectUnlock(driver->inactivePciHostdevs); return ret; diff --git a/src/util/virpci.c b/src/util/virpci.c index 89c1eea4cb75c5fc7c9f2afbaaf37966a0d11c9b..d00c3ee8222ae41cf60c277a6810d3febf4b9366 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -69,7 +69,7 @@ struct _virPCIDevice { bool has_flr; bool has_pm_reset; bool managed; - const char *stubDriver; + char *stubDriver; /* used by reattach function */ bool unbind_from_stub; @@ -1480,6 +1480,7 @@ virPCIDeviceFree(virPCIDevicePtr dev) return; VIR_DEBUG("%s %s: freeing", dev->id, dev->name); VIR_FREE(dev->path); + VIR_FREE(dev->stubDriver); VIR_FREE(dev); } @@ -1500,10 +1501,11 @@ virPCIDeviceGetManaged(virPCIDevicePtr dev) return dev->managed; } -void +int virPCIDeviceSetStubDriver(virPCIDevicePtr dev, const char *driver) { - dev->stubDriver = driver; + VIR_FREE(dev->stubDriver); + return driver ? VIR_STRDUP(dev->stubDriver, driver) : 0; } const char * diff --git a/src/util/virpci.h b/src/util/virpci.h index 7bcadb42f6d5604d7a827c6308ac2c086002551b..17b15fef06482dab2ade1f267c7907b772b08e62 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -62,8 +62,8 @@ int virPCIDeviceReset(virPCIDevicePtr dev, void virPCIDeviceSetManaged(virPCIDevice *dev, bool managed); unsigned int virPCIDeviceGetManaged(virPCIDevice *dev); -void virPCIDeviceSetStubDriver(virPCIDevicePtr dev, - const char *driver); +int virPCIDeviceSetStubDriver(virPCIDevicePtr dev, + const char *driver); const char *virPCIDeviceGetStubDriver(virPCIDevicePtr dev); void virPCIDeviceSetUsedBy(virPCIDevice *dev, const char *used_by); diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index bf283a76c1eeebfe5c49df023d74ba893f6eb764..ffc6e414eb1301e2a8def7fc9cc9881b701e8c83 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2432,7 +2432,8 @@ xenUnifiedNodeDeviceDetachFlags(virNodeDevicePtr dev, return -1; if (!driverName) { - virPCIDeviceSetStubDriver(pci, "pciback"); + if (virPCIDeviceSetStubDriver(pci, "pciback") < 0) + goto out; } else { virReportError(VIR_ERR_INVALID_ARG, _("unknown driver name '%s'"), driverName);