| From 53ae6296386a754ed74a1d3fbd88f39ab7a89f0d Mon Sep 17 00:00:00 2001 |
| From: Lennart Poettering <lennart@poettering.net> |
| Date: Mon, 12 Dec 2016 20:54:45 +0100 |
| Subject: [PATCH] journald: don't flush to /var/log/journal before we get asked |
| to |
| |
| This changes journald to not write to /var/log/journal until it received |
| SIGUSR1 for the first time, thus having been requested to flush the runtime |
| journal to disk. |
| |
| This makes the journal work nicer with systems which have the root file system |
| writable early, but still need to rearrange /var before journald should start |
| writing and creating files to it, for example because ACLs need to be applied |
| first, or because /var is to be mounted from another file system, NFS or tmpfs |
| (as is the case for systemd.volatile=state). |
| |
| Before this change we required setupts with /var split out to mount the root |
| disk read-only early on, and ship an /etc/fstab that remounted it writable only |
| after having placed /var at the right place. But even that was racy for various |
| preparations as journald might end up accessing the file system before it was |
| entirely set up, as soon as it was writable. |
| |
| With this change we make scheduling when to start writing to /var/log/journal |
| explicit. This means persistent mode now requires |
| systemd-journal-flush.service in the mix to work, as otherwise journald would |
| never write to the directory. |
| |
| See: #1397 |
| (cherry picked from commit f78273c8dacf678cc8fd7387f678e6344a99405c) |
| --- |
| src/journal/journald-server.c | 21 +++++++++++---------- |
| src/journal/journald-server.h | 2 +- |
| src/journal/journald.c | 2 +- |
| 3 files changed, 13 insertions(+), 12 deletions(-) |
| |
| diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c |
| index 1d2fce8dc7..ced0ad6f21 100644 |
| --- a/src/journal/journald-server.c |
| +++ b/src/journal/journald-server.c |
| @@ -283,17 +283,16 @@ static int open_journal( |
| } |
| |
| static bool flushed_flag_is_set(void) { |
| - return (access("/run/systemd/journal/flushed", F_OK) >= 0); |
| + return access("/run/systemd/journal/flushed", F_OK) >= 0; |
| } |
| |
| static int system_journal_open(Server *s, bool flush_requested) { |
| - bool flushed = false; |
| const char *fn; |
| int r = 0; |
| |
| if (!s->system_journal && |
| - (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) && |
| - (flush_requested || (flushed = flushed_flag_is_set()))) { |
| + IN_SET(s->storage, STORAGE_PERSISTENT, STORAGE_AUTO) && |
| + (flush_requested || flushed_flag_is_set())) { |
| |
| /* If in auto mode: first try to create the machine |
| * path, but not the prefix. |
| @@ -326,8 +325,8 @@ static int system_journal_open(Server *s, bool flush_requested) { |
| * Perform an implicit flush to var, leaving the runtime |
| * journal closed, now that the system journal is back. |
| */ |
| - if (s->runtime_journal && flushed) |
| - (void) server_flush_to_var(s); |
| + if (!flush_requested) |
| + (void) server_flush_to_var(s, true); |
| } |
| |
| if (!s->runtime_journal && |
| @@ -1183,7 +1182,7 @@ finish: |
| dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid); |
| } |
| |
| -int server_flush_to_var(Server *s) { |
| +int server_flush_to_var(Server *s, bool require_flag_file) { |
| sd_id128_t machine; |
| sd_journal *j = NULL; |
| char ts[FORMAT_TIMESPAN_MAX]; |
| @@ -1193,13 +1192,15 @@ int server_flush_to_var(Server *s) { |
| |
| assert(s); |
| |
| - if (s->storage != STORAGE_AUTO && |
| - s->storage != STORAGE_PERSISTENT) |
| + if (!IN_SET(s->storage, STORAGE_AUTO, STORAGE_PERSISTENT)) |
| return 0; |
| |
| if (!s->runtime_journal) |
| return 0; |
| |
| + if (require_flag_file && !flushed_flag_is_set()) |
| + return 0; |
| + |
| (void) system_journal_open(s, true); |
| |
| if (!s->system_journal) |
| @@ -1411,7 +1412,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo * |
| |
| log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid); |
| |
| - (void) server_flush_to_var(s); |
| + (void) server_flush_to_var(s, false); |
| server_sync(s); |
| server_vacuum(s, false); |
| |
| diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h |
| index 99d91496be..de1c48f805 100644 |
| --- a/src/journal/journald-server.h |
| +++ b/src/journal/journald-server.h |
| @@ -197,7 +197,7 @@ void server_sync(Server *s); |
| int server_vacuum(Server *s, bool verbose); |
| void server_rotate(Server *s); |
| int server_schedule_sync(Server *s, int priority); |
| -int server_flush_to_var(Server *s); |
| +int server_flush_to_var(Server *s, bool require_flag_file); |
| void server_maybe_append_tags(Server *s); |
| int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata); |
| void server_space_usage_message(Server *s, JournalStorage *storage); |
| diff --git a/src/journal/journald.c b/src/journal/journald.c |
| index 7f47ca22dd..9ac21457f6 100644 |
| --- a/src/journal/journald.c |
| +++ b/src/journal/journald.c |
| @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) { |
| goto finish; |
| |
| server_vacuum(&server, false); |
| - server_flush_to_var(&server); |
| + server_flush_to_var(&server, true); |
| server_flush_dev_kmsg(&server); |
| |
| log_debug("systemd-journald running as pid "PID_FMT, getpid()); |