[libvirt] [PATCHv3 11/19] storage: make it easier to find file within chain

Laine Stump laine at laine.org
Thu Oct 18 18:36:36 UTC 2012


On 10/17/2012 06:30 PM, Eric Blake wrote:
> In order to temporarily label files read/write during a commit
> operation, we need to crawl the backing chain and find the absolute
> file name that needs labeling in the first place, as well as the
> name of the file that owns the backing file.
>
> * src/util/storage_file.c (virStorageFileChainLookup): New
> function.
> * src/util/storage_file.h: Declare it.
> * src/libvirt_private.syms (storage_file.h): Export it.
> ---
>
> v3: fix -Wshadow failure, improve comments
>
>  src/libvirt_private.syms |  1 +
>  src/util/storage_file.c  | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
>  src/util/storage_file.h  |  7 ++++++
>  3 files changed, 72 insertions(+)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 6155738..ccee23d 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1130,6 +1130,7 @@ virStorageGenerateQcowPassphrase;
>
>
>  # storage_file.h
> +virStorageFileChainLookup;
>  virStorageFileFormatTypeFromString;
>  virStorageFileFormatTypeToString;
>  virStorageFileFreeMetadata;
> diff --git a/src/util/storage_file.c b/src/util/storage_file.c
> index 2ff444c..882df6e 100644
> --- a/src/util/storage_file.c
> +++ b/src/util/storage_file.c
> @@ -1262,3 +1262,67 @@ const char *virStorageFileGetSCSIKey(const char *path)
>      return NULL;
>  }
>  #endif
> +
> +/* Given a CHAIN that starts at the named file START, return a string
> + * pointing to either START or within CHAIN that gives the preferred
> + * name for the backing file NAME within that chain.  Pass NULL for
> + * NAME to find the base of the chain.  If META is not NULL, set *META
> + * to the point in the chain that describes NAME (or to NULL if the
> + * backing element is not a file).  If PARENT is not NULL, set *PARENT
> + * to the preferred name of the parent (or to NULL if NAME matches
> + * START).  Since the results point within CHAIN, they must not be
> + * independently freed.  */
> +const char *
> +virStorageFileChainLookup(virStorageFileMetadataPtr chain, const char *start,
> +                          const char *name, virStorageFileMetadataPtr *meta,
> +                          const char **parent)
> +{
> +    virStorageFileMetadataPtr owner;
> +    const char *tmp;
> +
> +    if (!parent)
> +        parent = &tmp;
> +
> +    *parent = NULL;
> +    if (name ? STREQ(start, name) || virFileLinkPointsTo(start, name) :
> +        !chain->backingStore) {
> +        if (meta)
> +            *meta = chain;
> +        return start;
> +    }
> +
> +    owner = chain;
> +    *parent = start;
> +    while (owner) {
> +        if (!owner->backingStore)
> +            goto error;
> +        if (!name) {
> +            if (!owner->backingMeta ||
> +                !owner->backingMeta->backingStore)
> +                break;
> +        } else if (STREQ_NULLABLE(name, owner->backingStoreRaw) ||
> +                   STREQ(name, owner->backingStore)) {
> +            break;
> +        } else if (owner->backingStoreIsFile) {
> +            char *absName = absolutePathFromBaseFile(*parent, name);
> +            if (absName && STREQ(absName, owner->backingStore)) {
> +                VIR_FREE(absName);
> +                break;
> +            }
> +            VIR_FREE(absName);
> +        }
> +        *parent = owner->backingStore;
> +        owner = owner->backingMeta;
> +    }
> +    if (!owner)
> +        goto error;
> +    if (meta)
> +        *meta = owner->backingMeta;
> +    return owner->backingStore;
> +
> +error:
> +    *parent = NULL;
> +    if (meta)
> +        *meta = NULL;
> +    return NULL;
> +}
> diff --git a/src/util/storage_file.h b/src/util/storage_file.h
> index 685fcb8..9b00dba 100644
> --- a/src/util/storage_file.h
> +++ b/src/util/storage_file.h
> @@ -78,6 +78,13 @@ virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
>                                                            int fd,
>                                                            int format);
>
> +const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
> +                                      const char *start,
> +                                      const char *name,
> +                                      virStorageFileMetadataPtr *meta,
> +                                      const char **parent)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +
>  void virStorageFileFreeMetadata(virStorageFileMetadataPtr meta);
>
>  int virStorageFileResize(const char *path, unsigned long long capacity);

Previous ACK stands.




More information about the libvir-list mailing list