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.
The callback function's primary purpose is to copy anything within
the local LookupKeys into the target.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virobject.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virobject.h | 9 ++++++
3 files changed, 89 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index df3f246..c7c9762 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2332,6 +2332,7 @@ virObjectListFreeCount;
virObjectLock;
virObjectLockableNew;
virObjectLookupHashAdd;
+virObjectLookupHashClone;
virObjectLookupHashFind;
virObjectLookupHashFindLocked;
virObjectLookupHashForEach;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 17ea4e6..0a4195d 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -1167,3 +1167,82 @@ virObjectLookupHashSearch(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)
+{
+ virObjectLookupKeysPtr 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 element
+ * and call the driver specific @cb function with the element from the
+ * source hash table in order to clone into the destination hash table.
+ *
+ * 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);
+ virHashForEach(srcHashObj->objsKey1, cloneCallback, &data);
+ virObjectRWUnlock(srcHashObj);
+
+ if (data.error)
+ return -1;
+
+ return 0;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index d4bc3c3..b9e6311 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -252,4 +252,13 @@ virObjectLookupHashSearch(void *anyobj,
void *opaque)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+typedef int (*virObjectLookupHashCloneCallback)(void *destHashTable,
+ 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.4