From ca6ae2e64bb56710342e83506b00d539eb44f182 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 14 Mar 2016 13:57:28 -0700 Subject: [PATCH] Remove container on load if it exited If the shim gets sigkilled while containerd is down we need to be able to remove the container correctly so that it does not stay in a stopped state forever. Signed-off-by: Michael Crosby --- runtime/container.go | 5 ++++- runtime/container_linux.go | 13 +++++-------- runtime/process.go | 14 ++++++++++++++ supervisor/supervisor.go | 6 +++--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/runtime/container.go b/runtime/container.go index 3920523a0..d61aa1f7c 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "os" + "os/exec" "path/filepath" "github.com/Sirupsen/logrus" @@ -200,7 +201,9 @@ func (c *container) readSpec() (*specs.PlatformSpec, error) { } func (c *container) Delete() error { - return os.RemoveAll(filepath.Join(c.root, c.id)) + err := os.RemoveAll(filepath.Join(c.root, c.id)) + exec.Command(c.runtime, "delete", c.id).Run() + return err } func (c *container) Processes() ([]Process, error) { diff --git a/runtime/container_linux.go b/runtime/container_linux.go index 473fb63c1..40897fa45 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -38,14 +38,10 @@ func getRootIDs(s *specs.PlatformSpec) (int, int, error) { func (c *container) State() State { proc := c.processes["init"] - if proc == nil || proc.pid == 0 { + if proc == nil { return Stopped } - err := syscall.Kill(proc.pid, 0) - if err != nil && err == syscall.ESRCH { - return Stopped - } - return Running + return proc.State() } func (c *container) Runtime() string { @@ -53,11 +49,11 @@ func (c *container) Runtime() string { } func (c *container) Pause() error { - return exec.Command("runc", "pause", c.id).Run() + return exec.Command(c.runtime, "pause", c.id).Run() } func (c *container) Resume() error { - return exec.Command("runc", "resume", c.id).Run() + return exec.Command(c.runtime, "resume", c.id).Run() } func (c *container) Checkpoints() ([]Checkpoint, error) { @@ -336,6 +332,7 @@ func waitForStart(p *process, cmd *exec.Cmd) error { return errNoPidFile } +// isAlive checks if the shim that launched the container is still alive func isAlive(cmd *exec.Cmd) (bool, error) { if err := syscall.Kill(cmd.Process.Pid, 0); err != nil { if err == syscall.ESRCH { diff --git a/runtime/process.go b/runtime/process.go index 7f5837873..e571e721b 100644 --- a/runtime/process.go +++ b/runtime/process.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strconv" + "syscall" "github.com/docker/containerd/specs" ) @@ -36,6 +37,8 @@ type Process interface { Stdio() Stdio // SystemPid is the pid on the system SystemPid() int + // State returns if the process is running or not + State() State } type processConfig struct { @@ -178,6 +181,17 @@ func (p *process) Close() error { return p.exitPipe.Close() } +func (p *process) State() State { + if p.pid == 0 { + return Stopped + } + err := syscall.Kill(p.pid, 0) + if err != nil && err == syscall.ESRCH { + return Stopped + } + return Running +} + func (p *process) getPidFromFile() (int, error) { data, err := ioutil.ReadFile(filepath.Join(p.root, "pid")) if err != nil { diff --git a/supervisor/supervisor.go b/supervisor/supervisor.go index f282e4d0d..9fe15d89f 100644 --- a/supervisor/supervisor.go +++ b/supervisor/supervisor.go @@ -272,12 +272,12 @@ func (s *Supervisor) restore() error { logrus.WithField("id", id).Debug("containerd: container restored") var exitedProcesses []runtime.Process for _, p := range processes { - if _, err := p.ExitStatus(); err == nil { - exitedProcesses = append(exitedProcesses, p) - } else { + if p.State() == runtime.Running { if err := s.monitorProcess(p); err != nil { return err } + } else { + exitedProcesses = append(exitedProcesses, p) } } if len(exitedProcesses) > 0 {