From 031dbdddebd64d85336d3e6b251f992013c460b2 Mon Sep 17 00:00:00 2001 From: Andrea Luzzardi Date: Mon, 21 Jan 2013 18:03:23 -0800 Subject: [PATCH 1/2] Docker: Clean shutdown of containers. Stop() will send a SIGTERM to the init process of the container and give it 10 seconds to shutdown properly. After the timeout is reached, the process will be force killed (SIGKILL). Also available is Kill() which kills the process on the spot. Upstream-commit: 24dac22892cc3c8f34e90222f64b87d750b5025e Component: engine --- components/engine/container.go | 71 +++++++++++++++++++++++++---- components/engine/container_test.go | 10 ++-- 2 files changed, 67 insertions(+), 14 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index 77fd7c0fec..d89f99e474 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -5,10 +5,12 @@ import ( "errors" "io" "io/ioutil" + "log" "os" "os/exec" "path" "syscall" + "time" ) type Container struct { @@ -176,22 +178,57 @@ func (container *Container) StderrPipe() (io.ReadCloser, error) { func (container *Container) monitor() { container.cmd.Wait() + exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() + + // Cleanup container container.stdout.Close() container.stderr.Close() - container.State.setStopped(container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()) + if err := container.Filesystem.Umount(); err != nil { + log.Printf("%v: Failed to umount filesystem: %v", container.Name, err) + } + + // Report status back + container.State.setStopped(exitCode) +} + +func (container *Container) kill() error { + // This will cause the main container process to receive a SIGKILL + if err := exec.Command("/usr/bin/lxc-stop", "-n", container.Name).Run(); err != nil { + return err + } + + // Wait for the container to be actually stopped + if err := exec.Command("/usr/bin/lxc-wait", "-n", container.Name, "-s", "STOPPED").Run(); err != nil { + return err + } + return nil +} + +func (container *Container) Kill() error { + if !container.State.Running { + return nil + } + return container.kill() } func (container *Container) Stop() error { - if container.State.Running { - if err := exec.Command("/usr/bin/lxc-stop", "-n", container.Name).Run(); err != nil { - return err - } - //FIXME: We should lxc-wait for the container to stop + if !container.State.Running { + return nil } - if err := container.Filesystem.Umount(); err != nil { - // FIXME: Do not abort, probably already umounted? - return nil + // 1. Send a SIGTERM + if err := exec.Command("/usr/bin/lxc-kill", "-n", container.Name, "15").Run(); err != nil { + return err + } + + // 2. Wait for the process to exit on its own + if err := container.WaitTimeout(10 * time.Second); err != nil { + log.Printf("Container %v failed to exit within 10 seconds of SIGTERM", container.Name) + } + + // 3. Force kill + if err := container.kill(); err != nil { + return err } return nil } @@ -201,3 +238,19 @@ func (container *Container) Wait() { container.State.wait() } } + +func (container *Container) WaitTimeout(timeout time.Duration) error { + done := make(chan bool) + go func() { + container.Wait() + done <- true + }() + + select { + case <-time.After(timeout): + return errors.New("Timed Out") + case <-done: + return nil + } + return nil +} diff --git a/components/engine/container_test.go b/components/engine/container_test.go index 650d2a07f9..e348a2b4b0 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -98,15 +98,15 @@ func TestOutput(t *testing.T) { } } -func TestStop(t *testing.T) { +func TestKill(t *testing.T) { docker, err := newTestDocker() if err != nil { t.Fatal(err) } container, err := docker.Create( "stop_test", - "sleep", - []string{"300"}, + "cat", + []string{"/dev/zero"}, []string{"/var/lib/docker/images/ubuntu"}, &Config{}, ) @@ -124,7 +124,7 @@ func TestStop(t *testing.T) { if !container.State.Running { t.Errorf("Container should be running") } - if err := container.Stop(); err != nil { + if err := container.Kill(); err != nil { t.Fatal(err) } if container.State.Running { @@ -135,7 +135,7 @@ func TestStop(t *testing.T) { t.Errorf("Container shouldn't be running") } // Try stopping twice - if err := container.Stop(); err != nil { + if err := container.Kill(); err != nil { t.Fatal(err) } } From 7876504025a8e5229123b5f46269d6423a78e518 Mon Sep 17 00:00:00 2001 From: Andrea Luzzardi Date: Mon, 21 Jan 2013 18:06:31 -0800 Subject: [PATCH 2/2] Removed bogus .swp file Upstream-commit: 13cd4650fdc636862bee73e6de5374205f3e6dd1 Component: engine --- components/engine/dockerd/.dockerd.go.swp | Bin 28672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 components/engine/dockerd/.dockerd.go.swp diff --git a/components/engine/dockerd/.dockerd.go.swp b/components/engine/dockerd/.dockerd.go.swp deleted file mode 100644 index 5bb84f54fd048b94e749ba04f63f70afc339e2ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 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