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(a)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