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 virNodeDeviceObjListForEach() (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 <jjongsma@xxxxxxxxxx> --- src/conf/virnodedeviceobj.c | 65 ++++++++++++++++++++++++++++++++++--- src/conf/virnodedeviceobj.h | 12 +++++++ src/libvirt_private.syms | 2 ++ 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index 53cf3d1bcd..681ad54314 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(virNodeDeviceObjListPtr devs, + virNodeDeviceObjPtr dev) +{ + virHashRemoveEntry(devs->objs, dev->def->name); +} + + /* * Return the NPIV dev's parent device name */ @@ -1014,3 +1020,54 @@ virNodeDeviceObjSetPersistent(virNodeDeviceObjPtr obj, { obj->persistent = persistent; } + + +struct _virNodeDeviceObjListForEachData { + virNodeDeviceObjListIterator iter; + const void *opaque; +}; + + +static int +virNodeDeviceObjListForEachCb(void *payload, + const char *name G_GNUC_UNUSED, + void *opaque) +{ + virNodeDeviceObjPtr obj = payload; + struct _virNodeDeviceObjListForEachData *data = opaque; + + /* Grab a reference so that we don't rely only on references grabbed by + * hash table earlier. Remember, an iterator can remove object from the + * hash table. */ + virObjectRef(obj); + virObjectLock(obj); + data->iter(obj, data->opaque); + virNodeDeviceObjEndAPI(&obj); + + return 0; +} + + +/** + * virNodeDeviceObjListForEach + * @devs: Pointer to object list + * @iter: Callback iteration helper + * @opaque: Opaque data to use as argument to helper + * + * For each object in @devs, call the @iter helper using @opaque as + * an argument. + */ +void +virNodeDeviceObjListForEachSafe(virNodeDeviceObjListPtr devs, + virNodeDeviceObjListIterator iter, + const void *opaque) +{ + struct _virNodeDeviceObjListForEachData data = { + .iter = iter, + .opaque = opaque + }; + + virObjectRWLockWrite(devs); + virHashForEachSafe(devs->objs, virNodeDeviceObjListForEachCb, &data); + virObjectRWUnlock(devs); +} diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h index 43af012103..a7d12674b4 100644 --- a/src/conf/virnodedeviceobj.h +++ b/src/conf/virnodedeviceobj.h @@ -80,6 +80,10 @@ void virNodeDeviceObjListRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr dev); +void +virNodeDeviceObjListRemoveLocked(virNodeDeviceObjListPtr devs, + virNodeDeviceObjPtr dev); + int virNodeDeviceObjListGetParentHost(virNodeDeviceObjListPtr devs, virNodeDeviceDefPtr def); @@ -134,3 +138,11 @@ virNodeDeviceObjIsPersistent(virNodeDeviceObjPtr obj); void virNodeDeviceObjSetPersistent(virNodeDeviceObjPtr obj, bool persistent); + +typedef void +(*virNodeDeviceObjListIterator)(virNodeDeviceObjPtr obj, + const void *opaque); + +void virNodeDeviceObjListForEachSafe(virNodeDeviceObjListPtr devs, + virNodeDeviceObjListIterator iter, + const void *opaque); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d044a1111b..69090a7efe 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1269,12 +1269,14 @@ virNodeDeviceObjListFindByName; virNodeDeviceObjListFindBySysfsPath; virNodeDeviceObjListFindMediatedDeviceByUUID; virNodeDeviceObjListFindSCSIHostByWWNs; +virNodeDeviceObjListForEachSafe; virNodeDeviceObjListFree; virNodeDeviceObjListGetNames; virNodeDeviceObjListGetParentHost; virNodeDeviceObjListNew; virNodeDeviceObjListNumOfDevices; virNodeDeviceObjListRemove; +virNodeDeviceObjListRemoveLocked; virNodeDeviceObjSetActive; virNodeDeviceObjSetPersistent; -- 2.26.2