Merge pull request #28760 from poettering/coredump-tweaks

coredump: minor tweaks/modernizations
This commit is contained in:
Yu Watanabe 2023-08-11 04:16:31 +09:00 committed by GitHub
commit 09256904ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 28 deletions

View file

@ -57,18 +57,22 @@
<term><varname>Storage=</varname></term>
<listitem><para>Controls where to store cores. One of <literal>none</literal>,
<literal>external</literal>, and <literal>journal</literal>. When
<literal>none</literal>, the core dumps may be logged (including the backtrace if
possible), but not stored permanently. When <literal>external</literal> (the
default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
When <literal>journal</literal>, cores will be stored in the journal and rotated
following normal journal rotation patterns.</para>
<literal>external</literal>, and <literal>journal</literal>. When <literal>none</literal>, the core
dumps may be logged (including the backtrace if possible), but not stored permanently. When
<literal>external</literal> (the default), cores will be stored in
<filename>/var/lib/systemd/coredump/</filename>. When <literal>journal</literal>, cores will be
stored in the journal and rotated following normal journal rotation patterns.</para>
<para>When cores are stored in the journal, they might be
compressed following journal compression settings, see
<para>When cores are stored in the journal, they might be compressed following journal compression
settings, see
<citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
When cores are stored externally, they will be compressed
by default, see below.</para></listitem>
When cores are stored externally, they will be compressed by default, see below.</para>
<para>Note that in order to process a coredump (i.e. extract a stack trace) the core must be written
to disk first. Thus, unless <varname>ProcessSizeMax=</varname> is set to 0 (see below), the core will
be written to <filename>/var/lib/systemd/coredump/</filename> either way (under a temporary filename,
or even in an unlinked file), <varname>Storage=</varname> thus only controls whether to leave it
there even after it was processed.</para></listitem>
</varlistentry>
<varlistentry>
@ -84,7 +88,7 @@
<term><varname>ProcessSizeMax=</varname></term>
<listitem><para>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.</para>

View file

@ -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);

View file

@ -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);