chiark / gitweb /
SMACK: Add configuration options. (v3)
[elogind.git] / src / core / switch-root.c
index ed0a31e6978b3649429f57f83710ed7dc621d52e..150332a8587b841e8bd6a767fe6c8ce50393dbd3 100644 (file)
@@ -56,6 +56,15 @@ int switch_root(const char *new_root) {
                 goto fail;
         }
 
+        /* Work-around for a kernel bug: for some reason the kernel
+         * refuses switching root if any file systems are mounted
+         * MS_SHARED. Hence remount them MS_PRIVATE here as a
+         * work-around.
+         *
+         * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+        if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
+                log_warning("Failed to make \"/\" private mount: %m");
+
         NULSTR_FOREACH(i, move_mounts) {
                 char new_mount[PATH_MAX];
                 struct stat sb;
@@ -106,13 +115,21 @@ int switch_root(const char *new_root) {
                 goto fail;
         }
 
+        if (chdir("/") < 0) {
+                r = -errno;
+                log_error("Failed to change directory: %m");
+                goto fail;
+        }
+
         if (old_root_fd >= 0) {
                 struct stat rb;
 
                 if (fstat(old_root_fd, &rb) < 0)
                         log_warning("Failed to stat old root directory, leaving: %m");
-                else
+                else {
                         rm_rf_children(old_root_fd, false, false, &rb);
+                        old_root_fd = -1;
+                }
         }
 
         r = 0;