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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list