Leak introduced in commit 16ebf10f (v1.2.6), detected by valgrind:
==9816== 216 (96 direct, 120 indirect) bytes in 6 blocks are definitely lost in loss
record 665 of 821
==9816== at 0x4A081D4: calloc (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==9816== by 0x50836FB: virAlloc (viralloc.c:144)
==9816== by 0x1DBDBE27: udevProcessPCI (node_device_udev.c:546)
==9816== by 0x1DBDD79D: udevGetDeviceDetails (node_device_udev.c:1293)
* src/util/virpci.h (virPCIEDeviceInfoFree): New prototype.
* src/util/virpci.c (virPCIEDeviceInfoFree): New function.
* src/conf/node_device_conf.c (virNodeDevCapsDefFree): Clear
pci_express under pci case.
(virNodeDevCapPCIDevParseXML): Avoid leak.
* src/node_device/node_device_udev.c (udevProcessPCI): Likewise.
* src/libvirt_private.syms (virpci.h): Export it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/conf/node_device_conf.c | 3 ++-
src/libvirt_private.syms | 1 +
src/node_device/node_device_udev.c | 2 +-
src/util/virpci.c | 12 ++++++++++++
src/util/virpci.h | 3 +++
5 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index b244a1f..78bc63f 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -1291,7 +1291,7 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,
ret = 0;
out:
- VIR_FREE(pci_express);
+ virPCIEDeviceInfoFree(pci_express);
ctxt->node = orignode;
return ret;
}
@@ -1664,6 +1664,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
VIR_FREE(data->pci_dev.iommuGroupDevices[i]);
}
VIR_FREE(data->pci_dev.iommuGroupDevices);
+ virPCIEDeviceInfoFree(data->pci_dev.pci_express);
break;
case VIR_NODE_DEV_CAP_USB_DEV:
VIR_FREE(data->usb_dev.product_name);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 51504d1..fe02f9c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1753,6 +1753,7 @@ virPCIDeviceSetUnbindFromStub;
virPCIDeviceSetUsedBy;
virPCIDeviceUnbind;
virPCIDeviceWaitForCleanup;
+virPCIEDeviceInfoFree;
virPCIGetNetName;
virPCIGetPhysicalFunction;
virPCIGetVirtualFunctionIndex;
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 28d2953..0fe474d 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -570,7 +570,7 @@ static int udevProcessPCI(struct udev_device *device,
out:
virPCIDeviceFree(pciDev);
- VIR_FREE(pci_express);
+ virPCIEDeviceInfoFree(pci_express);
return ret;
}
diff --git a/src/util/virpci.c b/src/util/virpci.c
index b7400e9..0098d6c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2847,3 +2847,15 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
virPCIDeviceConfigClose(dev, fd);
return ret;
}
+
+
+void
+virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev)
+{
+ if (!dev)
+ return;
+
+ VIR_FREE(dev->link_cap);
+ VIR_FREE(dev->link_sta);
+ VIR_FREE(dev);
+}
diff --git a/src/util/virpci.h b/src/util/virpci.h
index edec439..3da8eb3 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -212,4 +212,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
unsigned int *cap_width,
unsigned int *sta_speed,
unsigned int *sta_width);
+
+void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
+
#endif /* __VIR_PCI_H__ */
--
1.9.3