From: Serge Hallyn Date: Sat, 1 Mar 2014 05:41:12 +0000 (-0600) Subject: simpler shared rootfs handling X-Git-Tag: lxc-1.1.0.alpha1~251 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7f954bbddc50844e5ea3f7e72170173f5cecfb7;p=thirdparty%2Flxc.git simpler shared rootfs handling 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 Acked-by: Stéphane Graber --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index d99659a68..26223710e 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 0190a4764..ded8e8eec 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 978f5860a..a318ec868 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);