From e41eae8b42052d07432405cca113ffcf8cf49c06 Mon Sep 17 00:00:00 2001 From: Shijiang Wei Date: Sat, 31 Oct 2015 02:15:49 +0800 Subject: [PATCH] fix a race in json logger reader The json decoder starts to decode immediately an inotify event is received. But at the time the inotify event is trigged, the json log entry might haven't been fully written to the disk. In this case the decoder will return an "io.UnexpectedEOF" error, but there is still data remaining in the decoder's buffer. And the data should be passed to the decoder when the next inotify event is triggered. Signed-off-by: Shijiang Wei --- daemon/logger/jsonfilelog/jsonfilelog.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/daemon/logger/jsonfilelog/jsonfilelog.go b/daemon/logger/jsonfilelog/jsonfilelog.go index 490e84ca9c..09012c59c6 100644 --- a/daemon/logger/jsonfilelog/jsonfilelog.go +++ b/daemon/logger/jsonfilelog/jsonfilelog.go @@ -357,6 +357,17 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int retries++ continue } + + // io.ErrUnexpectedEOF is returned from json.Decoder when there is + // remaining data in the parser's buffer while an io.EOF occurs. + // If the json logger writes a partial json log entry to the disk + // while at the same time the decoder tries to decode it, the race codition happens. + if err == io.ErrUnexpectedEOF && retries <= maxJSONDecodeRetry { + reader := io.MultiReader(dec.Buffered(), f) + dec = json.NewDecoder(reader) + retries++ + continue + } logWatcher.Err <- err return }