X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=404fee7b2e5854230beab97d88e28e4299762bac;hb=75cb8502dfec0a6a5305fe766d4b6a1a04a43549;hp=f342cdd2895559c6a322d9cdc8e2f5a12f6a85dd;hpb=718db96199eb307751264e4163555662c9a389fa;p=elogind.git diff --git a/src/core/main.c b/src/core/main.c index f342cdd28..404fee7b2 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -32,6 +32,10 @@ #include #include +#ifdef HAVE_VALGRIND_VALGRIND_H +#include +#endif + #include "sd-daemon.h" #include "sd-messages.h" #include "sd-bus.h" @@ -86,7 +90,7 @@ static bool arg_dump_core = true; static bool arg_crash_shell = false; static int arg_crash_chvt = -1; static bool arg_confirm_spawn = false; -static bool arg_show_status = true; +static ShowStatus arg_show_status = SHOW_STATUS_UNSET; static bool arg_switched_root = false; static char ***arg_join_controllers = NULL; static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; @@ -108,7 +112,7 @@ static FILE* serialization = NULL; static void nop_handler(int sig) { } -_noreturn_ static void crash(int sig) { +noreturn static void crash(int sig) { if (getpid() != 1) /* Pass this on immediately, if this is not PID 1 */ @@ -127,7 +131,7 @@ _noreturn_ static void crash(int sig) { pid = fork(); if (pid < 0) - log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno)); + log_error("Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig)); else if (pid == 0) { struct rlimit rl = {}; @@ -162,7 +166,7 @@ _noreturn_ static void crash(int sig) { else if (status.si_code != CLD_DUMPED) log_error("Caught <%s>, core dump failed.", signal_to_string(sig)); else - log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid); + log_error("Caught <%s>, dumped core as pid "PID_FMT".", signal_to_string(sig), pid); } } @@ -193,7 +197,7 @@ _noreturn_ static void crash(int sig) { _exit(1); } - log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid); + log_info("Successfully spawned crash shell as pid "PID_FMT".", pid); } log_info("Freezing execution."); @@ -334,10 +338,9 @@ static int parse_proc_cmdline_word(const char *word) { } else if (startswith(word, "systemd.show_status=")) { int r; - if ((r = parse_boolean(word + 20)) < 0) + r = parse_show_status(word + 20, &arg_show_status); + if (r < 0) log_warning("Failed to parse show status switch %s. Ignoring.", word + 20); - else - arg_show_status = r; } else if (startswith(word, "systemd.default_standard_output=")) { int r; @@ -392,7 +395,7 @@ static int parse_proc_cmdline_word(const char *word) { "systemd.crash_shell=0|1 Run shell on crash\n" "systemd.crash_chvt=N Change to VT #N on crash\n" "systemd.confirm_spawn=0|1 Confirm every process spawn\n" - "systemd.show_status=0|1 Show status updates on the console during bootup\n" + "systemd.show_status=0|1|auto Show status updates on the console during bootup\n" "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n" " Log target\n" "systemd.log_level=LEVEL Log level\n" @@ -405,15 +408,16 @@ static int parse_proc_cmdline_word(const char *word) { "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n"); } - } else if (streq(word, "quiet")) - arg_show_status = false; - else if (streq(word, "debug")) { + } else if (streq(word, "quiet")) { + if (arg_show_status == SHOW_STATUS_UNSET) + arg_show_status = SHOW_STATUS_AUTO; + } else if (streq(word, "debug")) { /* Log to kmsg, the journal socket will fill up before the * journal is started and tools running during that time * will block with every log message for for 60 seconds, * before they give up. */ log_set_max_level(LOG_DEBUG); - log_set_target(LOG_TARGET_KMSG); + log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG); } else if (!in_initrd()) { unsigned i; @@ -431,6 +435,7 @@ static int parse_proc_cmdline_word(const char *word) { const char *filename, \ unsigned line, \ const char *section, \ + unsigned section_line, \ const char *lvalue, \ int ltype, \ const char *rvalue, \ @@ -457,11 +462,11 @@ DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target") DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" ) DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location") - static int config_parse_cpu_affinity2(const char *unit, const char *filename, unsigned line, const char *section, + unsigned section_line, const char *lvalue, int ltype, const char *rvalue, @@ -534,6 +539,7 @@ static int config_parse_join_controllers(const char *unit, const char *filename, unsigned line, const char *section, + unsigned section_line, const char *lvalue, int ltype, const char *rvalue, @@ -593,17 +599,12 @@ static int config_parse_join_controllers(const char *unit, for (a = arg_join_controllers; *a; a++) { if (strv_overlap(*a, l)) { - char **c; - - c = strv_merge(*a, l); - if (!c) { + if (strv_extend_strv(&l, *a) < 0) { strv_free(l); strv_free_free(t); return log_oom(); } - strv_free(l); - l = c; } else { char **c; @@ -637,7 +638,7 @@ static int parse_config_file(void) { { "Manager", "LogLocation", config_parse_location, 0, NULL }, { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core }, { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell }, - { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status }, + { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status }, { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt }, { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output }, @@ -896,12 +897,14 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_SHOW_STATUS: - r = optarg ? parse_boolean(optarg) : 1; - if (r < 0) { - log_error("Failed to parse show status boolean %s.", optarg); - return r; - } - arg_show_status = r; + if (optarg) { + r = parse_show_status(optarg, &arg_show_status); + if (r < 0) { + log_error("Failed to parse show status boolean %s.", optarg); + return r; + } + } else + arg_show_status = SHOW_STATUS_YES; break; case ARG_DESERIALIZE: { @@ -1321,6 +1324,7 @@ int main(int argc, char *argv[]) { /* Running inside a container, as PID 1 */ arg_running_as = SYSTEMD_SYSTEM; log_set_target(LOG_TARGET_CONSOLE); + log_close_console(); /* force reopen of /dev/console */ log_open(); /* For the later on, see above... */ @@ -1473,15 +1477,19 @@ int main(int argc, char *argv[]) { if (in_initrd()) log_info("Running in initial RAM disk."); - } else - log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")"); + } else { + _cleanup_free_ char *t = uid_to_name(getuid()); + log_debug(PACKAGE_STRING " running in user mode for user "PID_FMT"/%s. (" SYSTEMD_FEATURES ")", + getuid(), t); + } if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { - if (arg_show_status || plymouth_running()) + if (arg_show_status > 0 || plymouth_running()) status_welcome(); #ifdef HAVE_KMOD - kmod_setup(); + if (detect_container(NULL) <= 0) + kmod_setup(); #endif hostname_setup(); machine_id_setup(); @@ -1524,7 +1532,7 @@ int main(int argc, char *argv[]) { if (arg_running_as == SYSTEMD_SYSTEM) bump_rlimit_nofile(&saved_rlimit_nofile); - r = manager_new(arg_running_as, !!serialization, &m); + r = manager_new(arg_running_as, &m); if (r < 0) { log_error("Failed to allocate manager object: %s", strerror(-r)); goto finish; @@ -1551,6 +1559,8 @@ int main(int argc, char *argv[]) { if (arg_default_environment) manager_environment_add(m, NULL, arg_default_environment); + if (arg_show_status == SHOW_STATUS_UNSET) + arg_show_status = SHOW_STATUS_YES; manager_set_show_status(m, arg_show_status); /* Remember whether we should queue the default job */ @@ -1738,7 +1748,7 @@ finish: * initrd, but don't wait for them, so that we * can handle the SIGCHLD for them after * deserializing. */ - broadcast_signal(SIGTERM, false); + broadcast_signal(SIGTERM, false, true); /* And switch root */ r = switch_root(switch_root_dir); @@ -1830,16 +1840,26 @@ finish: if (fds) fdset_free(fds); +#ifdef HAVE_VALGRIND_VALGRIND_H + /* If we are PID 1 and running under valgrind, then let's exit + * here explicitly. valgrind will only generate nice output on + * exit(), not on exec(), hence let's do the former not the + * latter here. */ + if (getpid() == 1 && RUNNING_ON_VALGRIND) + return 0; +#endif + if (shutdown_verb) { const char * command_line[] = { SYSTEMD_SHUTDOWN_BINARY_PATH, shutdown_verb, NULL }; - char **env_block; + _cleanup_strv_free_ char **env_block = NULL; + env_block = strv_copy(environ); if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) { - char e[32]; + char *e; /* If we reboot let's set the shutdown * watchdog and tell the shutdown binary to @@ -1847,15 +1867,11 @@ finish: watchdog_set_timeout(&arg_shutdown_watchdog); watchdog_close(false); - /* Tell the binary how often to ping */ - snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog); - char_array_0(e); - - env_block = strv_append(environ, e); - } else { - env_block = strv_copy(environ); + /* Tell the binary how often to ping, ignore failure */ + if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0) + strv_push(&env_block, e); + } else watchdog_close(true); - } /* Avoid the creation of new processes forked by the * kernel; at this point, we will not listen to the @@ -1864,7 +1880,6 @@ finish: cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER); execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block); - free(env_block); log_error("Failed to execute shutdown binary, freezing: %m"); }