diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index ce84e4d8c1..23fbaac889 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -507,23 +507,29 @@ void virNodeDeviceObjListRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr obj) { - virNodeDeviceDefPtr def; - if (!obj) return; - def = obj->def; virObjectRef(obj); virObjectUnlock(obj); virObjectRWLockWrite(devs); virObjectLock(obj); - virHashRemoveEntry(devs->objs, def->name); + virNodeDeviceObjListRemoveLocked(devs, obj); virObjectUnlock(obj); virObjectUnref(obj); virObjectRWUnlock(devs); } +/* The caller must hold lock on 'devs' */ +void +virNodeDeviceObjListRemoveLocked(virNodeDeviceObjList *devs, + virNodeDeviceObj *dev) +{ + virHashRemoveEntry(devs->objs, dev->def->name); +} + + /* * Return the NPIV dev's parent device name */ @@ -1019,3 +1025,47 @@ virNodeDeviceObjSetPersistent(virNodeDeviceObj *obj, { obj->persistent = persistent; } + + +struct virNodeDeviceObjListRemoveHelperData +{ + virNodeDeviceObjListRemoveIterator callback; + void *opaque; +}; + +static int virNodeDeviceObjListRemoveHelper(void *key G_GNUC_UNUSED, + void *value, + void *opaque) +{ + struct virNodeDeviceObjListRemoveHelperData *data = opaque; + + return data->callback(value, data->opaque); +} + + +/** + * virNodeDeviceObjListForEachRemove + * @devs: Pointer to object list + * @callback: function to call for each device object + * @opaque: Opaque data to use as argument to helper + * + * For each object in @devs, call the @callback helper using @opaque as + * an argument. If @callback returns true, that item will be removed from the + * object list. + */ +void +virNodeDeviceObjListForEachRemove(virNodeDeviceObjList *devs, + virNodeDeviceObjListRemoveIterator callback, + void *opaque) +{ + struct virNodeDeviceObjListRemoveHelperData data = { + .callback = callback, + .opaque = opaque + }; + + virObjectRWLockWrite(devs); + g_hash_table_foreach_remove(devs->objs, + virNodeDeviceObjListRemoveHelper, + &data); + virObjectRWUnlock(devs); +} diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h index 7f682b9dca..a41742c257 100644 --- a/src/conf/virnodedeviceobj.h +++ b/src/conf/virnodedeviceobj.h @@ -80,6 +80,10 @@ void virNodeDeviceObjListRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr dev); +void +virNodeDeviceObjListRemoveLocked(virNodeDeviceObjList *devs, + virNodeDeviceObj *dev); + int virNodeDeviceObjListGetParentHost(virNodeDeviceObjListPtr devs, virNodeDeviceDefPtr def); @@ -134,3 +138,10 @@ virNodeDeviceObjIsPersistent(virNodeDeviceObj *obj); void virNodeDeviceObjSetPersistent(virNodeDeviceObj *obj, bool persistent); + +typedef bool (*virNodeDeviceObjListRemoveIterator)(virNodeDeviceObj *obj, + const void *opaque); + +void virNodeDeviceObjListForEachRemove(virNodeDeviceObjList *devs, + virNodeDeviceObjListRemoveIterator callback, + void *opaque); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 047314ec19..f36400b5f6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1280,12 +1280,14 @@ virNodeDeviceObjListFindByName; virNodeDeviceObjListFindBySysfsPath; virNodeDeviceObjListFindMediatedDeviceByUUID; virNodeDeviceObjListFindSCSIHostByWWNs; +virNodeDeviceObjListForEachRemove; virNodeDeviceObjListFree; virNodeDeviceObjListGetNames; virNodeDeviceObjListGetParentHost; virNodeDeviceObjListNew; virNodeDeviceObjListNumOfDevices; virNodeDeviceObjListRemove; +virNodeDeviceObjListRemoveLocked; virNodeDeviceObjSetActive; virNodeDeviceObjSetPersistent;