From 91f349d8fd517577cd6c94faf0f92178145901c3 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 10 Apr 2014 17:36:06 -0600 Subject: [PATCH] util: new virFileRelLinkPointsTo function When checking if two filenames point to the same inode (whether by hardlink or symlink), sometimes one of the names might be relative. This convenience function makes it easier to check. * src/util/virfile.h (virFileRelLinkPointsTo): New prototype. * src/util/virfile.c (virFileRelLinkPointsTo): New function. * src/libvirt_private.syms (virfile.h): Export it. * src/xen/xm_internal.c (xenXMDomainGetAutostart): Use it. Signed-off-by: Eric Blake --- src/libvirt_private.syms | 1 + src/util/virfile.c | 32 +++++++++++++++++++++++++++++++- src/util/virfile.h | 7 ++++++- src/xen/xm_internal.c | 11 +++++------ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6e807c4919..0e81f2f952 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1255,6 +1255,7 @@ virFilePrintf; virFileReadAll; virFileReadHeaderFD; virFileReadLimFD; +virFileRelLinkPointsTo; virFileResolveAllLinks; virFileResolveLink; virFileRewrite; diff --git a/src/util/virfile.c b/src/util/virfile.c index a28cbf1441..3eb2703c0d 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1368,7 +1368,8 @@ virFileHasSuffix(const char *str, && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) /* Return nonzero if checkLink and checkDest - refer to the same file. Otherwise, return 0. */ + * refer to the same file. Otherwise, return 0. + */ int virFileLinkPointsTo(const char *checkLink, const char *checkDest) @@ -1382,6 +1383,35 @@ virFileLinkPointsTo(const char *checkLink, } +/* Return positive if checkLink (residing within directory if not + * absolute) and checkDest refer to the same file. Otherwise, return + * -1 on allocation failure (error reported), or 0 if not the same + * (silent). + */ +int +virFileRelLinkPointsTo(const char *directory, + const char *checkLink, + const char *checkDest) +{ + char *candidate; + int ret; + + if (*checkLink == '/') + return virFileLinkPointsTo(checkLink, checkDest); + if (!directory) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot resolve '%s' without starting directory"), + checkLink); + return -1; + } + if (virAsprintf(&candidate, "%s/%s", directory, checkLink) < 0) + return -1; + ret = virFileLinkPointsTo(candidate, checkDest); + VIR_FREE(candidate); + return ret; +} + + static int virFileResolveLinkHelper(const char *linkpath, bool intermediatePaths, diff --git a/src/util/virfile.h b/src/util/virfile.h index 638378a2af..46ef781479 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -143,7 +143,12 @@ int virFileStripSuffix(char *str, const char *suffix) ATTRIBUTE_RETURN_CHECK; int virFileLinkPointsTo(const char *checkLink, - const char *checkDest); + const char *checkDest) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int virFileRelLinkPointsTo(const char *directory, + const char *checkLink, + const char *checkDest) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); int virFileResolveLink(const char *linkpath, char **resultpath) ATTRIBUTE_RETURN_CHECK; diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 52d2a1e039..f25a7df6de 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1427,25 +1427,24 @@ int xenXMDomainGetAutostart(virDomainDefPtr def, int *autostart) { - char *linkname = xenXMAutostartLinkName(def); char *config = xenXMDomainConfigName(def); int ret = -1; - if (!linkname || !config) + if (!config) goto cleanup; - *autostart = virFileLinkPointsTo(linkname, config); + *autostart = virFileRelLinkPointsTo("/etc/xen/auto/", def->name, config); if (*autostart < 0) { virReportSystemError(errno, - _("cannot check link %s points to config %s"), - linkname, config); + _("cannot check link /etc/xen/auto/%s points " + "to config %s"), + def->name, config); goto cleanup; } ret = 0; cleanup: - VIR_FREE(linkname); VIR_FREE(config); return ret; } -- GitLab