[lxc-devel] [PATCH] simpler shared rootfs handling

Serge Hallyn serge.hallyn at ubuntu.com
Sat Mar 1 05:41:12 UTC 2014


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 at ubuntu.com>
---
 src/lxc/conf.c  |  7 ++++++-
 src/lxc/utils.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 src/lxc/utils.h |  1 +
 3 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index d99659a..2622371 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -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
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 0190a47..ded8e8e 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -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;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 978f586..a318ec8 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -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);
-- 
1.9.0



More information about the lxc-devel mailing list