diff --git a/src/core/main.c b/src/core/main.c index 6a2dbc2f54..6f6b565d68 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -164,16 +164,11 @@ _noreturn_ static void crash(int sig) { sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART; assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); - if ((pid = fork()) < 0) + pid = fork(); + if (pid < 0) log_error("Failed to fork off crash shell: %s", strerror(errno)); else if (pid == 0) { - int fd, r; - - if ((fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1)) < 0) - log_error("Failed to acquire terminal: %s", strerror(-fd)); - else if ((r = make_stdio(fd)) < 0) - log_error("Failed to duplicate terminal fd: %s", strerror(-r)); - + make_console_stdio(); execl("/bin/sh", "/bin/sh", NULL); log_error("execl() failed: %s", strerror(errno)); @@ -1677,6 +1672,9 @@ finish: * rebooted while we do that */ watchdog_close(true); + /* Reopen the console */ + make_console_stdio(); + if (switch_root_dir) { r = switch_root(switch_root_dir); if (r < 0) diff --git a/src/core/shutdown.c b/src/core/shutdown.c index baef66dd9d..194a1ccf21 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -267,9 +267,10 @@ static int prepare_new_root(void) { } static int pivot_to_new_root(void) { - int fd; - - chdir("/run/initramfs"); + if (chdir("/run/initramfs") < 0) { + log_error("Failed to change directory to /run/initramfs: %m"); + return -errno; + } /* In case some evil process made "/" MS_SHARED @@ -288,19 +289,12 @@ static int pivot_to_new_root(void) { } chroot("."); + + setsid(); + make_console_stdio(); + log_info("Successfully changed into root pivot."); - fd = open("/dev/console", O_RDWR); - if (fd < 0) - log_error("Failed to open /dev/console: %m"); - else { - make_stdio(fd); - - /* Initialize the controlling terminal */ - setsid(); - ioctl(STDIN_FILENO, TIOCSCTTY, NULL); - } - return 0; } diff --git a/src/shared/util.c b/src/shared/util.c index 62121b5923..63471899fd 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2940,7 +2940,8 @@ int make_stdio(int fd) { int make_null_stdio(void) { int null_fd; - if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0) + null_fd = open("/dev/null", O_RDWR|O_NOCTTY); + if (null_fd < 0) return -errno; return make_stdio(null_fd); @@ -5844,3 +5845,23 @@ void warn_melody(void) { ioctl(fd, KIOCSOUND, 0); close_nointr_nofail(fd); } + +int make_console_stdio(void) { + int fd, r; + + /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ + + fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1); + if (fd < 0) { + log_error("Failed to acquire terminal: %s", strerror(-fd)); + return fd; + } + + r = make_stdio(fd); + if (r < 0) { + log_error("Failed to duplicate terminal fd: %s", strerror(-r)); + return r; + } + + return 0; +} diff --git a/src/shared/util.h b/src/shared/util.h index 89e9a00afc..c8d048f9b2 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -278,6 +278,7 @@ char *format_timespan(char *buf, size_t l, usec_t t); int make_stdio(int fd); int make_null_stdio(void); +int make_console_stdio(void); unsigned long long random_ull(void);