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