[libvirt PATCH v3 08/21] nodedev: add helper functions to remove node devices

Jonathon Jongsma jjongsma at redhat.com
Thu Dec 24 14:14:32 UTC 2020


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 at 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




More information about the libvir-list mailing list