mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add inconditionnal lock in Start/Stop/Kill to avoid races
This commit is contained in:
parent
329f4449dc
commit
7c2b085d1a
3 changed files with 24 additions and 6 deletions
15
container.go
15
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ func (runtime *Runtime) Register(container *Container) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
container.State.initLock()
|
||||
|
||||
container.runtime = runtime
|
||||
|
||||
|
|
14
state.go
14
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()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue