[libvirt] [RFC PATCH 4/5] util: storagefile: Add deep copy for struct virStorageSource
Eric Blake
eblake at redhat.com
Thu Jun 12 22:38:17 UTC 2014
On 06/12/2014 09:02 AM, Peter Krempa wrote:
> Now that we have pointers to store disk source information and thus can
> easily exchange the structs behind we need a function to copy all the
> data.
> ---
> src/libvirt_private.syms | 1 +
> src/util/virstoragefile.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++
> src/util/virstoragefile.h | 2 +
> 3 files changed, 153 insertions(+)
>
> +virStorageSourcePtr
> +virStorageSourceCopy(const virStorageSource *src,
> + bool backingChain)
> +{
> + size_t i;
> + virStorageSourcePtr ret = NULL;
> +
> + if (VIR_ALLOC(ret) < 0)
> + return NULL;
> +
> + ret->type = src->type;
> + ret->protocol = src->protocol;
> + ret->format = src->format;
> + ret->allocation = src->allocation;
> + ret->capacity = src->capacity;
> + ret->backingRelative = src->backingRelative;
If I'm not mistaken, backingRelative disappears in your other series;
I'm guessing you plan on rebasing that on top of this to pick up on the
easier semantics.
> +
> + /* storage driver metadata are not copied */
> + ret->drv = NULL;
Seems okay, particularly since doing a deep copy of that would require
callback functions in the storage drivers.
> +
> + if (VIR_STRDUP(ret->path, src->path) < 0 ||
> + VIR_STRDUP(ret->volume, src->volume) < 0 ||
> + VIR_STRDUP(ret->driverName, src->driverName) < 0 ||
> + VIR_STRDUP(ret->relPath, src->relPath) < 0 ||
> + VIR_STRDUP(ret->relDir, src->relDir) < 0 ||
> + VIR_STRDUP(ret->backingStoreRaw, src->backingStoreRaw) < 0 ||
> + VIR_STRDUP(ret->compat, src->compat) < 0 ||
> + VIR_STRDUP(ret->auth.username, src->auth.username) < 0)
> + goto error;
...
> +
> + ret->auth.secretType = src->auth.secretType;
> + switch ((virStorageSecretType) src->auth.secretType) {
> + case VIR_STORAGE_SECRET_TYPE_NONE:
> + case VIR_STORAGE_SECRET_TYPE_LAST:
> + break;
It might be worth adding an intermediate patch to break out the embedded
auth struct into a formal top-level struct, then add a function that
copies an auth struct, rather than having to inline all the nested
struct work here. But for now I can live with it.
> + if (backingChain && src->backingStore) {
> + if (!(ret->backingStore = virStorageSourceCopy(src->backingStore,
> + true)))
> + goto error;
> + }
Nice - we have the choice of shallow or deep chain copy.
Random thought - I wonder if it would be better to make
virStorageSourcePtr inherit from virObject, and make it
reference-counted, so that we can share a single object among multiple
users rather than copying users right and left. But even if it is a
good idea, it's enough refactoring that I don't think we need to tackle
it right away.
> +
> + ret->nseclabels = src->nseclabels;
> + if (VIR_ALLOC_N(ret->seclabels, ret->nseclabels) < 0)
> + goto error;
Maybe consider swapping those two lines. Unlike my comment in patch
1/5, in _this_ case, we were careful enough that virStorageSourceClear
checks seclabels for non-NULL before paying attention to nseclabels.
But as we are not consistently careful in the clear/free functions, it's
more robust to just get in the habit of setting the count after the
allocation is successful without having to check a particular free
function. Hmm - do I dare suggest simplifying virStorageSourceClear to
unconditionally iterate over nseclabels instead of hiding it in an 'if
(def->seclabels)' block? Or is it better form to suggest that all
cleanup functions be audited to be robust to non-zero count but NULL arrays?
> +++ b/src/util/virstoragefile.h
> @@ -324,6 +324,8 @@ int virStorageSourceGetActualType(virStorageSourcePtr def);
> void virStorageSourceFree(virStorageSourcePtr def);
> void virStorageSourceClearBackingStore(virStorageSourcePtr def);
> virStorageSourcePtr virStorageSourceNewFromBacking(virStorageSourcePtr parent);
> +virStorageSourcePtr virStorageSourceCopy(const virStorageSource *src,
> + bool backingChain);
ATTRIBUTE_NONNULL(1)
ACK
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 604 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140612/8e3e105b/attachment-0001.sig>
More information about the libvir-list
mailing list