From affd7ed1a923b0df8479cff1bd9eafb625fdaa66 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 13 Jun 2016 16:10:06 +0200 Subject: pid1: reconnect to the console before being re-executed When re-executed, reconnect the console to PID1's stdios as it was the case when PID1 was initially started by the kernel. --- src/core/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 93098daa9b..cef7575937 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1967,6 +1967,9 @@ finish: log_error_errno(r, "Failed to switch root, trying to continue: %m"); } + /* Reopen the console */ + (void) make_console_stdio(); + args_size = MAX(6, argc+1); args = newa(const char*, args_size); @@ -2018,9 +2021,6 @@ finish: arg_serialization = safe_fclose(arg_serialization); fds = fdset_free(fds); - /* Reopen the console */ - (void) make_console_stdio(); - for (j = 1, i = 1; j < (unsigned) argc; j++) args[i++] = argv[j]; args[i++] = NULL; -- cgit v1.2.3-54-g00ecf From 8ce0611e42c2b0d11007e2172edaa86ce4e4125d Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 20 Jun 2016 18:54:21 +0200 Subject: Revert "do not pass-along the environment from the kernel or initrd" This reverts commit ce8aba568156f2b9d0d3b023e960cda3d9d7db81. We should pass an environment as close as possible to what we originally got. --- src/core/main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index cef7575937..40d7ff9be5 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1995,10 +1995,6 @@ finish: args[i++] = sfd; args[i++] = NULL; - /* do not pass along the environment we inherit from the kernel or initrd */ - if (switch_root_dir) - (void) clearenv(); - assert(i <= args_size); /* -- cgit v1.2.3-54-g00ecf From 32391275c02715f76232128c49b19bb619cd9463 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 20 Jun 2016 18:54:21 +0200 Subject: pid1: initialize TERM environment variable correctly When systemd is started by the kernel, the kernel set the TERM environment variable unconditionnally to "linux" no matter the console device used. This might be an issue for dumb devices with no colors support. This patch uses default_term_for_tty() for getting a more accurate value. But it makes sure to keep the user preferences (if any) which might be passed via the kernel command line. For that purpose /proc should be mounted. --- src/core/main.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/core/main.c b/src/core/main.c index 40d7ff9be5..0a09ff514a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1294,6 +1294,35 @@ static int bump_unix_max_dgram_qlen(void) { return 1; } +static int fixup_environment(void) { + _cleanup_free_ char *term = NULL; + int r; + + /* When started as PID1, the kernel uses /dev/console + * for our stdios and uses TERM=linux whatever the + * backend device used by the console. We try to make + * a better guess here since some consoles might not + * have support for color mode for example. + * + * However if TERM was configured through the kernel + * command line then leave it alone. */ + + r = get_proc_cmdline_key("TERM=", &term); + if (r < 0) + return r; + + if (r == 0) { + term = strdup(default_term_for_tty("/dev/console") + 5); + if (!term) + return -errno; + } + + if (setenv("TERM", term, 1) < 0) + return -errno; + + return 0; +} + int main(int argc, char *argv[]) { Manager *m = NULL; int r, retval = EXIT_FAILURE; @@ -1480,6 +1509,14 @@ int main(int argc, char *argv[]) { (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0); } + /* We expect the environment to be set correctly if run inside a + * container. */ + if (arg_system && detect_container() <= 0) + if (fixup_environment() < 0) { + error_message = "Failed to fix up PID1 environment"; + goto finish; + } + /* Initialize default unit */ r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET); if (r < 0) { -- cgit v1.2.3-54-g00ecf From 3a18b60489504056f9b0b1a139439cbfa60a87e1 Mon Sep 17 00:00:00 2001 From: Franck Bui Date: Mon, 20 Jun 2016 21:45:28 +0200 Subject: pid1: initialize status color mode after setting up TERM Also we had to connect PID's stdio to null later since colors_enabled() assume that stdout is connected to the console. --- src/core/main.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index 0a09ff514a..6124a984c3 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1382,7 +1382,6 @@ int main(int argc, char *argv[]) { saved_argv = argv; saved_argc = argc; - log_show_color(colors_enabled()); log_set_upgrade_syslog_to_journal(true); /* Disable the umask logic */ @@ -1393,7 +1392,6 @@ int main(int argc, char *argv[]) { /* Running outside of a container as PID 1 */ arg_system = true; - make_null_stdio(); log_set_target(LOG_TARGET_KMSG); log_open(); @@ -1511,12 +1509,19 @@ int main(int argc, char *argv[]) { /* We expect the environment to be set correctly if run inside a * container. */ - if (arg_system && detect_container() <= 0) + if (arg_system && detect_container() <= 0) { if (fixup_environment() < 0) { error_message = "Failed to fix up PID1 environment"; goto finish; } + /* Try to figure out if we can use colors with the console. No + * need to do that for user instances since they never log + * into the console. */ + log_show_color(colors_enabled()); + make_null_stdio(); + } + /* Initialize default unit */ r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET); if (r < 0) { -- cgit v1.2.3-54-g00ecf