ecbff1
From 6032a92b8fb27a7c65a1853e62a142fd9a062b73 Mon Sep 17 00:00:00 2001
ecbff1
From: Lennart Poettering <lennart@poettering.net>
ecbff1
Date: Thu, 17 Aug 2017 10:21:23 +0200
ecbff1
Subject: [PATCH] journald: don't flush to /var/log/journal before we get asked
ecbff1
 to
ecbff1
ecbff1
This changes journald to not write to /var/log/journal until it received
ecbff1
SIGUSR1 for the first time, thus having been requested to flush the runtime
ecbff1
journal to disk.
ecbff1
ecbff1
This makes the journal work nicer with systems which have the root file system
ecbff1
writable early, but still need to rearrange /var before journald should start
ecbff1
writing and creating files to it, for example because ACLs need to be applied
ecbff1
first, or because /var is to be mounted from another file system, NFS or tmpfs
ecbff1
(as is the case for systemd.volatile=state).
ecbff1
ecbff1
Before this change we required setupts with /var split out to mount the root
ecbff1
disk read-only early on, and ship an /etc/fstab that remounted it writable only
ecbff1
after having placed /var at the right place. But even that was racy for various
ecbff1
preparations as journald might end up accessing the file system before it was
ecbff1
entirely set up, as soon as it was writable.
ecbff1
ecbff1
With this change we make scheduling when to start writing to /var/log/journal
ecbff1
explicit. This means persistent mode now requires
ecbff1
systemd-journal-flush.service in the mix to work, as otherwise journald would
ecbff1
never write to the directory.
ecbff1
ecbff1
See: #1397
ecbff1
ecbff1
(cherry-picked from commit f78273c8dacf678cc8fd7387f678e6344a99405c)
ecbff1
ecbff1
Resolves: #1364092
ecbff1
---
ecbff1
 src/journal/journald-server.c | 21 +++++++++++----------
ecbff1
 src/journal/journald-server.h |  2 +-
ecbff1
 src/journal/journald.c        |  2 +-
ecbff1
 3 files changed, 13 insertions(+), 12 deletions(-)
ecbff1
ecbff1
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
ecbff1
index 96ffda4ec..07426b41e 100644
ecbff1
--- a/src/journal/journald-server.c
ecbff1
+++ b/src/journal/journald-server.c
ecbff1
@@ -918,7 +918,7 @@ finish:
ecbff1
 }
ecbff1
 
ecbff1
 static bool flushed_flag_is_set(void) {
ecbff1
-        return (access("/run/systemd/journal/flushed", F_OK) >= 0);
ecbff1
+        return access("/run/systemd/journal/flushed", F_OK) >= 0;
ecbff1
 }
ecbff1
 
ecbff1
 static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
@@ -926,7 +926,6 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
         char *fn;
ecbff1
         sd_id128_t machine;
ecbff1
         char ids[33];
ecbff1
-        bool flushed = false;
ecbff1
 
ecbff1
         r = sd_id128_get_machine(&machine);
ecbff1
         if (r < 0)
ecbff1
@@ -935,8 +934,8 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
         sd_id128_to_string(machine, ids);
ecbff1
 
ecbff1
         if (!s->system_journal &&
ecbff1
-            (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
ecbff1
-            (flush_requested || (flushed = flushed_flag_is_set()))) {
ecbff1
+            IN_SET(s->storage, STORAGE_PERSISTENT, STORAGE_AUTO) &&
ecbff1
+            (flush_requested || flushed_flag_is_set())) {
ecbff1
 
ecbff1
                 /* If in auto mode: first try to create the machine
ecbff1
                  * path, but not the prefix.
ecbff1
@@ -969,8 +968,8 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
                  * Perform an implicit flush to var, leaving the runtime
ecbff1
                  * journal closed, now that the system journal is back.
ecbff1
                  */
ecbff1
-                if (s->runtime_journal && flushed)
ecbff1
-                        (void) server_flush_to_var(s);
ecbff1
+                if (!flush_requested)
ecbff1
+                        (void) server_flush_to_var(s, true);
ecbff1
         }
ecbff1
 
ecbff1
         if (!s->runtime_journal &&
ecbff1
@@ -1021,7 +1020,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
         return r;
ecbff1
 }
ecbff1
 
ecbff1
-int server_flush_to_var(Server *s) {
ecbff1
+int server_flush_to_var(Server *s, bool require_flag_file) {
ecbff1
         sd_id128_t machine;
ecbff1
         sd_journal *j = NULL;
ecbff1
         char ts[FORMAT_TIMESPAN_MAX];
ecbff1
@@ -1031,13 +1030,15 @@ int server_flush_to_var(Server *s) {
ecbff1
 
ecbff1
         assert(s);
ecbff1
 
ecbff1
-        if (s->storage != STORAGE_AUTO &&
ecbff1
-            s->storage != STORAGE_PERSISTENT)
ecbff1
+        if (!IN_SET(s->storage, STORAGE_AUTO, STORAGE_PERSISTENT))
ecbff1
                 return 0;
ecbff1
 
ecbff1
         if (!s->runtime_journal)
ecbff1
                 return 0;
ecbff1
 
ecbff1
+        if (require_flag_file && !flushed_flag_is_set())
ecbff1
+                return 0;
ecbff1
+
ecbff1
         system_journal_open(s, true);
ecbff1
 
ecbff1
         if (!s->system_journal)
ecbff1
@@ -1243,7 +1244,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
ecbff1
 
ecbff1
         log_info("Received request to flush runtime journal from PID %"PRIu32, si->ssi_pid);
ecbff1
 
ecbff1
-        (void) server_flush_to_var(s);
ecbff1
+        (void) server_flush_to_var(s, false);
ecbff1
         server_sync(s);
ecbff1
         server_vacuum(s);
ecbff1
 
ecbff1
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
ecbff1
index b1263a758..7a456c2d5 100644
ecbff1
--- a/src/journal/journald-server.h
ecbff1
+++ b/src/journal/journald-server.h
ecbff1
@@ -173,6 +173,6 @@ void server_sync(Server *s);
ecbff1
 void server_vacuum(Server *s);
ecbff1
 void server_rotate(Server *s);
ecbff1
 int server_schedule_sync(Server *s, int priority);
ecbff1
-int server_flush_to_var(Server *s);
ecbff1
+int server_flush_to_var(Server *s, bool require_flag_file);
ecbff1
 void server_maybe_append_tags(Server *s);
ecbff1
 int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata);
ecbff1
diff --git a/src/journal/journald.c b/src/journal/journald.c
ecbff1
index 80f4634f6..15bbcbe3d 100644
ecbff1
--- a/src/journal/journald.c
ecbff1
+++ b/src/journal/journald.c
ecbff1
@@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
ecbff1
                 goto finish;
ecbff1
 
ecbff1
         server_vacuum(&server);
ecbff1
-        server_flush_to_var(&server);
ecbff1
+        server_flush_to_var(&server, true);
ecbff1
         server_flush_dev_kmsg(&server);
ecbff1
 
ecbff1
         log_debug("systemd-journald running as pid "PID_FMT, getpid());