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(a)redhat.com>
---
src/conf/virnodedeviceobj.c | 62 ++++++++++++++++++++++++++++++++++---
src/conf/virnodedeviceobj.h | 12 +++++++
src/libvirt_private.syms | 2 ++
3 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
index 6e9291264a..5f0b21f8bf 100644
--- a/src/conf/virnodedeviceobj.c
+++ b/src/conf/virnodedeviceobj.c
@@ -506,23 +506,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
*/
@@ -1000,3 +1006,51 @@ virNodeDeviceObjSetActive(virNodeDeviceObjPtr obj,
{
obj->active = active;
}
+
+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
+virNodeDeviceObjListForEach(virNodeDeviceObjListPtr devs,
+ virNodeDeviceObjListIterator iter,
+ const void *opaque)
+{
+ struct _virNodeDeviceObjListForEachData data = {
+ .iter = iter,
+ .opaque = opaque
+ };
+
+ virObjectRWLockWrite(devs);
+ virHashForEach(devs->objs, virNodeDeviceObjListForEachCb, &data);
+ virObjectRWUnlock(devs);
+}
diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h
index c119f4c51f..e672d8af61 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);
@@ -128,3 +132,11 @@ virNodeDeviceObjIsActive(virNodeDeviceObjPtr obj);
void
virNodeDeviceObjSetActive(virNodeDeviceObjPtr obj,
bool active);
+
+typedef void
+(*virNodeDeviceObjListIterator)(virNodeDeviceObjPtr obj,
+ const void *opaque);
+
+void virNodeDeviceObjListForEach(virNodeDeviceObjListPtr devs,
+ virNodeDeviceObjListIterator iter,
+ const void *opaque);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fecd012300..181d91792e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1210,12 +1210,14 @@ virNodeDeviceObjListFindByName;
virNodeDeviceObjListFindBySysfsPath;
virNodeDeviceObjListFindMediatedDeviceByUUID;
virNodeDeviceObjListFindSCSIHostByWWNs;
+virNodeDeviceObjListForEach;
virNodeDeviceObjListFree;
virNodeDeviceObjListGetNames;
virNodeDeviceObjListGetParentHost;
virNodeDeviceObjListNew;
virNodeDeviceObjListNumOfDevices;
virNodeDeviceObjListRemove;
+virNodeDeviceObjListRemoveLocked;
virNodeDeviceObjSetActive;
--
2.26.2