[libvirt] [PATCH v5 09/15] util: Introduce virObjectLookupHashClone

John Ferlan jferlan at redhat.com
Wed Aug 23 21:22:05 UTC 2017


A convenience API that will utilize the virHashForEach API for the
LookupHash in order to create a clone/copy. Primary consumer is the
interface driver which has a desire to save off a copy of its only
hash table in order to possible restore it if something goes wrong
during processing.

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

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b32004e..ecbd84a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2331,6 +2331,7 @@ virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
 virObjectLookupHashAdd;
+virObjectLookupHashClone;
 virObjectLookupHashFind;
 virObjectLookupHashFindLocked;
 virObjectLookupHashForEachName;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index b20e938..7152b17 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -1179,3 +1179,86 @@ virObjectLookupHashSearchName(void *anyobj,
 
     return obj;
 }
+
+
+struct cloneData {
+    virObjectLookupHashCloneCallback callback;
+    virObjectLookupHashPtr dst;
+    bool error;
+};
+
+/*
+ * Take the provided virHashForEach element and call the @cb function
+ * with the input @dst hash table and the source element from the
+ * @src hash table in order to perform the copy - tracking success/
+ * failure using the error boolean.
+ *
+ * Once there's a failure, no future copy/clone will occur.
+ *
+ * The @cb function can expect the @src hash table object to be
+ * locked upon entry.
+ *
+ * Returns 0 to the virHashForEach on success, -1 on failure.
+ */
+static int
+cloneCallback(void *payload,
+              const void *name ATTRIBUTE_UNUSED,
+              void *opaque)
+{
+    virObjectLockablePtr obj = payload;
+    struct cloneData *data = opaque;
+
+    if (data->error)
+        return 0;
+
+    virObjectLock(obj);
+
+    if (data->callback(data->dst, obj) < 0)
+        data->error = true;
+
+    virObjectUnlock(obj);
+
+    if (data->error)
+        return -1;
+
+    return 0;
+}
+
+/**
+ * virObjectLookupHashClone
+ * @srcAnyobj: source LookupHash object to clone from
+ * @dstAnyobj: destination LookupHash object to clone to
+ * @cb: callback function to handle the clone
+ *
+ * The clone function is designed to traverse each source hash entry
+ * and call the driver specific @cb function with the element from the
+ * source hash table in order to clone into the destination hash table.
+ * This will be done for each hash table that exists.
+ *
+ * Return 0 on success, -1 on failure
+ */
+int
+virObjectLookupHashClone(void *srcAnyobj,
+                         void *dstAnyobj,
+                         virObjectLookupHashCloneCallback cb)
+{
+    virObjectLookupHashPtr srcHashObj = virObjectGetLookupHashObj(srcAnyobj);
+    virObjectLookupHashPtr dstHashObj = virObjectGetLookupHashObj(dstAnyobj);
+    struct cloneData data = { .callback = cb, .dst = dstHashObj,
+        .error = false };
+
+    if (!srcHashObj || !dstHashObj)
+        return -1;
+
+    virObjectRWLockRead(srcHashObj);
+    if (srcHashObj->objsUUID)
+        virHashForEach(srcHashObj->objsUUID, cloneCallback, &data);
+    if (srcHashObj->objsName)
+        virHashForEach(srcHashObj->objsName, cloneCallback, &data);
+    virObjectRWUnlock(srcHashObj);
+
+    if (data.error)
+        return -1;
+
+    return 0;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 03a23e0..66b44ca 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -256,4 +256,13 @@ virObjectLookupHashSearchName(void *anyobj,
                               void *opaque)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+typedef int (*virObjectLookupHashCloneCallback)(void *dstHashTable,
+                                                void *sourceObject);
+int
+virObjectLookupHashClone(void *srcAnyobj,
+                         void *dstAnyobj,
+                         virObjectLookupHashCloneCallback cb)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.5




More information about the libvir-list mailing list