Blame SOURCES/0613-sd-journal-when-picking-up-a-new-file-compare-inode-.patch

17b0f1
From febbc3baae65db64692e3ae2852630c5e324ab43 Mon Sep 17 00:00:00 2001
17b0f1
From: Michal Sekletar <msekleta@redhat.com>
17b0f1
Date: Tue, 20 Feb 2018 14:16:15 +0100
17b0f1
Subject: [PATCH] sd-journal: when picking up a new file, compare inode/device
17b0f1
 info with previous open file by same name
17b0f1
17b0f1
Let's make sure we aren't confused if a journal file is replaced by a
17b0f1
different one (for example due to rotation) if we are in a q overflow:
17b0f1
let's compare the inode/device information, and if it changed replace
17b0f1
any open file object as needed.
17b0f1
17b0f1
Fixes: #8198
17b0f1
17b0f1
(cherry-picked from commit 32cb1983ad6f7084ff86e259ff079742a8139719)
17b0f1
17b0f1
[msekleta: this is very slimmed down version of the above commit because
17b0f1
a lot of code from is not applicable to RHEL-7 version]
17b0f1
17b0f1
Related: #1540538
17b0f1
---
17b0f1
 src/journal/sd-journal.c | 35 +++++++++++++++++++++++++++++------
17b0f1
 1 file changed, 29 insertions(+), 6 deletions(-)
17b0f1
17b0f1
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
17b0f1
index e1cde6e1c2..004fe646d4 100644
17b0f1
--- a/src/journal/sd-journal.c
17b0f1
+++ b/src/journal/sd-journal.c
17b0f1
@@ -1224,20 +1224,43 @@ static bool file_type_wanted(int flags, const char *filename) {
17b0f1
 
17b0f1
 static int add_any_file(sd_journal *j, const char *path) {
17b0f1
         JournalFile *f = NULL;
17b0f1
+        struct stat st;
17b0f1
         int r, k;
17b0f1
 
17b0f1
         assert(j);
17b0f1
         assert(path);
17b0f1
 
17b0f1
-        if (path) {
17b0f1
-                f = ordered_hashmap_get(j->files, path);
17b0f1
-                if (f) {
17b0f1
-                        /* Mark this file as seen in this generation. This is used to GC old files in
17b0f1
-                         * process_q_overflow() to detect journal files that are still and discern them from those who
17b0f1
-                         * are gone. */
17b0f1
+        if (stat(path, &st) < 0) {
17b0f1
+                r = log_debug_errno(errno, "Failed to stat file '%s': %m", path);
17b0f1
+                return -errno;
17b0f1
+        }
17b0f1
+        if (S_ISDIR(st.st_mode)) {
17b0f1
+                log_debug("Uh, file '%s' is a directory? Refusing.", path);
17b0f1
+                return -EISDIR;
17b0f1
+        }
17b0f1
+        if (!S_ISREG(st.st_mode)) {
17b0f1
+                log_debug("Uh, file '%s' is not a regular file? Refusing.", path);
17b0f1
+                return -EBADFD;
17b0f1
+        }
17b0f1
+
17b0f1
+        f = ordered_hashmap_get(j->files, path);
17b0f1
+        if (f) {
17b0f1
+
17b0f1
+                if (f->last_stat.st_dev == st.st_dev &&
17b0f1
+                    f->last_stat.st_ino == st.st_ino) {
17b0f1
+
17b0f1
+                        /* We already track this file, under the same path and with the same device/inode numbers, it's hence
17b0f1
+                         * really the same. Mark this file as seen in this generation. This is used to GC old files in
17b0f1
+                         * process_q_overflow() to detect journal files that are still and discern them from those who are
17b0f1
+                         * gone. */
17b0f1
                         f->last_seen_generation = j->generation;
17b0f1
                         return 0;
17b0f1
                 }
17b0f1
+
17b0f1
+                /* So we tracked a file under this name, but it has a different inode/device. In that case, it got
17b0f1
+                 * replaced (probably due to rotation?), let's drop it hence from our list. */
17b0f1
+                remove_file_real(j, f);
17b0f1
+                f = NULL;
17b0f1
         }
17b0f1
 
17b0f1
         if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {