From: Franck Bui Date: Mon, 8 Oct 2018 14:09:59 +0000 (+0200) Subject: core: introduce systemd.early_core_pattern= kernel cmdline option X-Git-Tag: v240~606 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c6885f5f36ec299d2ebd5d49d03b2cee37cf8e88;p=thirdparty%2Fsystemd.git core: introduce systemd.early_core_pattern= kernel cmdline option Until a core dump handler is installed by systemd-sysctl, the generation of core dump for services is turned OFF which can make the debugging of the early boot process harder especially since there's no easy way to restore the core dump generation. This patch introduces a new kernel command line option which specifies an absolute path where the kernel should write the core dump file when an early process crashes. This will take effect until systemd-coredump (or any other handlers) takes over. --- diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 0545f9d84b2..43b3a3667e6 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -55,6 +55,7 @@ systemd.unit= rd.systemd.unit= systemd.dump_core + systemd.early_core_pattern= systemd.crash_chvt systemd.crash_shell systemd.crash_reboot @@ -90,6 +91,16 @@ + + systemd.early_core_pattern= + + During early boot, the generation of core dump files is disabled until a core dump handler (if any) + takes over. This parameter allows to specifies an absolute path where core dump files should be stored until + a handler is installed. The path should be absolute and may contain specifiers, see + core5 for details. + + + systemd.restore_state= diff --git a/src/core/main.c b/src/core/main.c index 078decb432b..ce45f2ded23 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -109,6 +109,7 @@ static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL; static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; static usec_t arg_runtime_watchdog = 0; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; +static char *arg_early_core_pattern = NULL; static char *arg_watchdog_device = NULL; static char **arg_default_environment = NULL; static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {}; @@ -351,6 +352,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat else arg_dump_core = r; + } else if (proc_cmdline_key_streq(key, "systemd.early_core_pattern")) { + + if (proc_cmdline_value_missing(key, value)) + return 0; + + if (path_is_absolute(value)) + (void) parse_path_argument_and_warn(value, false, &arg_early_core_pattern); + else + log_warning("Specified core pattern '%s' is not an absolute path, ignoring.", value); + } else if (proc_cmdline_key_streq(key, "systemd.crash_chvt")) { if (!value) @@ -466,7 +477,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - parse_path_argument_and_warn(value, false, &arg_watchdog_device); + (void) parse_path_argument_and_warn(value, false, &arg_watchdog_device); } else if (streq(key, "quiet") && !value) { @@ -1482,13 +1493,29 @@ static void initialize_coredump(bool skip_setup) { if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0) log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m"); - /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored - * until the systemd-coredump tool is enabled via sysctl. */ + /* But at the same time, turn off the core_pattern logic by default, so that no + * coredumps are stored until the systemd-coredump tool is enabled via + * sysctl. However it can be changed via the kernel command line later so core + * dumps can still be generated during early startup and in initramfs. */ if (!skip_setup) disable_coredumps(); #endif } +static void initialize_core_pattern(bool skip_setup) { + int r; + + if (skip_setup || !arg_early_core_pattern) + return; + + if (getpid_cached() != 1) + return; + + r = write_string_file("/proc/sys/kernel/core_pattern", arg_early_core_pattern, 0); + if (r < 0) + log_warning_errno(r, "Failed to write '%s' to /proc/sys/kernel/core_pattern, ignoring: %m", arg_early_core_pattern); +} + static void do_reexecute( int argc, char *argv[], @@ -2345,6 +2372,9 @@ int main(int argc, char *argv[]) { if (arg_action == ACTION_RUN) { + /* A core pattern might have been specified via the cmdline. */ + initialize_core_pattern(skip_setup); + /* Close logging fds, in order not to confuse collecting passed fds and terminal logic below */ log_close();