Fix docker daemon restart with paused container.
Signed-off-by: Lei Jitang <leijitang@huawei.com>
This commit is contained in:
parent
7ead74d903
commit
9a9724ad56
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/namesgenerator"
|
"github.com/docker/docker/pkg/namesgenerator"
|
||||||
"github.com/docker/docker/pkg/nat"
|
"github.com/docker/docker/pkg/nat"
|
||||||
|
"github.com/docker/docker/pkg/signal"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/docker/pkg/sysinfo"
|
"github.com/docker/docker/pkg/sysinfo"
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
|
@ -760,10 +761,40 @@ func (daemon *Daemon) Shutdown() error {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer group.Done()
|
defer group.Done()
|
||||||
|
// TODO(windows): Handle docker restart with paused containers
|
||||||
|
if c.IsPaused() {
|
||||||
|
// To terminate a process in freezer cgroup, we should send
|
||||||
|
// SIGTERM to this process then unfreeze it, and the process will
|
||||||
|
// force to terminate immediately.
|
||||||
|
logrus.Debugf("Found container %s is paused, sending SIGTERM before unpause it", c.ID)
|
||||||
|
sig, ok := signal.SignalMap["TERM"]
|
||||||
|
if !ok {
|
||||||
|
logrus.Warnf("System does not support SIGTERM")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := daemon.Kill(c, int(sig)); err != nil {
|
||||||
|
logrus.Debugf("sending SIGTERM to container %s with error: %v", c.ID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := c.Unpause(); err != nil {
|
||||||
|
logrus.Debugf("Failed to unpause container %s with error: %v", c.ID, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := c.WaitStop(10 * time.Second); err != nil {
|
||||||
|
logrus.Debugf("container %s failed to exit in 10 second of SIGTERM, sending SIGKILL to force", c.ID)
|
||||||
|
sig, ok := signal.SignalMap["KILL"]
|
||||||
|
if !ok {
|
||||||
|
logrus.Warnf("System does not support SIGKILL")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
daemon.Kill(c, int(sig))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// If container failed to exit in 10 seconds of SIGTERM, then using the force
|
// If container failed to exit in 10 seconds of SIGTERM, then using the force
|
||||||
if err := c.Stop(10); err != nil {
|
if err := c.Stop(10); err != nil {
|
||||||
logrus.Errorf("Stop container %s with error: %v", c.ID, err)
|
logrus.Errorf("Stop container %s with error: %v", c.ID, err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c.WaitStop(-1 * time.Second)
|
c.WaitStop(-1 * time.Second)
|
||||||
logrus.Debugf("container stopped %s", c.ID)
|
logrus.Debugf("container stopped %s", c.ID)
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -1570,3 +1570,41 @@ func (s *DockerDaemonSuite) TestDaemonWideLogConfig(c *check.C) {
|
||||||
c.Fatalf("Unexpected log-opt: %s, expected map[max-size:1k]", cfg)
|
c.Fatalf("Unexpected log-opt: %s, expected map[max-size:1k]", cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerDaemonSuite) TestDaemonRestartWithPausedContainer(c *check.C) {
|
||||||
|
if err := s.d.StartWithBusybox(); err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
if out, err := s.d.Cmd("run", "-i", "-d", "--name", "test", "busybox", "top"); err != nil {
|
||||||
|
c.Fatal(err, out)
|
||||||
|
}
|
||||||
|
if out, err := s.d.Cmd("pause", "test"); err != nil {
|
||||||
|
c.Fatal(err, out)
|
||||||
|
}
|
||||||
|
if err := s.d.Restart(); err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
errchan := make(chan error)
|
||||||
|
go func() {
|
||||||
|
out, err := s.d.Cmd("start", "test")
|
||||||
|
if err != nil {
|
||||||
|
errchan <- fmt.Errorf("%v:\n%s", err, out)
|
||||||
|
}
|
||||||
|
name := strings.TrimSpace(out)
|
||||||
|
if name != "test" {
|
||||||
|
errchan <- fmt.Errorf("Paused container start error on docker daemon restart, expected 'test' but got '%s'", name)
|
||||||
|
}
|
||||||
|
close(errchan)
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
c.Fatal("Waiting on start a container timed out")
|
||||||
|
case err := <-errchan:
|
||||||
|
if err != nil {
|
||||||
|
c.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue