浏览代码

d/logger/journald: quit waiting when logger closes

If a reader has caught up to the logger and is waiting for the next
message, it should stop waiting when the logger is closed. Otherwise
the reader will unnecessarily wait the full closedDrainTimeout for no
log messages to arrive.

This case was overlooked when the journald reader was recently
overhauled to be compatible with systemd 255, and the reader tests only
failed when a logical race happened to settle in such a way to exercise
the bugged code path. It was only after implicit flushing on close was
added to the journald test harness that the Follow tests would
repeatably fail due to this bug. (No new regression tests are needed.)

Signed-off-by: Cory Snider <csnider@mirantis.com>
Cory Snider 1 年之前
父节点
当前提交
987fe37ed1
共有 1 个文件被更改,包括 7 次插入4 次删除
  1. 7 4
      daemon/logger/journald/read.go

+ 7 - 4
daemon/logger/journald/read.go

@@ -216,6 +216,9 @@ func (r *reader) wait() (bool, error) {
 			return false, nil
 		case <-r.s.closed:
 			// Container is gone; don't wait indefinitely for journal entries that will never arrive.
+			if r.maxOrdinal >= atomic.LoadUint64(&r.s.ordinal) {
+				return false, nil
+			}
 			if r.drainDeadline.IsZero() {
 				r.drainDeadline = time.Now().Add(closedDrainTimeout)
 			}
@@ -241,10 +244,10 @@ func (r *reader) nextWait() (bool, error) {
 // current read pointer, until the end of the journal or a terminal stopping
 // condition is reached.
 //
-// It returns false when a terminal stopping condition has been reached: the
-// watch consumer is gone, a log entry is read which has a timestamp after until
-// (if until is nonzero), or the log driver is closed and the last message
-// logged has been sent from the journal.
+// It returns false when a terminal stopping condition has been reached:
+//   - the watch consumer is gone, or
+//   - (if until is nonzero) a log entry is read which has a timestamp after
+//     until
 func (r *reader) drainJournal() (bool, error) {
 	for i := 0; ; i++ {
 		// Read the entry's timestamp.