On Fri, Mar 26, 2021 at 11:48:08AM -0500, Jonathon Jongsma wrote: > 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 <jjongsma@xxxxxxxxxx> > --- > 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..97e7d7ab11 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 virNodeDeviceObjListRemoveData Looking at other libvirt code, the precedent seems to be for this be named xyzListRemoveHelperData > +{ > + virNodeDeviceObjListRemoveIter iter; and ^this one should IMO be named xyzListRemoveIterator callback; > + void *opaque; > +}; > + > +static int virNodeDeviceObjListRemoveCb(void *key G_GNUC_UNUSED, > + void *value, > + void *opaque) > +{ > + struct virNodeDeviceObjListRemoveData *data = opaque; > + > + return data->iter(value, data->opaque); data->callback > +} > + > + > +/** > + * virNodeDeviceObjListForEachRemove > + * @devs: Pointer to object list > + * @iter: function to call for each device object s/iter/callback (it sounds odd that we're iterating over something and call another iterator over each item --> hence "callback") > + * @opaque: Opaque data to use as argument to helper > + * > + * For each object in @devs, call the @iter helper using @opaque as > + * an argument. If @iter returns true, that item will be removed from the > + * object list. > + */ > +void > +virNodeDeviceObjListForEachRemove(virNodeDeviceObjList *devs, > + virNodeDeviceObjListRemoveIter iter, > + void *opaque) > +{ > + struct virNodeDeviceObjListRemoveData data = { > + .iter = iter, > + .opaque = opaque > + }; > + > + virObjectRWLockWrite(devs); > + g_hash_table_foreach_remove(devs->objs, > + virNodeDeviceObjListRemoveCb, xyzListRemoveHelper... Reviewed-by: Erik Skultety <eskultet@xxxxxxxxxx>