diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index df8e4b0eec05e959f442d99783ae5857006468f8..0dfd4c1f1cc2da0807af908049a9e3a5002472dd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1101,6 +1101,7 @@ virFileOpenAs; virFileOpenTty; virFileReadAll; virFileReadLimFD; +virFileResolveAllLinks; virFileResolveLink; virFileSanitizePath; virFileStripSuffix; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 1e7803abceb7e4b3c09daa1b8d230c2c884e7052..4e4388b101e1508313bcc4bc9dfb5de7bc52607a 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1111,11 +1111,34 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef) return 0; } + +static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef) +{ + char *newroot; + size_t i; + + for (i = 0 ; i < vmDef->nfss ; i++) { + virDomainFSDefPtr fs = vmDef->fss[i]; + if (virFileResolveAllLinks(fs->src, &newroot) < 0) + return -1; + + VIR_DEBUG("Resolved '%s' to %s", fs->src, newroot); + + VIR_FREE(fs->src); + fs->src = newroot; + } + + return 0; +} + static int lxcContainerSetupMounts(virDomainDefPtr vmDef, virDomainFSDefPtr root, char **ttyPaths, size_t nttyPaths) { + if (lxcContainerResolveSymlinks(vmDef) < 0) + return -1; + if (root) return lxcContainerSetupPivotRoot(vmDef, root, ttyPaths, nttyPaths); else diff --git a/src/util/util.c b/src/util/util.c index 6f46d530fb73600ea9a24e2c23f26e08349c0581..8663c4d664dafbf06416901238fdffe83b700881 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -536,16 +536,10 @@ int virFileLinkPointsTo(const char *checkLink, -/* - * Attempt to resolve a symbolic link, returning an - * absolute path where only the last component is guaranteed - * not to be a symlink. - * - * Return 0 if path was not a symbolic, or the link was - * resolved. Return -1 with errno set upon error - */ -int virFileResolveLink(const char *linkpath, - char **resultpath) +static int +virFileResolveLinkHelper(const char *linkpath, + bool intermediatePaths, + char **resultpath) { struct stat st; @@ -554,7 +548,7 @@ int virFileResolveLink(const char *linkpath, /* We don't need the full canonicalization of intermediate * directories, if linkpath is absolute and the basename is * already a non-symlink. */ - if (IS_ABSOLUTE_FILE_NAME(linkpath)) { + if (IS_ABSOLUTE_FILE_NAME(linkpath) && !intermediatePaths) { if (lstat(linkpath, &st) < 0) return -1; @@ -570,6 +564,33 @@ int virFileResolveLink(const char *linkpath, return *resultpath == NULL ? -1 : 0; } +/* + * Attempt to resolve a symbolic link, returning an + * absolute path where only the last component is guaranteed + * not to be a symlink. + * + * Return 0 if path was not a symbolic, or the link was + * resolved. Return -1 with errno set upon error + */ +int virFileResolveLink(const char *linkpath, + char **resultpath) +{ + return virFileResolveLinkHelper(linkpath, false, resultpath); +} + +/* + * Attempt to resolve a symbolic link, returning an + * absolute path where every component is guaranteed + * not to be a symlink. + * + * Return 0 if path was not a symbolic, or the link was + * resolved. Return -1 with errno set upon error + */ +int virFileResolveAllLinks(const char *linkpath, + char **resultpath) +{ + return virFileResolveLinkHelper(linkpath, true, resultpath); +} /* * Check whether the given file is a link. diff --git a/src/util/util.h b/src/util/util.h index c9c785b49bf52bd1211a9fd7607092fc1376466d..977ab6cc6470a67b245ae64774c660e251c07826 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -77,6 +77,8 @@ int virFileLinkPointsTo(const char *checkLink, int virFileResolveLink(const char *linkpath, char **resultpath) ATTRIBUTE_RETURN_CHECK; +int virFileResolveAllLinks(const char *linkpath, + char **resultpath) ATTRIBUTE_RETURN_CHECK; int virFileIsLink(const char *linkpath) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;