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