From: Lennart Poettering Date: Mon, 27 Oct 2025 17:26:37 +0000 (+0100) Subject: main: switch explicitly to tty1 on soft-reboot X-Git-Tag: v259-rc1~230 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6fa83be763f588038c3054cabdf0d3b5b42bc929;p=thirdparty%2Fsystemd.git main: switch explicitly to tty1 on soft-reboot Fixes: #39462 --- diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index aca549bbc4c..48cce67833f 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -166,6 +166,8 @@ static inline bool osc_char_is_valid(char c) { return (unsigned char) c >= 32 && (unsigned char) c < 127; } +#define VTNR_MAX 63 + static inline bool vtnr_is_valid(unsigned n) { - return n >= 1 && n <= 63; + return n >= 1 && n <= VTNR_MAX; } diff --git a/src/core/main.c b/src/core/main.c index 822d2eedcd3..f1c424684f7 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -1931,6 +1932,32 @@ static void finish_remaining_processes(ManagerObjective objective) { broadcast_signal(SIGKILL, /* wait_for_exit= */ false, /* send_sighup= */ false, arg_defaults.timeout_stop_usec); } +static void reduce_vt(ManagerObjective objective) { + int r; + + if (objective != MANAGER_SOFT_REBOOT) + return; + + /* Switches back to VT 1, and releases all other VTs, in an attempt to return to a situation similar + * to how it was during the original kernel initialization. This is important because if some random + * TTY is in foreground, /dev/console will end up pointing to it, where the future init system will + * then write its status output to, but where it probably shouldn't be writing to. */ + + r = chvt(1); + if (r < 0) + log_debug_errno(r, "Failed to switch to VT TTY 1, ignoring: %m"); + + _cleanup_close_ int tty0_fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); + if (tty0_fd < 0) + return (void) log_debug_errno(tty0_fd, "Failed to open '/dev/tty0', ignoring: %m"); + + for (int ttynr = 2; ttynr <= VTNR_MAX; ttynr++) + if (ioctl(tty0_fd, VT_DISALLOCATE, ttynr) < 0) + log_debug_errno(errno, "Failed to disallocate VT TTY %i, ignoring: %m", ttynr); + else + log_debug("Successfully disallocated VT TTY %i.", ttynr); +} + static int do_reexecute( ManagerObjective objective, int argc, @@ -1998,6 +2025,7 @@ static int do_reexecute( (void) setrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock); finish_remaining_processes(objective); + reduce_vt(objective); if (switch_root_dir) { r = switch_root(/* new_root= */ switch_root_dir,