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 {
|
func (container *Container) Start() error {
|
||||||
|
container.State.lock()
|
||||||
|
defer container.State.unlock()
|
||||||
|
|
||||||
if container.State.Running {
|
if container.State.Running {
|
||||||
return fmt.Errorf("The container %s is already running.", container.Id)
|
return fmt.Errorf("The container %s is already running.", container.Id)
|
||||||
}
|
}
|
||||||
|
@ -411,7 +414,6 @@ func (container *Container) Start() error {
|
||||||
|
|
||||||
// Init the lock
|
// Init the lock
|
||||||
container.waitLock = make(chan struct{})
|
container.waitLock = make(chan struct{})
|
||||||
|
|
||||||
container.ToDisk()
|
container.ToDisk()
|
||||||
go container.monitor()
|
go container.monitor()
|
||||||
return nil
|
return nil
|
||||||
|
@ -544,7 +546,7 @@ func (container *Container) monitor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) kill() error {
|
func (container *Container) kill() error {
|
||||||
if container.cmd == nil {
|
if !container.State.Running || container.cmd == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := container.cmd.Process.Kill(); err != nil {
|
if err := container.cmd.Process.Kill(); err != nil {
|
||||||
|
@ -556,13 +558,14 @@ func (container *Container) kill() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) Kill() error {
|
func (container *Container) Kill() error {
|
||||||
if !container.State.Running {
|
container.State.lock()
|
||||||
return nil
|
defer container.State.unlock()
|
||||||
}
|
|
||||||
return container.kill()
|
return container.kill()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (container *Container) Stop() error {
|
func (container *Container) Stop() error {
|
||||||
|
container.State.lock()
|
||||||
|
defer container.State.unlock()
|
||||||
if !container.State.Running {
|
if !container.State.Running {
|
||||||
return nil
|
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 {
|
if output, err := exec.Command("lxc-kill", "-n", container.Id, "15").CombinedOutput(); err != nil {
|
||||||
log.Print(string(output))
|
log.Print(string(output))
|
||||||
log.Print("Failed to send SIGTERM to the process, force killing")
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,7 @@ func (runtime *Runtime) Register(container *Container) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
container.State.initLock()
|
||||||
|
|
||||||
container.runtime = runtime
|
container.runtime = runtime
|
||||||
|
|
||||||
|
|
14
state.go
14
state.go
|
@ -2,6 +2,7 @@ package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ type State struct {
|
||||||
Pid int
|
Pid int
|
||||||
ExitCode int
|
ExitCode int
|
||||||
StartedAt time.Time
|
StartedAt time.Time
|
||||||
|
l *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a human-readable description of the state
|
// String returns a human-readable description of the state
|
||||||
|
@ -32,3 +34,15 @@ func (s *State) setStopped(exitCode int) {
|
||||||
s.Pid = 0
|
s.Pid = 0
|
||||||
s.ExitCode = exitCode
|
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