From: "Daniel P. Berrange" <berrange(a)redhat.com>
During startup, the LXC driver uses paths such as
/.oldroot/var/run/libvirt/lxc/...
to access directories from the previous root filesystem
after doing a pivot_root(). Unfortunately if /var/run
is an absolute symlink to /run, instead of a relative
symlink to ../run, these paths break.
At least one Linux distro is known to use an absolute
symlink for /var/run, so workaround this, by resolving
all symlinks before doing the pivot_root().
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_container.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 8bad314..1a80376 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -745,14 +745,17 @@ cleanup:
}
#if WITH_FUSE
-static int lxcContainerMountProcFuse(virDomainDefPtr def)
+static int lxcContainerMountProcFuse(virDomainDefPtr def,
+ const char *stateDir)
{
int ret;
char *meminfo_path = NULL;
+ VIR_DEBUG("Mount /proc/meminfo stateDir=%s", stateDir);
+
if ((ret = virAsprintf(&meminfo_path,
"/.oldroot/%s/%s.fuse/meminfo",
- LXC_STATE_DIR,
+ stateDir,
def->name)) < 0)
return ret;
@@ -767,20 +770,24 @@ static int lxcContainerMountProcFuse(virDomainDefPtr def)
return ret;
}
#else
-static int lxcContainerMountProcFuse(virDomainDefPtr def ATTRIBUTE_UNUSED)
+static int lxcContainerMountProcFuse(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ const char *stateDir ATTRIBUTE_UNUSED)
{
return 0;
}
#endif
-static int lxcContainerMountFSDevPTS(virDomainDefPtr def)
+static int lxcContainerMountFSDevPTS(virDomainDefPtr def,
+ const char *stateDir)
{
int ret;
char *path = NULL;
+ VIR_DEBUG("Mount /dev/pts stateDir=%s", stateDir);
+
if ((ret = virAsprintf(&path,
"/.oldroot/%s/%s.devpts",
- LXC_STATE_DIR,
+ stateDir,
def->name)) < 0)
return ret;
@@ -1723,6 +1730,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
int rc;
int ret = -1;
char *sec_mount_options;
+ char *stateDir = NULL;
if (!(sec_mount_options = virSecurityManagerGetMountOptions(securityDriver, vmDef)))
return -1;
@@ -1735,6 +1743,9 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
goto cleanup;
}
+ if (virFileResolveAllLinks(LXC_STATE_DIR, &stateDir) < 0)
+ goto cleanup;
+
/* Ensure the root filesystem is mounted */
if (lxcContainerPrepareRoot(vmDef, root) < 0)
goto cleanup;
@@ -1772,7 +1783,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
goto cleanup;
/* Mounts /proc/meminfo etc sysinfo */
- if (lxcContainerMountProcFuse(vmDef) < 0)
+ if (lxcContainerMountProcFuse(vmDef, stateDir) < 0)
goto cleanup;
/* Now we can re-mount the cgroups controllers in the
@@ -1781,7 +1792,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
goto cleanup;
/* Mounts /dev/pts */
- if (lxcContainerMountFSDevPTS(vmDef) < 0)
+ if (lxcContainerMountFSDevPTS(vmDef, stateDir) < 0)
goto cleanup;
/* Populates device nodes in /dev/ */
@@ -1807,6 +1818,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
ret = 0;
cleanup:
+ VIR_FREE(stateDir);
virCgroupFree(&cgroup);
VIR_FREE(sec_mount_options);
return ret;
--
1.8.2.1