Merge pull request #28127 from poettering/coredump-loop-read
coredump: fixes with overly large coredumps
This commit is contained in:
@@ -97,11 +97,14 @@
|
||||
<term><varname>ExternalSizeMax=</varname></term>
|
||||
<term><varname>JournalSizeMax=</varname></term>
|
||||
|
||||
<listitem><para>The maximum (compressed or uncompressed) size in bytes of a core to be saved in
|
||||
separate files on disk (default: 1G on 32bit, 32G on 64bit systems) or in the journal (default:
|
||||
10M). Unit suffixes are allowed just as in <option>ProcessSizeMax=</option>.</para></listitem>
|
||||
<listitem><para>The maximum (compressed or uncompressed) size in bytes of a coredump to be saved in
|
||||
separate files on disk (default: 1G on 32-bit systems, 32G on 64-bit systems) or in the journal
|
||||
(default: 767M). Note that the journal service enforces a hard limit on journal log records of 767M,
|
||||
and will ignore larger submitted log records. Hence, <varname>JournalSizeMax=</varname> may be
|
||||
lowered relative to the default, but not increased. Unit suffixes are allowed just as in
|
||||
<option>ProcessSizeMax=</option>.</para>
|
||||
|
||||
<para><varname>ExternalSizeMax=infinity</varname> sets the core size to unlimited.</para>
|
||||
<para><varname>ExternalSizeMax=infinity</varname> sets the core size to unlimited.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
||||
+1
-2
@@ -54,8 +54,7 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
/* If called with nbytes == 0, let's call read() at least
|
||||
* once, to validate the operation */
|
||||
/* If called with nbytes == 0, let's call read() at least once, to validate the operation */
|
||||
|
||||
if (nbytes > (size_t) SSIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
+27
-8
@@ -172,9 +172,27 @@ static int parse_config(void) {
|
||||
{}
|
||||
};
|
||||
|
||||
return config_parse_config_file("coredump.conf", "Coredump\0",
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN, NULL);
|
||||
int r;
|
||||
|
||||
r = config_parse_config_file(
|
||||
"coredump.conf",
|
||||
"Coredump\0",
|
||||
config_item_table_lookup,
|
||||
items,
|
||||
CONFIG_PARSE_WARN,
|
||||
/* userdata= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Let's make sure we fix up the maximum size we send to the journal here on the client side, for
|
||||
* efficiency reasons. journald wouldn't accept anything larger anyway. */
|
||||
if (arg_journal_size_max > JOURNAL_SIZE_MAX) {
|
||||
log_warning("JournalSizeMax= set to larger value (%s) than journald would accept (%s), lowering automatically.",
|
||||
FORMAT_BYTES(arg_journal_size_max), FORMAT_BYTES(JOURNAL_SIZE_MAX));
|
||||
arg_journal_size_max = JOURNAL_SIZE_MAX;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t storage_size_max(void) {
|
||||
@@ -604,14 +622,15 @@ static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_s
|
||||
return log_warning_errno(errno, "Failed to seek: %m");
|
||||
|
||||
field = malloc(9 + size);
|
||||
if (!field) {
|
||||
log_warning("Failed to allocate memory for coredump, coredump will not be stored.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!field)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(ENOMEM),
|
||||
"Failed to allocate memory for coredump, coredump will not be stored.");
|
||||
|
||||
memcpy(field, "COREDUMP=", 9);
|
||||
|
||||
n = read(fd, field + 9, size);
|
||||
/* NB: simple read() would fail for overly large coredumps, since read() on Linux can only deal with
|
||||
* 0x7ffff000 bytes max. Hence call things in a loop. */
|
||||
n = loop_read(fd, field + 9, size, /* do_poll= */ false);
|
||||
if (n < 0)
|
||||
return log_error_errno((int) n, "Failed to read core data: %m");
|
||||
if ((size_t) n < size)
|
||||
|
||||
Reference in New Issue
Block a user