From 4f8cec1924bf00532f5350d9a4d7af8e853241fe Mon Sep 17 00:00:00 2001
From: huangkaibin <huangkaibin@huawei.com>
Date: Thu, 28 Jun 2018 20:23:45 +0800
Subject: [PATCH] systemd-journald: Fix journal file descriptors leak problems.

Journal files opened and then be removed by external programs(for example, the journal rotation
of systemd-journald will removed jounal files) before journal directory notify watching is added
will not be closed properly. This patch fix this problem by removing and closing these deleted journal files
after notify watching is added.
---
 src/libsystemd/sd-journal/sd-journal.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c
index 5728c53..1238652 100644
--- a/src/libsystemd/sd-journal/sd-journal.c
+++ b/src/libsystemd/sd-journal/sd-journal.c
@@ -1584,6 +1584,17 @@ fail:
         log_debug_errno(errno, "Failed to enumerate directory %s, ignoring: %m", m->path);
 }
 
+static void remove_nonexistent_journal_files(sd_journal *j) {
+    JournalFile *f = NULL;
+    ORDERED_HASHMAP_FOREACH(f, j->files) {
+        if(f->path && access(f->path, F_OK) < 0) {
+            log_debug("Remove not-existed file from the journal map: %s", f->path);
+            /*Its OK to remove entry from the hashmap although we are iterating on it.*/
+            remove_file_real(j, f);
+        }
+    }
+}
+
 static void directory_watch(sd_journal *j, Directory *m, int fd, uint32_t mask) {
         int r;
 
@@ -1612,6 +1623,14 @@ static void directory_watch(sd_journal *j, Directory *m, int fd, uint32_t mask)
                 (void) inotify_rm_watch(j->inotify_fd, m->wd);
                 m->wd = -1;
         }
+
+        /*
+         * Before event watching, there were some files opened and if some of these opened files were
+         * deleted due to the journal rotation of systemd-jounald, they will become leaking files and will
+         * never be closed until the process exited.
+         * So here we remove these deleted files from the journal after event watching.
+         */
+        remove_nonexistent_journal_files(j);
 }
 
 static int add_directory(
-- 
2.27.0

