提交 c53ba61b 编写于 作者: D Daniel P. Berrange

Fix startup of LXC containers with filesystems containing symlinks

Given an LXC guest with a root filesystem path of

  /export/lxc/roots/helloworld/root

During startup, we will pivot the root filesystem to end up
at

  /.oldroot/export/lxc/roots/helloworld/root

We then try to open

  /.oldroot/export/lxc/roots/helloworld/root/dev/pts

Now consider if '/export/lxc' is an absolute symlink pointing
to '/media/lxc'. The kernel will try to open

  /media/lxc/roots/helloworld/root/dev/pts

whereas it should be trying to open

  /.oldroot//media/lxc/roots/helloworld/root/dev/pts

To deal with the fact that the root filesystem can be moved,
we need to resolve symlinks in *any* part of the filesystem
source path.

* src/libvirt_private.syms, src/util/util.c,
  src/util/util.h: Add virFileResolveAllLinks to resolve
  all symlinks in a path
* src/lxc/lxc_container.c: Resolve all symlinks in filesystem
  paths during startup
上级 7aeb9794
...@@ -1101,6 +1101,7 @@ virFileOpenAs; ...@@ -1101,6 +1101,7 @@ virFileOpenAs;
virFileOpenTty; virFileOpenTty;
virFileReadAll; virFileReadAll;
virFileReadLimFD; virFileReadLimFD;
virFileResolveAllLinks;
virFileResolveLink; virFileResolveLink;
virFileSanitizePath; virFileSanitizePath;
virFileStripSuffix; virFileStripSuffix;
......
...@@ -1111,11 +1111,34 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef) ...@@ -1111,11 +1111,34 @@ static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef)
return 0; 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, static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
virDomainFSDefPtr root, virDomainFSDefPtr root,
char **ttyPaths, char **ttyPaths,
size_t nttyPaths) size_t nttyPaths)
{ {
if (lxcContainerResolveSymlinks(vmDef) < 0)
return -1;
if (root) if (root)
return lxcContainerSetupPivotRoot(vmDef, root, ttyPaths, nttyPaths); return lxcContainerSetupPivotRoot(vmDef, root, ttyPaths, nttyPaths);
else else
......
...@@ -536,16 +536,10 @@ int virFileLinkPointsTo(const char *checkLink, ...@@ -536,16 +536,10 @@ int virFileLinkPointsTo(const char *checkLink,
/* static int
* Attempt to resolve a symbolic link, returning an virFileResolveLinkHelper(const char *linkpath,
* absolute path where only the last component is guaranteed bool intermediatePaths,
* not to be a symlink. char **resultpath)
*
* 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)
{ {
struct stat st; struct stat st;
...@@ -554,7 +548,7 @@ int virFileResolveLink(const char *linkpath, ...@@ -554,7 +548,7 @@ int virFileResolveLink(const char *linkpath,
/* We don't need the full canonicalization of intermediate /* We don't need the full canonicalization of intermediate
* directories, if linkpath is absolute and the basename is * directories, if linkpath is absolute and the basename is
* already a non-symlink. */ * already a non-symlink. */
if (IS_ABSOLUTE_FILE_NAME(linkpath)) { if (IS_ABSOLUTE_FILE_NAME(linkpath) && !intermediatePaths) {
if (lstat(linkpath, &st) < 0) if (lstat(linkpath, &st) < 0)
return -1; return -1;
...@@ -570,6 +564,33 @@ int virFileResolveLink(const char *linkpath, ...@@ -570,6 +564,33 @@ int virFileResolveLink(const char *linkpath,
return *resultpath == NULL ? -1 : 0; 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. * Check whether the given file is a link.
......
...@@ -77,6 +77,8 @@ int virFileLinkPointsTo(const char *checkLink, ...@@ -77,6 +77,8 @@ int virFileLinkPointsTo(const char *checkLink,
int virFileResolveLink(const char *linkpath, int virFileResolveLink(const char *linkpath,
char **resultpath) ATTRIBUTE_RETURN_CHECK; char **resultpath) ATTRIBUTE_RETURN_CHECK;
int virFileResolveAllLinks(const char *linkpath,
char **resultpath) ATTRIBUTE_RETURN_CHECK;
int virFileIsLink(const char *linkpath) int virFileIsLink(const char *linkpath)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册