From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> To allow modifications to the lists to be synchronized, convert virPCIDeviceList and virUSBDeviceList into virObjectLockable classes. The locking, however, will not be self-contained. The users of these classes will have to call virObjectLock/Unlock in the critical regions. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/libvirt_private.syms | 2 -- src/lxc/lxc_hostdev.c | 4 ++-- src/qemu/qemu_driver.c | 6 +++--- src/qemu/qemu_hostdev.c | 20 ++++++++++---------- src/qemu/qemu_hotplug.c | 4 ++-- src/util/virpci.c | 35 ++++++++++++++++++++++++++--------- src/util/virpci.h | 2 +- src/util/virusb.c | 48 ++++++++++++++++++++++++++++++++---------------- src/util/virusb.h | 2 +- 9 files changed, 77 insertions(+), 46 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 60c8ba3..765025a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1007,7 +1007,6 @@ virPCIDeviceListCount; virPCIDeviceListDel; virPCIDeviceListFind; virPCIDeviceListFindIndex; -virPCIDeviceListFree; virPCIDeviceListGet; virPCIDeviceListNew; virPCIDeviceListSteal; @@ -1233,7 +1232,6 @@ virUSBDeviceListAdd; virUSBDeviceListCount; virUSBDeviceListDel; virUSBDeviceListFind; -virUSBDeviceListFree; virUSBDeviceListGet; virUSBDeviceListNew; virUSBDeviceListSteal; diff --git a/src/lxc/lxc_hostdev.c b/src/lxc/lxc_hostdev.c index a627714..33b0b60 100644 --- a/src/lxc/lxc_hostdev.c +++ b/src/lxc/lxc_hostdev.c @@ -167,7 +167,7 @@ virLXCFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev, *usb = virUSBDeviceListGet(devs, 0); virUSBDeviceListSteal(devs, *usb); } - virUSBDeviceListFree(devs); + virObjectUnref(devs); if (rc == 0) { goto out; @@ -273,7 +273,7 @@ virLXCPrepareHostUSBDevices(virLXCDriverPtr driver, ret = 0; cleanup: - virUSBDeviceListFree(list); + virObjectUnref(list); return ret; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f7e9406..b34b8e1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1047,9 +1047,9 @@ qemuShutdown(void) { qemuDriverLock(qemu_driver); virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver); - virPCIDeviceListFree(qemu_driver->activePciHostdevs); - virPCIDeviceListFree(qemu_driver->inactivePciHostdevs); - virUSBDeviceListFree(qemu_driver->activeUsbHostdevs); + virObjectUnref(qemu_driver->activePciHostdevs); + virObjectUnref(qemu_driver->inactivePciHostdevs); + virObjectUnref(qemu_driver->activeUsbHostdevs); virHashFree(qemu_driver->sharedDisks); virCapabilitiesFree(qemu_driver->caps); qemuCapsCacheFree(qemu_driver->capsCache); diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index 46a17a7..3dfcf63 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -56,13 +56,13 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) hostdev->source.subsys.u.pci.slot, hostdev->source.subsys.u.pci.function); if (!dev) { - virPCIDeviceListFree(list); + virObjectUnref(list); return NULL; } if (virPCIDeviceListAdd(list, dev) < 0) { virPCIDeviceFree(dev); - virPCIDeviceListFree(list); + virObjectUnref(list); return NULL; } @@ -98,14 +98,14 @@ qemuGetActivePciHostDeviceList(virQEMUDriverPtr driver, hostdev->source.subsys.u.pci.slot, hostdev->source.subsys.u.pci.function); if (!dev) { - virPCIDeviceListFree(list); + virObjectUnref(list); return NULL; } if ((activeDev = virPCIDeviceListFind(driver->activePciHostdevs, dev))) { if (virPCIDeviceListAdd(list, activeDev) < 0) { virPCIDeviceFree(dev); - virPCIDeviceListFree(list); + virObjectUnref(list); return NULL; } } @@ -557,7 +557,7 @@ int qemuPrepareHostdevPCIDevices(virQEMUDriverPtr driver, inactivedevs: /* Only steal all the devices from driver->activePciHostdevs. We will - * free them in virPCIDeviceListFree(). + * free them in virObjectUnref(). */ while (virPCIDeviceListCount(pcidevs) > 0) { virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, 0); @@ -580,7 +580,7 @@ reattachdevs: } cleanup: - virPCIDeviceListFree(pcidevs); + virObjectUnref(pcidevs); virObjectUnref(cfg); return ret; } @@ -686,7 +686,7 @@ qemuFindHostdevUSBDevice(virDomainHostdevDefPtr hostdev, *usb = virUSBDeviceListGet(devs, 0); virUSBDeviceListSteal(devs, *usb); } - virUSBDeviceListFree(devs); + virObjectUnref(devs); if (rc == 0) { goto out; @@ -792,7 +792,7 @@ qemuPrepareHostUSBDevices(virQEMUDriverPtr driver, ret = 0; cleanup: - virUSBDeviceListFree(list); + virObjectUnref(list); return ret; } @@ -880,7 +880,7 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver, continue; } - /* virPCIDeviceListFree() will take care of freeing the dev. */ + /* virObjectUnref() will take care of freeing the dev. */ virPCIDeviceListSteal(driver->activePciHostdevs, dev); } @@ -916,7 +916,7 @@ void qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver, qemuReattachPciDevice(dev, driver); } - virPCIDeviceListFree(pcidevs); + virObjectUnref(pcidevs); cleanup: virObjectUnref(cfg); } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5b6e2c5..450a62e 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1221,7 +1221,7 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver, goto error; } - virUSBDeviceListFree(list); + virObjectUnref(list); return 0; error: @@ -1230,7 +1230,7 @@ error: VIR_WARN("Unable to restore host device labelling on hotplug fail"); cleanup: - virUSBDeviceListFree(list); + virObjectUnref(list); if (usb) virUSBDeviceListSteal(driver->activeUsbHostdevs, usb); return -1; diff --git a/src/util/virpci.c b/src/util/virpci.c index 695f372..5044f40 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -74,6 +74,8 @@ struct _virPCIDevice { }; struct _virPCIDeviceList { + virObjectLockable parent; + unsigned count; virPCIDevicePtr *devs; }; @@ -165,6 +167,23 @@ struct _virPCIDeviceList { PCI_EXT_CAP_ACS_CR | \ PCI_EXT_CAP_ACS_UF) +static virClassPtr virPCIDeviceListClass; + +static void virPCIDeviceListDispose(void *obj); + +static int virPCIOnceInit(void) +{ + if (!(virPCIDeviceListClass = virClassNew(virClassForObjectLockable(), + "virPCIDeviceList", + sizeof(virPCIDeviceList), + virPCIDeviceListDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virPCI) + static int virPCIDeviceConfigOpen(virPCIDevicePtr dev, bool fatal) { @@ -1505,22 +1524,21 @@ virPCIDeviceListNew(void) { virPCIDeviceListPtr list; - if (VIR_ALLOC(list) < 0) { - virReportOOMError(); + if (virPCIInitialize() < 0) + return NULL; + + if (!(list = virObjectLockableNew(virPCIDeviceListClass))) return NULL; - } return list; } -void -virPCIDeviceListFree(virPCIDeviceListPtr list) +static void +virPCIDeviceListDispose(void *obj) { + virPCIDeviceListPtr list = obj; int i; - if (!list) - return; - for (i = 0; i < list->count; i++) { virPCIDeviceFree(list->devs[i]); list->devs[i] = NULL; @@ -1528,7 +1546,6 @@ virPCIDeviceListFree(virPCIDeviceListPtr list) list->count = 0; VIR_FREE(list->devs); - VIR_FREE(list); } int diff --git a/src/util/virpci.h b/src/util/virpci.h index 3ca7545..4eaf788 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -25,6 +25,7 @@ # define __VIR_PCI_H__ # include "internal.h" +# include "virobject.h" typedef struct _virPCIDevice virPCIDevice; typedef virPCIDevice *virPCIDevicePtr; @@ -78,7 +79,6 @@ void virPCIDeviceReAttachInit(virPCIDevice *dev); virPCIDeviceListPtr virPCIDeviceListNew(void); -void virPCIDeviceListFree(virPCIDeviceListPtr list); int virPCIDeviceListAdd(virPCIDeviceListPtr list, virPCIDevicePtr dev); virPCIDevicePtr virPCIDeviceListGet(virPCIDeviceListPtr list, diff --git a/src/util/virusb.c b/src/util/virusb.c index 88119e4..5974602 100644 --- a/src/util/virusb.c +++ b/src/util/virusb.c @@ -57,6 +57,7 @@ struct _virUSBDevice { }; struct _virUSBDeviceList { + virObjectLockable parent; unsigned int count; virUSBDevicePtr *devs; }; @@ -67,6 +68,23 @@ typedef enum { USB_DEVICE_FIND_BY_BUS = 1 << 1, } virUSBDeviceFindFlags; +static virClassPtr virUSBDeviceListClass; + +static void virUSBDeviceListDispose(void *obj); + +static int virUSBOnceInit(void) +{ + if (!(virUSBDeviceListClass = virClassNew(virClassForObjectLockable(), + "virUSBDeviceList", + sizeof(virUSBDeviceList), + virUSBDeviceListDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virUSB) + static int virUSBSysReadFile(const char *f_name, const char *d_name, int base, unsigned int *value) { @@ -184,7 +202,7 @@ cleanup: } if (!ret) - virUSBDeviceListFree(list); + virObjectUnref(list); return ret; } @@ -204,7 +222,7 @@ virUSBDeviceFindByVendor(unsigned int vendor, return -1; if (list->count == 0) { - virUSBDeviceListFree(list); + virObjectUnref(list); if (!mandatory) { VIR_DEBUG("Did not find USB device %x:%x", vendor, product); @@ -222,7 +240,7 @@ virUSBDeviceFindByVendor(unsigned int vendor, if (devices) *devices = list; else - virUSBDeviceListFree(list); + virObjectUnref(list); return count; } @@ -242,7 +260,7 @@ virUSBDeviceFindByBus(unsigned int bus, return -1; if (list->count == 0) { - virUSBDeviceListFree(list); + virObjectUnref(list); if (!mandatory) { VIR_DEBUG("Did not find USB device bus:%u device:%u", bus, devno); @@ -261,7 +279,7 @@ virUSBDeviceFindByBus(unsigned int bus, *usb = virUSBDeviceListGet(list, 0); virUSBDeviceListSteal(list, *usb); } - virUSBDeviceListFree(list); + virObjectUnref(list); return 0; } @@ -283,7 +301,7 @@ virUSBDeviceFind(unsigned int vendor, return -1; if (list->count == 0) { - virUSBDeviceListFree(list); + virObjectUnref(list); if (!mandatory) { VIR_DEBUG("Did not find USB device %x:%x bus:%u device:%u", vendor, product, bus, devno); @@ -302,7 +320,7 @@ virUSBDeviceFind(unsigned int vendor, *usb = virUSBDeviceListGet(list, 0); virUSBDeviceListSteal(list, *usb); } - virUSBDeviceListFree(list); + virObjectUnref(list); return 0; } @@ -404,27 +422,25 @@ virUSBDeviceListNew(void) { virUSBDeviceListPtr list; - if (VIR_ALLOC(list) < 0) { - virReportOOMError(); + if (virUSBInitialize() < 0) + return NULL; + + if (!(list = virObjectLockableNew(virUSBDeviceListClass))) return NULL; - } return list; } -void -virUSBDeviceListFree(virUSBDeviceListPtr list) +static void +virUSBDeviceListDispose(void *obj) { + virUSBDeviceListPtr list = obj; int i; - if (!list) - return; - for (i = 0; i < list->count; i++) virUSBDeviceFree(list->devs[i]); VIR_FREE(list->devs); - VIR_FREE(list); } int diff --git a/src/util/virusb.h b/src/util/virusb.h index f231a41..aa59d12 100644 --- a/src/util/virusb.h +++ b/src/util/virusb.h @@ -26,6 +26,7 @@ # define __VIR_USB_H__ # include "internal.h" +# include "virobject.h" # define USB_DEVFS "/dev/bus/usb/" @@ -81,7 +82,6 @@ int virUSBDeviceFileIterate(virUSBDevicePtr dev, void *opaque); virUSBDeviceListPtr virUSBDeviceListNew(void); -void virUSBDeviceListFree(virUSBDeviceListPtr list); int virUSBDeviceListAdd(virUSBDeviceListPtr list, virUSBDevicePtr dev); virUSBDevicePtr virUSBDeviceListGet(virUSBDeviceListPtr list, -- 1.8.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list