From 29f5a5aef013133cfa0a60f842b434a397234d4b Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 13 Jul 2023 14:50:23 +0200 Subject: [PATCH 1/3] tree-wide: Set /dev/console size when we reset it If a size is configured for /dev/console via the kernel cmdline, let's make sure we take that into account when resetting /dev/console. --- src/basic/terminal-util.c | 59 +++++++++++++++++++++++++++++++++++++++ src/basic/terminal-util.h | 1 + src/core/execute.c | 43 ++-------------------------- src/core/main.c | 10 +++++++ 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 31fed16682b..49a61a4f1b4 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -589,10 +589,21 @@ int make_console_stdio(void) { return log_error_errno(r, "Failed to make /dev/null stdin/stdout/stderr: %m"); } else { + unsigned rows, cols; + r = reset_terminal_fd(fd, true); if (r < 0) log_warning_errno(r, "Failed to reset terminal, ignoring: %m"); + r = proc_cmdline_tty_size("/dev/console", &rows, &cols); + if (r < 0) + log_warning_errno(r, "Failed to get terminal size, ignoring: %m"); + else { + r = terminal_set_size_fd(fd, NULL, rows, cols); + if (r < 0) + log_warning_errno(r, "Failed to set terminal size, ignoring: %m"); + } + r = rearrange_stdio(fd, fd, fd); /* This invalidates 'fd' both on success and on failure. */ if (r < 0) return log_error_errno(r, "Failed to make terminal stdin/stdout/stderr: %m"); @@ -882,6 +893,54 @@ int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols return 0; } +int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols) { + _cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL; + unsigned rows = UINT_MAX, cols = UINT_MAX; + int r; + + assert(tty); + + if (!ret_rows && !ret_cols) + return 0; + + tty = skip_dev_prefix(tty); + if (!in_charset(tty, ALPHANUMERICAL)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s contains non-alphanumeric characters", tty); + + rowskey = strjoin("systemd.tty.rows.", tty); + if (!rowskey) + return -ENOMEM; + + colskey = strjoin("systemd.tty.columns.", tty); + if (!colskey) + return -ENOMEM; + + r = proc_cmdline_get_key_many(/* flags = */ 0, + rowskey, &rowsvalue, + colskey, &colsvalue); + if (r < 0) + return log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline: %m", tty); + + if (rowsvalue) { + r = safe_atou(rowsvalue, &rows); + if (r < 0) + return log_debug_errno(r, "Failed to parse %s=%s: %m", rowskey, rowsvalue); + } + + if (colsvalue) { + r = safe_atou(colsvalue, &cols); + if (r < 0) + return log_debug_errno(r, "Failed to parse %s=%s: %m", colskey, colsvalue); + } + + if (ret_rows) + *ret_rows = rows; + if (ret_cols) + *ret_cols = cols; + + return 0; +} + /* intended to be used as a SIGWINCH sighandler */ void columns_lines_cache_reset(int signum) { cached_columns = 0; diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index 0fa01dbdf88..7a9b0fde7c0 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -127,6 +127,7 @@ int terminal_vhangup_fd(int fd); int terminal_vhangup(const char *name); int terminal_set_size_fd(int fd, const char *ident, unsigned rows, unsigned cols); +int proc_cmdline_tty_size(const char *tty, unsigned *ret_rows, unsigned *ret_cols); int chvt(int vt); diff --git a/src/core/execute.c b/src/core/execute.c index abedd8f5098..c2958b4bd29 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -208,10 +208,8 @@ static const char *exec_context_tty_path(const ExecContext *context) { } static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols) { - _cleanup_free_ char *rowskey = NULL, *rowsvalue = NULL, *colskey = NULL, *colsvalue = NULL; unsigned rows, cols; const char *tty; - int r; assert(context); assert(ret_rows); @@ -221,45 +219,8 @@ static int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, cols = context->tty_cols; tty = exec_context_tty_path(context); - if (!tty || (rows != UINT_MAX && cols != UINT_MAX)) { - *ret_rows = rows; - *ret_cols = cols; - return 0; - } - - tty = skip_dev_prefix(tty); - if (!in_charset(tty, ALPHANUMERICAL)) { - log_debug("%s contains non-alphanumeric characters, ignoring", tty); - *ret_rows = rows; - *ret_cols = cols; - return 0; - } - - rowskey = strjoin("systemd.tty.rows.", tty); - if (!rowskey) - return -ENOMEM; - - colskey = strjoin("systemd.tty.columns.", tty); - if (!colskey) - return -ENOMEM; - - r = proc_cmdline_get_key_many(/* flags = */ 0, - rowskey, &rowsvalue, - colskey, &colsvalue); - if (r < 0) - log_debug_errno(r, "Failed to read TTY size of %s from kernel cmdline, ignoring: %m", tty); - - if (rows == UINT_MAX && rowsvalue) { - r = safe_atou(rowsvalue, &rows); - if (r < 0) - log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", rowskey, rowsvalue); - } - - if (cols == UINT_MAX && colsvalue) { - r = safe_atou(colsvalue, &cols); - if (r < 0) - log_debug_errno(r, "Failed to parse %s=%s, ignoring: %m", colskey, colsvalue); - } + if (tty) + (void) proc_cmdline_tty_size(tty, rows == UINT_MAX ? &rows : NULL, cols == UINT_MAX ? &cols : NULL); *ret_rows = rows; *ret_cols = cols; diff --git a/src/core/main.c b/src/core/main.c index f9fd9fae7c3..bbbf77a7792 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -220,6 +220,7 @@ static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) { static int console_setup(void) { _cleanup_close_ int tty_fd = -EBADF; + unsigned rows, cols; int r; tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); @@ -232,6 +233,15 @@ static int console_setup(void) { if (r < 0) return log_error_errno(r, "Failed to reset /dev/console: %m"); + r = proc_cmdline_tty_size("/dev/console", &rows, &cols); + if (r < 0) + log_warning_errno(r, "Failed to get terminal size, ignoring: %m"); + else { + r = terminal_set_size_fd(tty_fd, NULL, rows, cols); + if (r < 0) + log_warning_errno(r, "Failed to set terminal size, ignoring: %m"); + } + return 0; } From 102f36efd1ac20c63e60444b1d67b495e0cd95af Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 14 Jul 2023 09:12:54 +0200 Subject: [PATCH 2/3] terminal-util: Document boolean parameter in one more place --- src/basic/terminal-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 49a61a4f1b4..d1cfb161de3 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -591,7 +591,7 @@ int make_console_stdio(void) { } else { unsigned rows, cols; - r = reset_terminal_fd(fd, true); + r = reset_terminal_fd(fd, /* switch_to_text= */ true); if (r < 0) log_warning_errno(r, "Failed to reset terminal, ignoring: %m"); From 95b8bf9df2dfea1dc39a1cdbdbd831d9f7e0df8c Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 13 Jul 2023 15:38:03 +0200 Subject: [PATCH 3/3] mkosi: Set systemd.early_core_pattern=/core This makes sure we get pid1 coredumps during early boot. --- mkosi.conf.d/10-systemd.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkosi.conf.d/10-systemd.conf b/mkosi.conf.d/10-systemd.conf index 8fe77e8fbe1..46d89d18243 100644 --- a/mkosi.conf.d/10-systemd.conf +++ b/mkosi.conf.d/10-systemd.conf @@ -44,3 +44,4 @@ KernelCommandLineExtra=systemd.crash_shell apparmor=0 selinux=0 enforcing=0 + systemd.early_core_pattern=/core