main: switch explicitly to tty1 on soft-reboot

Fixes: #39462
This commit is contained in:
Lennart Poettering
2025-10-29 13:09:20 +01:00
parent 2988bba60f
commit 6fa83be763
2 changed files with 31 additions and 1 deletions
+3 -1
View File
@@ -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;
}
+28
View File
@@ -3,6 +3,7 @@
#include <fcntl.h>
#include <getopt.h>
#include <linux/oom.h>
#include <linux/vt.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/prctl.h>
@@ -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,