diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml index f36a6e1eae..ac8d984670 100644 --- a/man/coredump.conf.xml +++ b/man/coredump.conf.xml @@ -57,18 +57,22 @@ Storage= Controls where to store cores. One of none, - external, and journal. When - none, the core dumps may be logged (including the backtrace if - possible), but not stored permanently. When external (the - default), cores will be stored in /var/lib/systemd/coredump/. - When journal, cores will be stored in the journal and rotated - following normal journal rotation patterns. + external, and journal. When none, the core + dumps may be logged (including the backtrace if possible), but not stored permanently. When + external (the default), cores will be stored in + /var/lib/systemd/coredump/. When journal, cores will be + stored in the journal and rotated following normal journal rotation patterns. - When cores are stored in the journal, they might be - compressed following journal compression settings, see + When cores are stored in the journal, they might be compressed following journal compression + settings, see journald.conf5. - When cores are stored externally, they will be compressed - by default, see below. + When cores are stored externally, they will be compressed by default, see below. + + Note that in order to process a coredump (i.e. extract a stack trace) the core must be written + to disk first. Thus, unless ProcessSizeMax= is set to 0 (see below), the core will + be written to /var/lib/systemd/coredump/ either way (under a temporary filename, + or even in an unlinked file), Storage= thus only controls whether to leave it + there even after it was processed. @@ -84,7 +88,7 @@ ProcessSizeMax= The maximum size in bytes of a core which will be processed. Core dumps exceeding - this size may be stored, but the backtrace will not be generated. Like other sizes in this same + this size may be stored, but the stack trace will not be generated. Like other sizes in this same config file, the usual suffixes to the base of 1024 are allowed (B, K, M, G, T, P, and E). Defaults to 1G on 32-bit systems, 32G on 64-bit systems. diff --git a/src/basic/io-util.h b/src/basic/io-util.h index 3ad8267962..4f7989e66d 100644 --- a/src/basic/io-util.h +++ b/src/basic/io-util.h @@ -93,6 +93,9 @@ struct iovec_wrapper { struct iovec_wrapper *iovw_new(void); struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw); struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw); + +DEFINE_TRIVIAL_CLEANUP_FUNC(struct iovec_wrapper*, iovw_free_free); + void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors); int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len); diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 8ae4a9f63f..659eae3b3e 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -1205,6 +1205,9 @@ static int gather_pid_metadata_from_argv( int r, signo; char *t; + assert(iovw); + assert(context); + /* We gather all metadata that were passed via argv[] into an array of iovecs that * we'll forward to the socket unit */ @@ -1250,7 +1253,7 @@ static int gather_pid_metadata_from_argv( return save_context(context, iovw); } -static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { +static int gather_pid_metadata_from_procfs(struct iovec_wrapper *iovw, Context *context) { uid_t owner_uid; pid_t pid; char *t; @@ -1258,6 +1261,9 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { const char *p; int r; + assert(iovw); + assert(context); + /* Note that if we fail on oom later on, we do not roll-back changes to the iovec * structure. (It remains valid, with the first iovec fields initialized.) */ @@ -1363,8 +1369,8 @@ static int gather_pid_metadata(struct iovec_wrapper *iovw, Context *context) { } static int process_kernel(int argc, char* argv[]) { + _cleanup_(iovw_free_freep) struct iovec_wrapper *iovw = NULL; Context context = {}; - struct iovec_wrapper *iovw; int r; /* When we're invoked by the kernel, stdout/stderr are closed which is dangerous because the fds @@ -1386,12 +1392,12 @@ static int process_kernel(int argc, char* argv[]) { /* Collect all process metadata passed by the kernel through argv[] */ r = gather_pid_metadata_from_argv(iovw, &context, argc - 1, argv + 1); if (r < 0) - goto finish; + return r; /* Collect the rest of the process metadata retrieved from the runtime */ - r = gather_pid_metadata(iovw, &context); + r = gather_pid_metadata_from_procfs(iovw, &context); if (r < 0) - goto finish; + return r; if (!context.is_journald) /* OK, now we know it's not the journal, hence we can make use of it now. */ @@ -1409,13 +1415,9 @@ static int process_kernel(int argc, char* argv[]) { } if (context.is_journald || context.is_pid1) - r = submit_coredump(&context, iovw, STDIN_FILENO); - else - r = send_iovec(iovw, STDIN_FILENO); + return submit_coredump(&context, iovw, STDIN_FILENO); - finish: - iovw = iovw_free_free(iovw); - return r; + return send_iovec(iovw, STDIN_FILENO); } static int process_backtrace(int argc, char *argv[]) { @@ -1441,7 +1443,7 @@ static int process_backtrace(int argc, char *argv[]) { goto finish; /* Collect the rest of the process metadata retrieved from the runtime */ - r = gather_pid_metadata(iovw, &context); + r = gather_pid_metadata_from_procfs(iovw, &context); if (r < 0) goto finish; @@ -1466,16 +1468,13 @@ static int process_backtrace(int argc, char *argv[]) { r = iovw_put_string_field(iovw, "MESSAGE=", message); if (r < 0) - return r; + goto finish; } else { /* The imported iovecs are not supposed to be freed by us so let's store * them at the end of the array so we can skip them while freeing the * rest. */ - for (size_t i = 0; i < importer.iovw.count; i++) { - struct iovec *iovec = importer.iovw.iovec + i; - + FOREACH_ARRAY(iovec, importer.iovw.iovec, importer.iovw.count) iovw_put(iovw, iovec->iov_base, iovec->iov_len); - } } r = sd_journal_sendv(iovw->iovec, iovw->count);