ecbff1
From 80f0fa4a77bfceab3bae7cf67f44b8f899b22427 Mon Sep 17 00:00:00 2001
ecbff1
From: Vito Caputo <vcaputo@gnugeneration.com>
ecbff1
Date: Tue, 18 Jul 2017 18:00:37 +0200
ecbff1
Subject: [PATCH] journal: implicitly flush to var on recovery (#4028)
ecbff1
ecbff1
When the system journal becomes re-opened post-flush with the runtime
ecbff1
journal open, it implies we've recovered from something like an ENOSPC
ecbff1
situation where the system journal rotate had failed, leaving the system
ecbff1
journal closed, causing the runtime journal to be opened post-flush.
ecbff1
ecbff1
For the duration of the unavailable system journal, we log to the
ecbff1
runtime journal.  But when the system journal gets opened (space made
ecbff1
available, for example), we need to close the runtime journal before new
ecbff1
journal writes will go to the system journal.  Calling
ecbff1
server_flush_to_var() after opening the system journal with a runtime
ecbff1
journal present, post-flush, achieves this while preserving the runtime
ecbff1
journal's contents in the system journal.
ecbff1
ecbff1
The combination of the present flushed flag file and the runtime journal
ecbff1
being open is a state where we should be logging to the system journal,
ecbff1
so it's appropriate to resume doing so once we've successfully opened
ecbff1
the system journal.
ecbff1
ecbff1
(cherry picked from commit 929eeb5498e8ae87e05ae683c6d3014d4b59056d)
ecbff1
ecbff1
Related: #1364092
ecbff1
---
ecbff1
 src/journal/journald-server.c | 15 +++++++++++++--
ecbff1
 1 file changed, 13 insertions(+), 2 deletions(-)
ecbff1
ecbff1
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
ecbff1
index 2b7ecd09a..3e9412d57 100644
ecbff1
--- a/src/journal/journald-server.c
ecbff1
+++ b/src/journal/journald-server.c
ecbff1
@@ -923,6 +923,7 @@ 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
@@ -933,7 +934,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
         if (!s->system_journal &&
ecbff1
             (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
ecbff1
             (flush_requested
ecbff1
-             || access("/run/systemd/journal/flushed", F_OK) >= 0)) {
ecbff1
+             || (flushed = (access("/run/systemd/journal/flushed", F_OK) >= 0)))) {
ecbff1
 
ecbff1
                 /* If in auto mode: first try to create the machine
ecbff1
                  * path, but not the prefix.
ecbff1
@@ -958,6 +959,16 @@ static int system_journal_open(Server *s, bool flush_requested) {
ecbff1
 
ecbff1
                         r = 0;
ecbff1
                 }
ecbff1
+
ecbff1
+                /* If the runtime journal is open, and we're post-flush, we're
ecbff1
+                 * recovering from a failed system journal rotate (ENOSPC)
ecbff1
+                 * for which the runtime journal was reopened.
ecbff1
+                 *
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
         }
ecbff1
 
ecbff1
         if (!s->runtime_journal &&
ecbff1
@@ -1230,7 +1241,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
-        server_flush_to_var(s);
ecbff1
+        (void) server_flush_to_var(s);
ecbff1
         server_sync(s);
ecbff1
         server_vacuum(s);
ecbff1