From 7c2b085d1a1394dc88b0cdf5c9df02ee1c1b2229 Mon Sep 17 00:00:00 2001 From: "Guillaume J. Charmes" Date: Tue, 9 Apr 2013 09:09:54 -0700 Subject: [PATCH] Add inconditionnal lock in Start/Stop/Kill to avoid races --- container.go | 15 +++++++++------ runtime.go | 1 + state.go | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/container.go b/container.go index 37899e57a3..466fe3e440 100644 --- a/container.go +++ b/container.go @@ -342,6 +342,9 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s } func (container *Container) Start() error { + container.State.lock() + defer container.State.unlock() + if container.State.Running { return fmt.Errorf("The container %s is already running.", container.Id) } @@ -411,7 +414,6 @@ func (container *Container) Start() error { // Init the lock container.waitLock = make(chan struct{}) - container.ToDisk() go container.monitor() return nil @@ -544,7 +546,7 @@ func (container *Container) monitor() { } func (container *Container) kill() error { - if container.cmd == nil { + if !container.State.Running || container.cmd == nil { return nil } if err := container.cmd.Process.Kill(); err != nil { @@ -556,13 +558,14 @@ func (container *Container) kill() error { } func (container *Container) Kill() error { - if !container.State.Running { - return nil - } + container.State.lock() + defer container.State.unlock() return container.kill() } func (container *Container) Stop() error { + container.State.lock() + defer container.State.unlock() if !container.State.Running { return nil } @@ -571,7 +574,7 @@ func (container *Container) Stop() error { if output, err := exec.Command("lxc-kill", "-n", container.Id, "15").CombinedOutput(); err != nil { log.Print(string(output)) log.Print("Failed to send SIGTERM to the process, force killing") - if err := container.Kill(); err != nil { + if err := container.kill(); err != nil { return err } } diff --git a/runtime.go b/runtime.go index 64a0c876df..7971fe4f48 100644 --- a/runtime.go +++ b/runtime.go @@ -150,6 +150,7 @@ func (runtime *Runtime) Register(container *Container) error { } } } + container.State.initLock() container.runtime = runtime diff --git a/state.go b/state.go index cde999f3a6..2ca7130921 100644 --- a/state.go +++ b/state.go @@ -2,6 +2,7 @@ package docker import ( "fmt" + "sync" "time" ) @@ -10,6 +11,7 @@ type State struct { Pid int ExitCode int StartedAt time.Time + l *sync.Mutex } // String returns a human-readable description of the state @@ -32,3 +34,15 @@ func (s *State) setStopped(exitCode int) { s.Pid = 0 s.ExitCode = exitCode } + +func (s *State) initLock() { + s.l = &sync.Mutex{} +} + +func (s *State) lock() { + s.l.Lock() +} + +func (s *State) unlock() { + s.l.Unlock() +}