]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Fix memory (and FD) leak on PCI device detach
authorJiri Denemark <jdenemar@redhat.com>
Tue, 4 Dec 2012 08:18:44 +0000 (09:18 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 5 Dec 2012 12:45:34 +0000 (13:45 +0100)
Unmanaged PCI devices were only leaked if pciDeviceListAdd failed but
managed devices were always leaked. And leaking PCI device is likely to
leave PCI config file descriptor open. This patch fixes
qemuReattachPciDevice to either free the PCI device or add it to the
inactivePciHostdevs list.

src/qemu/qemu_hostdev.c

index b79319e389abb57d215be8d9c591b64489896439..a748b8b3027a4fde0e37dc21753dee023106e954 100644 (file)
@@ -546,10 +546,8 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver,
     }
 
     /* Loop 9: Now steal all the devices from pcidevs */
-    while (pciDeviceListCount(pcidevs) > 0) {
-        pciDevice *dev = pciDeviceListGet(pcidevs, 0);
-        pciDeviceListSteal(pcidevs, dev);
-    }
+    while (pciDeviceListCount(pcidevs) > 0)
+        pciDeviceListStealIndex(pcidevs, 0);
 
     ret = 0;
     goto cleanup;
@@ -818,7 +816,8 @@ void qemuReattachPciDevice(pciDevice *dev, virQEMUDriverPtr driver)
      * successfully, it must have been inactive.
      */
     if (!pciDeviceGetManaged(dev)) {
-        pciDeviceListAdd(driver->inactivePciHostdevs, dev);
+        if (pciDeviceListAdd(driver->inactivePciHostdevs, dev) < 0)
+            pciFreeDevice(dev);
         return;
     }
 
@@ -835,6 +834,7 @@ void qemuReattachPciDevice(pciDevice *dev, virQEMUDriverPtr driver)
                   err ? err->message : _("unknown error"));
         virResetError(err);
     }
+    pciFreeDevice(dev);
 }
 
 
@@ -905,8 +905,8 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
         }
     }
 
-    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
-        pciDevice *dev = pciDeviceListGet(pcidevs, i);
+    while (pciDeviceListCount(pcidevs) > 0) {
+        pciDevice *dev = pciDeviceListStealIndex(pcidevs, 0);
         qemuReattachPciDevice(dev, driver);
     }