From da853e98c94c9ce8001d3d1516ba0fd2614db3b0 Mon Sep 17 00:00:00 2001 From: Alexandr Morozov Date: Mon, 30 Jun 2014 10:52:11 +0400 Subject: [PATCH] Add synchronization in server.Containers This fixes races between ps and other operations Docker-DCO-1.1-Signed-off-by: Alexandr Morozov (github: LK4D4) --- server/server.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/server/server.go b/server/server.go index 0bbb9f31ca..8be4dcd7b3 100644 --- a/server/server.go +++ b/server/server.go @@ -23,6 +23,7 @@ package server import ( "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -955,22 +956,25 @@ func (srv *Server) Containers(job *engine.Job) engine.Status { } } - for _, container := range srv.daemon.List() { + errLast := errors.New("last container") + writeCont := func(container *daemon.Container) error { + container.Lock() + defer container.Unlock() if !container.State.IsRunning() && !all && n <= 0 && since == "" && before == "" { - continue + return nil } if before != "" && !foundBefore { if container.ID == beforeCont.ID { foundBefore = true } - continue + return nil } if n > 0 && displayed == n { - break + return errLast } if since != "" { if container.ID == sinceCont.ID { - break + return errLast } } displayed++ @@ -997,7 +1001,7 @@ func (srv *Server) Containers(job *engine.Job) engine.Status { out.Set("Status", container.State.String()) str, err := container.NetworkSettings.PortMappingAPI().ToListString() if err != nil { - return job.Error(err) + return err } out.Set("Ports", str) if size { @@ -1006,6 +1010,16 @@ func (srv *Server) Containers(job *engine.Job) engine.Status { out.SetInt64("SizeRootFs", sizeRootFs) } outs.Add(out) + return nil + } + + for _, container := range srv.daemon.List() { + if err := writeCont(container); err != nil { + if err != errLast { + return job.Error(err) + } + break + } } outs.ReverseSort() if _, err := outs.WriteListTo(job.Stdout); err != nil {