]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: introduce systemd.early_core_pattern= kernel cmdline option
authorFranck Bui <fbui@suse.com>
Mon, 8 Oct 2018 14:09:59 +0000 (16:09 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 9 Oct 2018 08:26:23 +0000 (10:26 +0200)
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.

man/kernel-command-line.xml
src/core/main.c

index 0545f9d84b2ab43f0b4c8a99d476b191d5bb2b46..43b3a3667e6cbe7712d767a1ee259fa2e4937f64 100644 (file)
@@ -55,6 +55,7 @@
         <term><varname>systemd.unit=</varname></term>
         <term><varname>rd.systemd.unit=</varname></term>
         <term><varname>systemd.dump_core</varname></term>
+        <term><varname>systemd.early_core_pattern=</varname></term>
         <term><varname>systemd.crash_chvt</varname></term>
         <term><varname>systemd.crash_shell</varname></term>
         <term><varname>systemd.crash_reboot</varname></term>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>systemd.early_core_pattern=</varname></term>
+        <listitem>
+          <para>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
+          <citerefentry><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>systemd.restore_state=</varname></term>
         <listitem>
index 078decb432b37a9ed821a468bcf9606d17006a85..ce45f2ded234948c31564b90a7e23cf0dff62855 100644 (file)
@@ -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();