Add synchronization in server.Containers

This fixes races between ps and other operations
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)
This commit is contained in:
Alexandr Morozov 2014-06-30 10:52:11 +04:00
parent b4df555d27
commit da853e98c9
1 changed files with 20 additions and 6 deletions

View File

@ -23,6 +23,7 @@ package server
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "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 == "" { if !container.State.IsRunning() && !all && n <= 0 && since == "" && before == "" {
continue return nil
} }
if before != "" && !foundBefore { if before != "" && !foundBefore {
if container.ID == beforeCont.ID { if container.ID == beforeCont.ID {
foundBefore = true foundBefore = true
} }
continue return nil
} }
if n > 0 && displayed == n { if n > 0 && displayed == n {
break return errLast
} }
if since != "" { if since != "" {
if container.ID == sinceCont.ID { if container.ID == sinceCont.ID {
break return errLast
} }
} }
displayed++ displayed++
@ -997,7 +1001,7 @@ func (srv *Server) Containers(job *engine.Job) engine.Status {
out.Set("Status", container.State.String()) out.Set("Status", container.State.String())
str, err := container.NetworkSettings.PortMappingAPI().ToListString() str, err := container.NetworkSettings.PortMappingAPI().ToListString()
if err != nil { if err != nil {
return job.Error(err) return err
} }
out.Set("Ports", str) out.Set("Ports", str)
if size { if size {
@ -1006,6 +1010,16 @@ func (srv *Server) Containers(job *engine.Job) engine.Status {
out.SetInt64("SizeRootFs", sizeRootFs) out.SetInt64("SizeRootFs", sizeRootFs)
} }
outs.Add(out) 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() outs.ReverseSort()
if _, err := outs.WriteListTo(job.Stdout); err != nil { if _, err := outs.WriteListTo(job.Stdout); err != nil {