X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fswitch-root.c;h=150332a8587b841e8bd6a767fe6c8ce50393dbd3;hb=2b43f939a4b3ad5aeb2650868b0234ff42ec0045;hp=ed0a31e6978b3649429f57f83710ed7dc621d52e;hpb=416693175bc317ef3fa4963af51a5ee077320d09;p=elogind.git diff --git a/src/core/switch-root.c b/src/core/switch-root.c index ed0a31e69..150332a85 100644 --- a/src/core/switch-root.c +++ b/src/core/switch-root.c @@ -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;