Browse code

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 <nalin@redhat.com>.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 981c01665bcb2c9fc5e555c5b976995f31c2a6b4)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>

Kir Kolyshkin authored on 2019/03/12 07:40:17
Showing 1 changed files
... ...
@@ -330,6 +330,15 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon
330 330
 		close(logWatcher.Msg)
331 331
 		return
332 332
 	}
333
+	if config.Follow {
334
+		// Initialize library inotify watches early
335
+		rc = C.sd_journal_get_fd(j)
336
+		if rc < 0 {
337
+			logWatcher.Err <- errors.New("error getting journald fd: " + CErr(rc))
338
+			close(logWatcher.Msg)
339
+			return
340
+		}
341
+	}
333 342
 	// If we end up following the log, we can set the journal context
334 343
 	// pointer and the channel pointer to nil so that we won't close them
335 344
 	// here, potentially while the goroutine that uses them is still
... ...
@@ -402,21 +411,16 @@ func (s *journald) readLogs(logWatcher *logger.LogWatcher, config logger.ReadCon
402 402
 	}
403 403
 	cursor, _ = s.drainJournal(logWatcher, j, nil, untilUnixMicro)
404 404
 	if config.Follow {
405
-		// Allocate a descriptor for following the journal, if we'll
406
-		// need one.  Do it here so that we can report if it fails.
407
-		if fd := C.sd_journal_get_fd(j); fd < C.int(0) {
408
-			logWatcher.Err <- fmt.Errorf("error opening journald follow descriptor: %q", C.GoString(C.strerror(-fd)))
405
+		// Create a pipe that we can poll at the same time as
406
+		// the journald descriptor.
407
+		ret := C.pipe(&pipes[0])
408
+		if ret < 0 {
409
+			logWatcher.Err <- fmt.Errorf("error creating journald notification pipe")
409 410
 		} else {
410
-			// Create a pipe that we can poll at the same time as
411
-			// the journald descriptor.
412
-			if C.pipe(&pipes[0]) == C.int(-1) {
413
-				logWatcher.Err <- fmt.Errorf("error opening journald close notification pipe")
414
-			} else {
415
-				cursor = s.followJournal(logWatcher, j, pipes, cursor, untilUnixMicro)
416
-				// Let followJournal handle freeing the journal context
417
-				// object and closing the channel.
418
-				following = true
419
-			}
411
+			cursor = s.followJournal(logWatcher, j, pipes, cursor, untilUnixMicro)
412
+			// Let followJournal handle freeing the journal context
413
+			// object and closing the channel.
414
+			following = true
420 415
 		}
421 416
 	}
422 417