summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/journald.conf.xml39
-rw-r--r--src/journal/journal-file.h1
-rw-r--r--src/journal/journal-vacuum.c6
-rw-r--r--src/journal/journal-vacuum.h2
-rw-r--r--src/journal/journald-server.c22
-rw-r--r--src/journal/test-journal-interleaving.c4
-rw-r--r--src/journal/test-journal.c4
-rw-r--r--src/shared/macro.h7
8 files changed, 58 insertions, 27 deletions
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index b362c5de2c..e0796e1cce 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -250,20 +250,35 @@
<para><varname>SystemMaxUse=</varname>
and <varname>RuntimeMaxUse=</varname>
control how much disk space the
- journal may use up at
- maximum. Defaults to 10% of the size
- of the respective file
- system. <varname>SystemKeepFree=</varname>
- and
+ journal may use up at maximum.
+ <varname>SystemKeepFree=</varname> and
<varname>RuntimeKeepFree=</varname>
control how much disk space
- systemd-journald shall always leave
- free for other uses. Defaults to 15%
- of the size of the respective file
- system. systemd-journald will respect
- both limits, i.e. use the smaller of
- the two values.
- <varname>SystemMaxFileSize=</varname>
+ systemd-journald shall leave free for
+ other uses.
+ <command>systemd-journald</command>
+ will respect both limits and use the
+ smaller of the two values.</para>
+
+ <para>The first pair defaults to 10%
+ and the second to 15% of the size of
+ the respective file system. If the
+ file system is nearly full and either
+ <varname>SystemKeepFree=</varname> or
+ <varname>RuntimeKeepFree=</varname> is
+ violated when systemd-journald is
+ started, the value will be raised to
+ percentage that is actually free. This
+ means that if before there was enough
+ free space and journal files were
+ created, and subsequently something
+ else causes the file system to fill
+ up, journald will stop using more
+ space, but it'll will not removing
+ existing files to go reduce footprint
+ either.</para>
+
+ <para><varname>SystemMaxFileSize=</varname>
and
<varname>RuntimeMaxFileSize=</varname>
control how large individual journal
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 885b3b1df4..50dbe29cc1 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -37,6 +37,7 @@
typedef struct JournalMetrics {
uint64_t max_use;
+ uint64_t use;
uint64_t max_size;
uint64_t min_size;
uint64_t keep_free;
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index b2b47d69b2..c92c198245 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -150,7 +150,6 @@ static int journal_file_empty(int dir_fd, const char *name) {
int journal_directory_vacuum(
const char *directory,
uint64_t max_use,
- uint64_t min_free,
usec_t max_retention_usec,
usec_t *oldest_usec) {
@@ -164,7 +163,7 @@ int journal_directory_vacuum(
assert(directory);
- if (max_use <= 0 && min_free <= 0 && max_retention_usec <= 0)
+ if (max_use <= 0 && max_retention_usec <= 0)
return 0;
if (max_retention_usec > 0) {
@@ -309,8 +308,7 @@ int journal_directory_vacuum(
}
if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
- (max_use <= 0 || sum <= max_use) &&
- (min_free <= 0 || (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free))
+ (max_use <= 0 || sum <= max_use))
break;
if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h
index f5e3e5291f..bc30c3a140 100644
--- a/src/journal/journal-vacuum.h
+++ b/src/journal/journal-vacuum.h
@@ -23,4 +23,4 @@
#include <inttypes.h>
-int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free, usec_t max_retention_usec, usec_t *oldest_usec);
+int journal_directory_vacuum(const char *directory, uint64_t max_use, usec_t max_retention_usec, usec_t *oldest_usec);
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index a3bacdab66..d3a1c574bd 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -158,9 +158,18 @@ static uint64_t available_space(Server *s, bool verbose) {
}
ss_avail = ss.f_bsize * ss.f_bavail;
- avail = ss_avail > m->keep_free ? ss_avail - m->keep_free : 0;
- s->cached_available_space = MIN(m->max_use, avail) > sum ? MIN(m->max_use, avail) - sum : 0;
+ /* If we reached a high mark, we will always allow this much
+ * again, unless usage goes above max_use. This watermark
+ * value is cached so that we don't give up space on pressure,
+ * but hover below the maximum usage. */
+
+ if (m->use < sum)
+ m->use = sum;
+
+ avail = LESS_BY(ss_avail, m->keep_free);
+
+ s->cached_available_space = LESS_BY(MIN(m->max_use, avail), sum);
s->cached_available_space_timestamp = ts;
if (verbose) {
@@ -168,13 +177,14 @@ static uint64_t available_space(Server *s, bool verbose) {
fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX];
server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
- "%s journal is using %s (max %s, leaving %s of free %s, current limit %s).",
+ "%s journal is using %s (max allowed %s, "
+ "trying to leave %s free of %s available → current limit %s).",
s->system_journal ? "Permanent" : "Runtime",
format_bytes(fb1, sizeof(fb1), sum),
format_bytes(fb2, sizeof(fb2), m->max_use),
format_bytes(fb3, sizeof(fb3), m->keep_free),
format_bytes(fb4, sizeof(fb4), ss_avail),
- format_bytes(fb5, sizeof(fb5), MIN(m->max_use, avail)));
+ format_bytes(fb5, sizeof(fb5), s->cached_available_space + sum));
}
return s->cached_available_space;
@@ -379,7 +389,7 @@ void server_vacuum(Server *s) {
if (s->system_journal) {
char *p = strappenda("/var/log/journal/", ids);
- r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
+ r = journal_directory_vacuum(p, s->system_metrics.max_use, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
log_error("Failed to vacuum %s: %s", p, strerror(-r));
}
@@ -387,7 +397,7 @@ void server_vacuum(Server *s) {
if (s->runtime_journal) {
char *p = strappenda("/run/log/journal/", ids);
- r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
+ r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->max_retention_usec, &s->oldest_file_usec);
if (r < 0 && r != -ENOENT)
log_error("Failed to vacuum %s: %s", p, strerror(-r));
}
diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c
index 5b74714782..5c9604472e 100644
--- a/src/journal/test-journal-interleaving.c
+++ b/src/journal/test-journal-interleaving.c
@@ -189,7 +189,7 @@ static void test_skip(void (*setup)(void)) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
@@ -274,7 +274,7 @@ static void test_sequence_numbers(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index 189fe07b48..85b4cf71ac 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -126,7 +126,7 @@ static void test_non_empty(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
@@ -165,7 +165,7 @@ static void test_empty(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
diff --git a/src/shared/macro.h b/src/shared/macro.h
index 79bee0396c..dfbc20142f 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -117,6 +117,13 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
_a < _b ? _a : _b; \
})
+#define LESS_BY(A,B) \
+ __extension__ ({ \
+ typeof(A) _A = (A); \
+ typeof(B) _B = (B); \
+ _A > _B ? _A - _B : 0; \
+ })
+
#ifndef CLAMP
#define CLAMP(x, low, high) \
__extension__ ({ \