Previously stubDriver was always set from a string literal, so it was
okay to use a const char * that wasn't freed when the virPCIDevice was
freed. This will not be the case in the near future, so it is now a
char* that is allocated in virPCIDeviceSetStubDriver() and freed
during virPCIDeviceFree().
---
src/qemu/qemu_driver.c | 6 ++++--
src/qemu/qemu_hostdev.c | 25 +++++++++++++++++--------
src/util/virpci.c | 8 +++++---
src/util/virpci.h | 4 ++--
src/xen/xen_driver.c | 3 ++-
5 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3d9457f..6efec74 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10286,9 +10286,11 @@ qemuNodeDeviceDetachFlags(virNodeDevicePtr dev,
return -1;
if (!driverName || STREQ(driverName, "kvm")) {
- virPCIDeviceSetStubDriver(pci, "pci-stub");
+ if (virPCIDeviceSetStubDriver(pci, "pci-stub") < 0)
+ goto out;
} else if (STREQ(driverName, "vfio")) {
- virPCIDeviceSetStubDriver(pci, "vfio-pci");
+ if (virPCIDeviceSetStubDriver(pci, "vfio-pci") < 0)
+ goto out;
} else {
virReportError(VIR_ERR_INVALID_ARG,
_("unknown driver name '%s'"), driverName);
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 9013f60..7a9e6eb 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 89c1eea..d00c3ee 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 7bcadb4..17b15fe 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 3efc27a..2506b8e 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -2237,7 +2237,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);
--
1.7.11.7