nodedev: fix pci express memory leak

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@redhat.com>
This commit is contained in:
Eric Blake 2014-07-22 22:38:30 -06:00
parent be05c1414d
commit c6a4d268af
5 changed files with 19 additions and 2 deletions

View File

@ -1291,7 +1291,7 @@ virNodeDevCapPCIDevParseXML(xmlXPathContextPtr ctxt,
ret = 0; ret = 0;
out: out:
VIR_FREE(pci_express); virPCIEDeviceInfoFree(pci_express);
ctxt->node = orignode; ctxt->node = orignode;
return ret; return ret;
} }
@ -1664,6 +1664,7 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
VIR_FREE(data->pci_dev.iommuGroupDevices[i]); VIR_FREE(data->pci_dev.iommuGroupDevices[i]);
} }
VIR_FREE(data->pci_dev.iommuGroupDevices); VIR_FREE(data->pci_dev.iommuGroupDevices);
virPCIEDeviceInfoFree(data->pci_dev.pci_express);
break; break;
case VIR_NODE_DEV_CAP_USB_DEV: case VIR_NODE_DEV_CAP_USB_DEV:
VIR_FREE(data->usb_dev.product_name); VIR_FREE(data->usb_dev.product_name);

View File

@ -1753,6 +1753,7 @@ virPCIDeviceSetUnbindFromStub;
virPCIDeviceSetUsedBy; virPCIDeviceSetUsedBy;
virPCIDeviceUnbind; virPCIDeviceUnbind;
virPCIDeviceWaitForCleanup; virPCIDeviceWaitForCleanup;
virPCIEDeviceInfoFree;
virPCIGetNetName; virPCIGetNetName;
virPCIGetPhysicalFunction; virPCIGetPhysicalFunction;
virPCIGetVirtualFunctionIndex; virPCIGetVirtualFunctionIndex;

View File

@ -570,7 +570,7 @@ static int udevProcessPCI(struct udev_device *device,
out: out:
virPCIDeviceFree(pciDev); virPCIDeviceFree(pciDev);
VIR_FREE(pci_express); virPCIEDeviceInfoFree(pci_express);
return ret; return ret;
} }

View File

@ -2847,3 +2847,15 @@ virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
virPCIDeviceConfigClose(dev, fd); virPCIDeviceConfigClose(dev, fd);
return ret; return ret;
} }
void
virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev)
{
if (!dev)
return;
VIR_FREE(dev->link_cap);
VIR_FREE(dev->link_sta);
VIR_FREE(dev);
}

View File

@ -212,4 +212,7 @@ int virPCIDeviceGetLinkCapSta(virPCIDevicePtr dev,
unsigned int *cap_width, unsigned int *cap_width,
unsigned int *sta_speed, unsigned int *sta_speed,
unsigned int *sta_width); unsigned int *sta_width);
void virPCIEDeviceInfoFree(virPCIEDeviceInfoPtr dev);
#endif /* __VIR_PCI_H__ */ #endif /* __VIR_PCI_H__ */