Selaa lähdekoodia

Fix race conditions in logs API

Closing the log driver was in a defer meanwhile logs are
collected asyncronously, so the log driver was being closed before reads
were actually finished.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 7 vuotta sitten
vanhempi
commit
2c252a48c2
1 muutettua tiedostoa jossa 12 lisäystä ja 3 poistoa
  1. 12 3
      daemon/logs.go

+ 12 - 3
daemon/logs.go

@@ -22,7 +22,7 @@ import (
 //
 // if it returns nil, the config channel will be active and return log
 // messages until it runs out or the context is canceled.
-func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, config *types.ContainerLogsOptions) (<-chan *backend.LogMessage, bool, error) {
+func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, config *types.ContainerLogsOptions) (messages <-chan *backend.LogMessage, isTTY bool, retErr error) {
 	lg := logrus.WithFields(logrus.Fields{
 		"module":    "daemon",
 		"method":    "(*Daemon).ContainerLogs",
@@ -51,8 +51,10 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
 	}
 	if cLogCreated {
 		defer func() {
-			if err = cLog.Close(); err != nil {
-				logrus.Errorf("Error closing logger: %v", err)
+			if retErr != nil {
+				if err = cLog.Close(); err != nil {
+					logrus.Errorf("Error closing logger: %v", err)
+				}
 			}
 		}()
 	}
@@ -101,6 +103,13 @@ func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, c
 	// this goroutine functions as a shim between the logger and the caller.
 	messageChan := make(chan *backend.LogMessage, 1)
 	go func() {
+		if cLogCreated {
+			defer func() {
+				if err = cLog.Close(); err != nil {
+					logrus.Errorf("Error closing logger: %v", err)
+				}
+			}()
+		}
 		// set up some defers
 		defer logs.Close()