[libvirt] [PATCH 4/4] Fix LXC startup when /var/run is an absolute symlink

Daniel P. Berrange berrange at redhat.com
Wed May 15 09:53:16 UTC 2013


From: "Daniel P. Berrange" <berrange at 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 at 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




More information about the libvir-list mailing list