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; }