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