From 5451d79b296bbeada4d38d062044b6e985e54708 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 11 Mar 2019 15:40:17 -0700 Subject: [PATCH] Call sd_journal_get_fd() earlier, only if needed 1. The journald client library initializes inotify watch(es) during the first call to sd_journal_get_fd(), and it make sense to open it earlier in order to not lose any journal file rotation events. 2. It only makes sense to call this if we're going to use it later on -- so add a check for config.Follow. 3. Remove the redundant call to sd_journal_get_fd(). NOTE that any subsequent calls to sd_journal_get_fd() return the same file descriptor, so there's no real need to save it for later use in wait_for_data_cancelable(). Based on earlier patch by Nalin Dahyabhai . Signed-off-by: Kir Kolyshkin (cherry picked from commit 981c01665bcb2c9fc5e555c5b976995f31c2a6b4) Signed-off-by: Kir Kolyshkin Upstream-commit: 349e199eab5337f03b442f38720293143e1b1fca Component: engine --- .../engine/daemon/logger/journald/read.go | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/components/engine/daemon/logger/journald/read.go b/components/engine/daemon/logger/journald/read.go index cbd1e24677..8aa01c460d 100644 --- a/components/engine/daemon/logger/journald/read.go +++ b/components/engine/daemon/logger/journald/read.go @@ -330,6 +330,15 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon close(logWatcher.Msg) return } + if config.Follow { + // Initialize library inotify watches early + rc = C.sd_journal_get_fd(j) + if rc < 0 { + logWatcher.Err <- errors.New("error getting journald fd: " + CErr(rc)) + close(logWatcher.Msg) + return + } + } // If we end up following the log, we can set the journal context // pointer and the channel pointer to nil so that we won't close them // here, potentially while the goroutine that uses them is still @@ -402,21 +411,16 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon } cursor, _ = s.drainJournal(logWatcher, j, nil, untilUnixMicro) if config.Follow { - // Allocate a descriptor for following the journal, if we'll - // need one. Do it here so that we can report if it fails. - if fd := C.sd_journal_get_fd(j); fd < C.int(0) { - logWatcher.Err <- fmt.Errorf("error opening journald follow descriptor: %q", C.GoString(C.strerror(-fd))) + // Create a pipe that we can poll at the same time as + // the journald descriptor. + ret := C.pipe(&pipes[0]) + if ret < 0 { + logWatcher.Err <- fmt.Errorf("error creating journald notification pipe") } else { - // Create a pipe that we can poll at the same time as - // the journald descriptor. - if C.pipe(&pipes[0]) == C.int(-1) { - logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe") - } else { - cursor = s.followJournal(logWatcher, j, pipes, cursor, untilUnixMicro) - // Let followJournal handle freeing the journal context - // object and closing the channel. - following = true - } + cursor = s.followJournal(logWatcher, j, pipes, cursor, untilUnixMicro) + // Let followJournal handle freeing the journal context + // object and closing the channel. + following = true } }