diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
index 7cb71f80aa..7a617b1985 100644
--- a/man/coredump.conf.xml
+++ b/man/coredump.conf.xml
@@ -97,11 +97,14 @@
ExternalSizeMax=JournalSizeMax=
- 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 .
+ 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, JournalSizeMax= may be
+ lowered relative to the default, but not increased. Unit suffixes are allowed just as in
+ .
- ExternalSizeMax=infinity sets the core size to unlimited.
+ ExternalSizeMax=infinity sets the core size to unlimited.
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
index 6f6fb8068c..bf1aab9e38 100644
--- a/src/basic/io-util.c
+++ b/src/basic/io-util.c
@@ -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;
diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c
index 847ac531df..39b777b535 100644
--- a/src/coredump/coredump.c
+++ b/src/coredump/coredump.c
@@ -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)