From d7d7581b034d5fe9841a13ea04034c43802ec773 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 15 May 2013 10:49:20 +0100 Subject: [PATCH] Fix LXC startup when /var/run is an absolute symlink 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 --- 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 461eb5f3d5..e7eec6ef20 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -749,14 +749,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; @@ -791,20 +794,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; @@ -1747,6 +1754,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; @@ -1759,6 +1767,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; @@ -1796,7 +1807,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 @@ -1805,7 +1816,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/ */ @@ -1831,6 +1842,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, ret = 0; cleanup: + VIR_FREE(stateDir); virCgroupFree(&cgroup); VIR_FREE(sec_mount_options); return ret; -- 2.39.5