[libvirt] [PATCH v3 12/16] util: Introduce virObjectLookupHashForEach

John Ferlan jferlan at redhat.com
Thu Jun 22 14:02:42 UTC 2017


Introduce an API to use the virHashForEach API to go through each element
of a specified LookupHash (via @useUUID) calling a callback with a LookupKey
object entry from the LookupHash in order for it to be processed.

Create a common structure to define the various pieces of data needed by
the callback consumers:

    struct _virObjectLookupHashForEachData {
        virConnectPtr conn;        -> Connect ptr for @aclfilter APIs
        void *aclfilter;           -> A pointer to function for ACL calls
        bool wantActive;           -> Filter active objs
        bool error;                -> Set by callback functions for error
        const char *matchstr;      -> Filter for specific string in many objs
        unsigned int flags;        -> @flags argument to for Export calls
        int nelems;                -> # of elements found and passing filters
        void **elems;              -> array of elements
        int maxelems;              -> maximum # of elements to collect
    };

Upon successful completion, the data.nelems is returned to the caller
and possibly various fields within the structure filled in depending
on the callers need as follows:

    vir{Object}NumOf{Elem}
        => Would typically only care about @nelems based on whether
           the caller cares about @wantActive. Can also filter results
           based on the @aclfilter call.

    vir{Object}Get{Key}
        => Use the @elems and @maxelems in order to fill in an array
           of char ** strings based on the {Key} filtering data as
           necessary from the @aclfilter and possibly the @matchstr.
           Callers of this function will preallocate the @elems and
           supply the @maxelems value. The @nelems is used to keep track
           of the number of elements.

    vir{Object}Export
        => When @maxelems == -1, will cause allocation into data->elems
           of an array sized by the hash table size which will be used by
           the callback function to store addresses of objects specific to
           each {Object} that are typically assocated with virConnectListAll*
           API's from the virGet{Object}() calls. The @flags argument is
           typically used for additional filtering via vir{Object}Match or
           vir{Object}Filter APIs found in various vir*obj modules. Upon
           return from the call, the calling function must then move the
           data->elems into the returned structure.

It is up to the callback function to set @error in the event of an error
during processing resulting in calling the VIR_FREE() for each of the
@nelems already in the array.

When an error occurs, any collection done by the callback functions into
the @elems array is discarded.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virobject.c     | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virobject.h     | 20 ++++++++++++++++
 3 files changed, 82 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 68961e7..f783fec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2288,6 +2288,7 @@ virObjectLock;
 virObjectLockableNew;
 virObjectLookupHashAdd;
 virObjectLookupHashFind;
+virObjectLookupHashForEach;
 virObjectLookupHashGetName;
 virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 01922b3..8a994f5 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -893,3 +893,64 @@ virObjectLookupHashGetName(void *anyobj)
 
     return obj->objsName;
 }
+
+
+/**
+ * virObjectLookupHashForEach
+ * @tableobj: poolable hash table pointer to walk through
+ * @useUUID: boolean to use objsUUID
+ * @callback: callback function to handle the object specific checks
+ * @opaque: callback data
+ *
+ * For each element of the objsName hash table make a call into the
+ * callback routine to handle its task
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virObjectLookupHashForEach(void *tableobj,
+                           bool useUUID,
+                           virHashIterator callback,
+                           virObjectLookupHashForEachDataPtr data)
+{
+    virObjectLookupHashPtr hashObj = virObjectGetLookupHashObj(tableobj);
+    virHashTablePtr tbl;
+
+    if (!hashObj)
+        return -1;
+
+    if (useUUID)
+        tbl = hashObj->objsUUID;
+    else
+        tbl = hashObj->objsName;
+
+    if (data->maxelems == -1) {
+        if (VIR_ALLOC_N(data->elems, virHashSize(tbl) + 1) < 0)
+            return -1;
+    }
+
+    virObjectLock(hashObj);
+    virHashForEach(tbl, callback, data);
+    virObjectUnlock(hashObj);
+
+    if (data->error)
+        goto error;
+
+    if (data->maxelems == -1) {
+        /* trim the array to the final size */
+        ignore_value(VIR_REALLOC_N(data->elems, data->nelems + 1));
+    }
+
+    return data->nelems;
+
+ error:
+    if (data->elems) {
+        if (data->maxelems == -1) {
+            virObjectListFree(data->elems);
+        } else {
+            while (--data->nelems)
+                VIR_FREE(data->elems[data->nelems]);
+        }
+    }
+    return -1;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index ed99540..926c9d3 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -198,4 +198,24 @@ virObjectLookupHashGetUUID(void *anyobj);
 virHashTablePtr
 virObjectLookupHashGetName(void *anyobj);
 
+typedef struct _virObjectLookupHashForEachData virObjectLookupHashForEachData;
+typedef virObjectLookupHashForEachData *virObjectLookupHashForEachDataPtr;
+struct _virObjectLookupHashForEachData {
+    virConnectPtr conn;
+    void *aclfilter;
+    bool wantActive;
+    bool error;
+    const char *matchstr;
+    unsigned int flags;
+    int nelems;
+    void **elems;
+    int maxelems;
+};
+
+int
+virObjectLookupHashForEach(void *tableobj,
+                           bool useUUID,
+                           virHashIterator callback,
+                           virObjectLookupHashForEachDataPtr data);
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.4




More information about the libvir-list mailing list