Skip to content

Commit

Permalink
Do not wait for container on stop if the process doesn't exist.
Browse files Browse the repository at this point in the history
This fixes an issue that caused the client to hang forever if the
process died before the code arrived to exit the `Kill` function.

Signed-off-by: David Calavera <david.calavera@gmail.com>
  • Loading branch information
calavera committed Mar 4, 2016
1 parent e7cbae9 commit 1a729c3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 3 additions & 1 deletion daemon/container_operations_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,9 @@ func killProcessDirectly(container *container.Container) error {
if err != syscall.ESRCH {
return err
}
logrus.Debugf("Cannot kill process (pid=%d) with signal 9: no such process.", pid)
e := errNoSuchProcess{pid, 9}
logrus.Debug(e)
return e
}
}
}
Expand Down
27 changes: 25 additions & 2 deletions daemon/kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ import (
"github.com/docker/docker/pkg/signal"
)

type errNoSuchProcess struct {
pid int
signal int
}

func (e errNoSuchProcess) Error() string {
return fmt.Sprintf("Cannot kill process (pid=%d) with signal %d: no such process.", e.pid, e.signal)
}

// isErrNoSuchProcess returns true if the error
// is an instance of errNoSuchProcess.
func isErrNoSuchProcess(err error) bool {
_, ok := err.(errNoSuchProcess)
return ok
}

// ContainerKill send signal to the container
// If no signal is given (sig 0), then Kill with SIGKILL and wait
// for the container to exit.
Expand Down Expand Up @@ -89,6 +105,9 @@ func (daemon *Daemon) Kill(container *container.Container) error {
// So, instead we'll give it up to 2 more seconds to complete and if
// by that time the container is still running, then the error
// we got is probably valid and so we return it to the caller.
if isErrNoSuchProcess(err) {
return nil
}

if container.IsRunning() {
container.WaitStop(2 * time.Second)
Expand All @@ -100,6 +119,9 @@ func (daemon *Daemon) Kill(container *container.Container) error {

// 2. Wait for the process to die, in last resort, try to kill the process directly
if err := killProcessDirectly(container); err != nil {
if isErrNoSuchProcess(err) {
return nil
}
return err
}

Expand All @@ -111,8 +133,9 @@ func (daemon *Daemon) Kill(container *container.Container) error {
func (daemon *Daemon) killPossiblyDeadProcess(container *container.Container, sig int) error {
err := daemon.killWithSignal(container, sig)
if err == syscall.ESRCH {
logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.GetPID(), sig)
return nil
e := errNoSuchProcess{container.GetPID(), sig}
logrus.Debug(e)
return e
}
return err
}

0 comments on commit 1a729c3

Please sign in to comment.