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);