core: set RLIMIT_CORE to unlimited by default
authorLennart Poettering <lennart@poettering.net>
Mon, 8 Feb 2016 21:30:58 +0000 (22:30 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 10 Feb 2016 15:09:20 +0000 (16:09 +0100)
The kernel sets RLIMIT_CORE to 0 by default. Let's bump this to unlimited by
default (for systemd itself and all processes we fork off), so that the
coredump hooks have an effect if they honour it.

Bumping RLIMIT_CORE of course would have the effect that "core" files will end
up on the system at various places, if no coredump hook is used. To avoid this,
make sure PID1 sets the core pattern to the empty string by default, so that
this logic is disabled.

This change in defaults should be useful for all systems where coredump hooks
are used, as it allows useful usage of RLIMIT_CORE from these hooks again. OTOH
systems that expect that coredumps are placed under the name "core" in the
current directory will break with this change. Given how questionnable this
behaviour is, and given that no common distro makes use of this by default it
shouldn't be too much of a loss. Also, the old behaviour may be restored by
explicitly configuring a "core_pattern" of "core", and setting the default
system RLIMIT_CORE to 0 again via system.conf.

src/core/main.c

index 0e6832c..e208857 100644 (file)
@@ -172,19 +172,15 @@ noreturn static void crash(int sig) {
                 if (pid < 0)
                         log_emergency_errno(errno, "Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
                 else if (pid == 0) {
-                        struct rlimit rl = {
-                                .rlim_cur = RLIM_INFINITY,
-                                .rlim_max = RLIM_INFINITY,
-                        };
-
                         /* Enable default signal handler for core dump */
+
                         sa = (struct sigaction) {
                                 .sa_handler = SIG_DFL,
                         };
                         (void) sigaction(sig, &sa, NULL);
 
-                        /* Don't limit the core dump size */
-                        (void) setrlimit(RLIMIT_CORE, &rl);
+                        /* Don't limit the coredump size */
+                        (void) setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY));
 
                         /* Just to be sure... */
                         (void) chdir("/");
@@ -1466,6 +1462,17 @@ int main(int argc, char *argv[]) {
                 kernel_timestamp = DUAL_TIMESTAMP_NULL;
         }
 
+        if (getpid() == 1) {
+                /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
+                 * will process core dumps for system services by default. */
+                (void) setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY));
+
+                /* 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. */
+                if (!skip_setup)
+                        (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+        }
+
         /* Initialize default unit */
         r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET);
         if (r < 0) {