[libvirt] [PATCH 2/3] util: Introduce virFileComparePaths

John Ferlan jferlan at redhat.com
Thu Feb 9 23:02:11 UTC 2017



On 02/07/2017 09:16 AM, Erik Skultety wrote:
> So rather than comparing 2 paths (strings) as they are, which can very
> easily lead to unnecessary errors (e.g. in storage driver) that the paths
> are not the same when in fact they'd be e.g. just symlinks to the same
> location, we should put our best effort into resolving any symlinks and
> canonicalizing the path and only then compare the 2 paths.
> 
> Signed-off-by: Erik Skultety <eskultet at redhat.com>
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virfile.c       | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  src/util/virfile.h       |  2 ++
>  3 files changed, 48 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 8e994c7..06f3737 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1575,6 +1575,7 @@ virFileActivateDirOverride;
>  virFileBindMountDevice;
>  virFileBuildPath;
>  virFileClose;
> +virFileComparePaths;
>  virFileCopyACLs;
>  virFileDeleteTree;
>  virFileDirectFdFlag;
> diff --git a/src/util/virfile.c b/src/util/virfile.c
> index bf8099e..b261632 100644
> --- a/src/util/virfile.c
> +++ b/src/util/virfile.c
> @@ -3737,3 +3737,48 @@ virFileCopyACLs(const char *src,
>      virFileFreeACLs(&acl);
>      return ret;
>  }
> +
> +/*
> + * virFileComparePaths:
> + * @p1: source path 1
> + * @p2: source path 2
> + *
> + * Compares two paths for equality. To do so, it first canonicalizes both paths
> + * to resolve all symlinks and discard relative path components. If symlinks
> + * resolution or path canonicalization fails, plain string equality of @p1
> + * and @p2 is performed.
> + *
> + * Returns 0 if the paths are equal, 1 if they're not or -1 in case of an
> + * error.
> + */
> +int
> +virFileComparePaths(const char *p1, const char *p2)

I think this be "virFileCompareResolvedPaths" - change all the places...
 Better representation than just ComparePaths

> +{
> +    int ret = -1;
> +    char *res1, *res2;
> +
> +    res1 = res2 = NULL;
> +
> +    /* Assume p1 and p2 are symlinks, so try to resolve and canonicalize them.
> +     * Canonicalization fails for example on file systems names like 'proc' or
> +     * 'sysfs', since they're no real paths so fallback to plain string
> +     * comparison.
> +     */
> +    ignore_value(virFileResolveLink(p1, &res1));
> +    if (!res1 && VIR_STRDUP(res1, p1) < 0)
> +        goto cleanup;
> +
> +    ignore_value(virFileResolveLink(p2, &res2));
> +    if (!res2 && VIR_STRDUP(res2, p2) < 0)
> +        goto cleanup;
> +
> +    if (STREQ_NULLABLE(res1, res2))
> +        ret = 0;
> +    else
> +        ret = 1;

WHy not return 1 on match, 0 on non match, and -1 on failure that way
all you have to do is "ret = STREQ_NULLABLE(res1, res2);"... If so
adjust the returns comments above too.


ACK w/ adjustments.

> +
> + cleanup:
> +    VIR_FREE(res1);
> +    VIR_FREE(res2);
> +    return ret;
> +}
> diff --git a/src/util/virfile.h b/src/util/virfile.h
> index 0343acd..5822b29 100644
> --- a/src/util/virfile.h
> +++ b/src/util/virfile.h
> @@ -331,4 +331,6 @@ void virFileFreeACLs(void **acl);
>  
>  int virFileCopyACLs(const char *src,
>                      const char *dst);
> +
> +int virFileComparePaths(const char *p1, const char *p2);
>  #endif /* __VIR_FILE_H */
> 




More information about the libvir-list mailing list