提交 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;
virFileOpenTty;
virFileReadAll;
virFileReadLimFD;
virFileResolveAllLinks;
virFileResolveLink;
virFileSanitizePath;
virFileStripSuffix;
......
......@@ -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
......
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册