chiark / gitweb /
nspawn,namespaces: make sure we recursively bind mount things in
[elogind.git] / src / nspawn / nspawn.c
index b9fa02dc7680a6486adefb6c6a05433b4c94d560..7d188f0712820f9c171bcce10b076590405a1ec3 100644 (file)
@@ -266,16 +266,16 @@ static int mount_all(const char *dest) {
 
         static const MountPoint mount_table[] = {
                 { "proc",      "/proc",     "proc",  NULL,       MS_NOSUID|MS_NOEXEC|MS_NODEV, true  },
-                { "/proc/sys", "/proc/sys", "bind",  NULL,       MS_BIND, true                       },   /* Bind mount first */
-                { "/proc/sys", "/proc/sys", "bind",  NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
-                { "/sys",      "/sys",      "bind",  NULL,       MS_BIND,                      true  },   /* Bind mount first */
-                { "/sys",      "/sys",      "bind",  NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
+                { "/proc/sys", "/proc/sys", NULL,    NULL,       MS_BIND, true                       },   /* Bind mount first */
+                { NULL,        "/proc/sys", NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
+                { "/sys",      "/sys",      NULL,    NULL,       MS_BIND,                      true  },   /* Bind mount first */
+                { NULL,        "/sys",      NULL,    NULL,       MS_BIND|MS_RDONLY|MS_REMOUNT, true  },   /* Then, make it r/o */
                 { "tmpfs",     "/dev",      "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME,     true  },
-                { "/dev/pts",  "/dev/pts",  "bind",  NULL,       MS_BIND,                      true  },
+                { "/dev/pts",  "/dev/pts",  NULL,    NULL,       MS_BIND,                      true  },
                 { "tmpfs",     "/run",      "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true  },
 #ifdef HAVE_SELINUX
-                { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND,                      false },  /* Bind mount first */
-                { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false },  /* Then, make it r/o */
+                { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND,                      false },  /* Bind mount first */
+                { NULL,              "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false },  /* Then, make it r/o */
 #endif
         };
 
@@ -1178,20 +1178,22 @@ int main(int argc, char *argv[]) {
                         goto child_fail;
                 }
 
-                /* Mark / as private, in case somebody marked it shared */
-                if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
-                        log_error("MS_PRIVATE|MS_REC failed: %m");
+                /* Mark everything as slave, so that we still
+                 * receive mounts from the real root, but don't
+                 * propagate mounts to the real root. */
+                if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
+                        log_error("MS_SLAVE|MS_REC failed: %m");
                         goto child_fail;
                 }
 
                 /* Turn directory into bind mount */
-                if (mount(arg_directory, arg_directory, "bind", MS_BIND, NULL) < 0) {
+                if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) {
                         log_error("Failed to make bind mount.");
                         goto child_fail;
                 }
 
                 if (arg_read_only)
-                        if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
+                        if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) {
                                 log_error("Failed to make read-only.");
                                 goto child_fail;
                         }
@@ -1224,8 +1226,8 @@ int main(int argc, char *argv[]) {
                         goto child_fail;
                 }
 
-                if (mount(arg_directory, "/", "bind", MS_MOVE, NULL) < 0) {
-                        log_error("mount(MS_BIND) failed: %m");
+                if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) {
+                        log_error("mount(MS_MOVE) failed: %m");
                         goto child_fail;
                 }