mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
Merge pull request #28760 from poettering/coredump-tweaks
coredump: minor tweaks/modernizations
This commit is contained in:
commit
09256904ed
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue