]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
simpler shared rootfs handling
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Sat, 1 Mar 2014 05:41:12 +0000 (23:41 -0600)
committerStéphane Graber <stgraber@ubuntu.com>
Mon, 3 Mar 2014 16:04:29 +0000 (11:04 -0500)
Only do the funky chroot_into_slave if / is in fact the rootfs.
Rootfs is a special blacklisted case for pivot_root.

If / is not rootfs but is shared, just mount / rslave.  We're
already in our own namespace.

This appears to solve the extra /proc/$$/mount entries in
containers and the host directories in lxc-attach which have
been plagueing at least fedora and arch.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/conf.c
src/lxc/utils.c
src/lxc/utils.h

index d99659a68735d1e9046b67a15dafddf7923bd092..26223710e6ec9eee851993973bceed6ceb13df1b 100644 (file)
@@ -1506,11 +1506,16 @@ static int setup_rootfs(struct lxc_conf *conf)
                return -1;
        }
 
-       if (detect_shared_rootfs()) {
+       if (detect_ramfs_rootfs()) {
                if (chroot_into_slave(conf)) {
                        ERROR("Failed to chroot into slave /");
                        return -1;
                }
+       } else if (detect_shared_rootfs()) {
+               if (mount("", "/", NULL, MS_SLAVE|MS_REC, 0)) {
+                       SYSERROR("Failed to make / rslave");
+                       return -1;
+               }
        }
 
        // First try mounting rootfs using a bdev
index 0190a476499ae565e4c9dd1b045f1fb3192b53de..ded8e8eec535467ffa8c1479bf7e0b2c3110c1ed 100644 (file)
@@ -1215,16 +1215,16 @@ int detect_shared_rootfs(void)
                return 0;
        while (fgets(buf, LINELEN, f)) {
                for (p = buf, i=0; p && i < 4; i++)
-                       p = index(p+1, ' ');
+                       p = strchr(p+1, ' ');
                if (!p)
                        continue;
-               p2 = index(p+1, ' ');
+               p2 = strchr(p+1, ' ');
                if (!p2)
                        continue;
                *p2 = '\0';
                if (strcmp(p+1, "/") == 0) {
                        // this is '/'.  is it shared?
-                       p = index(p2+1, ' ');
+                       p = strchr(p2+1, ' ');
                        if (p && strstr(p, "shared:")) {
                                fclose(f);
                                return 1;
@@ -1235,6 +1235,45 @@ int detect_shared_rootfs(void)
        return 0;
 }
 
+/*
+ * looking at fs/proc_namespace.c, it appears we can
+ * actually expect the rootfs entry to very specifically contain
+ * " - rootfs rootfs "
+ * IIUC, so long as we've chrooted so that rootfs is not our root,
+ * the rootfs entry should always be skipped in mountinfo contents.
+ */
+int detect_ramfs_rootfs(void)
+{
+       char buf[LINELEN], *p;
+       FILE *f;
+       int i;
+       char *p2;
+
+       f = fopen("/proc/self/mountinfo", "r");
+       if (!f)
+               return 0;
+       while (fgets(buf, LINELEN, f)) {
+               for (p = buf, i=0; p && i < 4; i++)
+                       p = strchr(p+1, ' ');
+               if (!p)
+                       continue;
+               p2 = strchr(p+1, ' ');
+               if (!p2)
+                       continue;
+               *p2 = '\0';
+               if (strcmp(p+1, "/") == 0) {
+                       // this is '/'.  is it the ramfs?
+                       p = strchr(p2+1, '-');
+                       if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) {
+                               fclose(f);
+                               return 1;
+                       }
+               }
+       }
+       fclose(f);
+       return 0;
+}
+
 bool on_path(char *cmd) {
        char *path = NULL;
        char *entry = NULL;
index 978f5860a4a2106ce84b4c5edf1c56f35ae9ce96..a318ec86857ef78511398c3f09e90f69edcb79e2 100644 (file)
@@ -278,4 +278,5 @@ uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval);
 #endif
 
 int detect_shared_rootfs(void);
+int detect_ramfs_rootfs(void);
 bool on_path(char *cmd);