diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b81c2cc7da..0aef539dc8 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1780,6 +1780,7 @@ virStorageFileProbeGetMetadata; # storage_file/storage_source.h virStorageSourceAccess; virStorageSourceChainLookup; +virStorageSourceChainLookupBySource; virStorageSourceChown; virStorageSourceCreate; virStorageSourceDeinit; diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_source.c index ab0cdf2b12..0db6e69591 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -322,6 +322,46 @@ virStorageSourceChainLookup(virStorageSource *chain, } +/** + * virStorageSourceChainLookupBySource: + * @chain: chain top to look in + * @base: storage source to look for in @chain + * @parent: Filled with parent virStorageSource of the returned value if non-NULL. + * + * Looks up a storage source definition corresponding to @base in @chain. + * + * Returns virStorageSource withing chain or NULL if not found. + */ +virStorageSource * +virStorageSourceChainLookupBySource(virStorageSource *chain, + virStorageSource *base, + virStorageSource **parent) +{ + virStorageSource *prev = NULL; + + if (parent) + *parent = NULL; + + while (virStorageSourceIsBacking(chain)) { + if (virStorageSourceIsSameLocation(chain, base)) + break; + + prev = chain; + chain = chain->backingStore; + } + + if (!virStorageSourceIsBacking(chain)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("could not find base disk source in disk source chain")); + return NULL; + } + + if (parent) + *parent = prev; + return chain; +} + + static virStorageSource * virStorageSourceNewFromBackingRelative(virStorageSource *parent, const char *rel) diff --git a/src/storage_file/storage_source.h b/src/storage_file/storage_source.h index 0ae06f4e7d..63fefb6919 100644 --- a/src/storage_file/storage_source.h +++ b/src/storage_file/storage_source.h @@ -47,6 +47,12 @@ virStorageSourceChainLookup(virStorageSource *chain, virStorageSource **parent) ATTRIBUTE_NONNULL(1); +virStorageSource * +virStorageSourceChainLookupBySource(virStorageSource *chain, + virStorageSource *base, + virStorageSource **parent) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + int virStorageSourceUpdatePhysicalSize(virStorageSource *src, int fd,