From 00b649d0cfdc0e9170ec2ff1afc43a25c08ebe49 Mon Sep 17 00:00:00 2001 From: Jonathon Jongsma Date: Thu, 15 Oct 2020 11:30:35 -0500 Subject: [PATCH] nodedev: add helper functions to remove node devices When a mediated device is stopped or undefined by an application outside of libvirt, we need to remove it from our list of node devices within libvirt. This patch introduces virNodeDeviceObjListRemoveLocked() and virNodeDeviceObjListForEachRemove() (which are analogous to other types of object lists in libvirt) to facilitate that. They will be used in coming commits. Signed-off-by: Jonathon Jongsma Reviewed-by: Erik Skultety --- src/conf/virnodedeviceobj.c | 58 ++++++++++++++++++++++++++++++++++--- src/conf/virnodedeviceobj.h | 11 +++++++ src/libvirt_private.syms | 2 ++ 3 files changed, 67 insertions(+), 4 deletions(-) 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;