From 0581e02feec97170b3974ac1bd2c4aa5ea2c9693 Mon Sep 17 00:00:00 2001 From: yangshukui Date: Wed, 26 Apr 2017 13:56:49 +0800 Subject: [PATCH] Kill shim on restore if the bundle dir is missing Some anomalies due to the reboot of containerd(killed by docker daemon), can lead to docker-containerd-shim residue and shim process will not exit except you kill it manually. Signed-off-by: yangshukui --- containerd-shim/process.go | 7 ++++--- containerd-shim/process_linux.go | 11 ++--------- containerd-shim/process_solaris.go | 5 ----- osutils/pdeathsig_linux.go | 15 +++++++++++++++ osutils/pdeathsig_solaris.go | 8 ++++++++ runtime/container.go | 11 +++++++++++ runtime/process.go | 16 ++++++++++++++++ 7 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 osutils/pdeathsig_linux.go create mode 100644 osutils/pdeathsig_solaris.go diff --git a/containerd-shim/process.go b/containerd-shim/process.go index f94ae5d..d7c6724 100644 --- a/containerd-shim/process.go +++ b/containerd-shim/process.go @@ -15,6 +15,7 @@ import ( "syscall" "time" + "github.com/containerd/containerd/osutils" "github.com/containerd/containerd/specs" ) @@ -177,8 +178,8 @@ func (p *process) create() error { cmd.Stdin = p.stdio.stdin cmd.Stdout = p.stdio.stdout cmd.Stderr = p.stdio.stderr - // Call out to setPDeathSig to set SysProcAttr as elements are platform specific - cmd.SysProcAttr = setPDeathSig() + // Call out to SetPDeathSig to set SysProcAttr as elements are platform specific + cmd.SysProcAttr = osutils.SetPDeathSig() if err := cmd.Start(); err != nil { if exErr, ok := err.(*exec.Error); ok { @@ -220,7 +221,7 @@ func (p *process) pid() int { func (p *process) delete() error { if !p.state.Exec { cmd := exec.Command(p.runtime, append(p.state.RuntimeArgs, "delete", p.id)...) - cmd.SysProcAttr = setPDeathSig() + cmd.SysProcAttr = osutils.SetPDeathSig() out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("%s: %v", out, err) diff --git a/containerd-shim/process_linux.go b/containerd-shim/process_linux.go index 69bc942..a82df59 100644 --- a/containerd-shim/process_linux.go +++ b/containerd-shim/process_linux.go @@ -9,18 +9,11 @@ import ( "syscall" "time" + "github.com/containerd/containerd/osutils" "github.com/tonistiigi/fifo" "golang.org/x/net/context" ) -// setPDeathSig sets the parent death signal to SIGKILL so that if the -// shim dies the container process also dies. -func setPDeathSig() *syscall.SysProcAttr { - return &syscall.SysProcAttr{ - Pdeathsig: syscall.SIGKILL, - } -} - // openIO opens the pre-created fifo's for use with the container // in RDWR so that they remain open if the other side stops listening func (p *process) openIO() error { @@ -141,7 +134,7 @@ func (p *process) Wait() { func (p *process) killAll() error { if !p.state.Exec { cmd := exec.Command(p.runtime, append(p.state.RuntimeArgs, "kill", "--all", p.id, "SIGKILL")...) - cmd.SysProcAttr = setPDeathSig() + cmd.SysProcAttr = osutils.SetPDeathSig() out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("%s: %v", out, err) diff --git a/containerd-shim/process_solaris.go b/containerd-shim/process_solaris.go index 57da661..8b7fe3a 100644 --- a/containerd-shim/process_solaris.go +++ b/containerd-shim/process_solaris.go @@ -8,11 +8,6 @@ import ( "syscall" ) -// setPDeathSig is a no-op on Solaris as Pdeathsig is not defined. -func setPDeathSig() *syscall.SysProcAttr { - return nil -} - // TODO: Update to using fifo's package in openIO. Need to // 1. Merge and vendor changes in the package to use sys/unix. // 2. Figure out why context.Background is timing out. diff --git a/osutils/pdeathsig_linux.go b/osutils/pdeathsig_linux.go new file mode 100644 index 0000000..5310f2e --- /dev/null +++ b/osutils/pdeathsig_linux.go @@ -0,0 +1,15 @@ +// +build !solaris + +package osutils + +import ( + "syscall" +) + +// SetPDeathSig sets the parent death signal to SIGKILL so that if the +// shim dies the container process also dies. +func SetPDeathSig() *syscall.SysProcAttr { + return &syscall.SysProcAttr{ + Pdeathsig: syscall.SIGKILL, + } +} diff --git a/osutils/pdeathsig_solaris.go b/osutils/pdeathsig_solaris.go new file mode 100644 index 0000000..512e24b --- /dev/null +++ b/osutils/pdeathsig_solaris.go @@ -0,0 +1,8 @@ +// +build solaris + +package osutils + +// SetPDeathSig is a no-op on Solaris as Pdeathsig is not defined. +func SetPDeathSig() *syscall.SysProcAttr { + return nil +} diff --git a/runtime/container.go b/runtime/container.go index cb86efa..7b804b7 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -193,6 +193,17 @@ func Load(root, id, shimName string, timeout time.Duration) (Container, error) { } c.processes[pid] = p } + + _, err = os.Stat(c.bundle) + if err != nil && !os.IsExist(err) { + for key, p := range c.processes { + if key == InitProcessID { + p.Delete() + break + } + } + return nil, fmt.Errorf("bundle dir %s don't exist", c.bundle) + } return c, nil } diff --git a/runtime/process.go b/runtime/process.go index 7ce32f2..22d0192 100644 --- a/runtime/process.go +++ b/runtime/process.go @@ -15,6 +15,7 @@ import ( "time" "github.com/Sirupsen/logrus" + "github.com/containerd/containerd/osutils" "github.com/containerd/containerd/specs" "golang.org/x/sys/unix" ) @@ -458,3 +459,18 @@ func (p *process) Start() error { } return nil } + +// Delete delete any resources held by the container +func (p *process) Delete() error { + var ( + args = append(p.container.runtimeArgs, "delete", "-f", p.container.id) + cmd = exec.Command(p.container.runtime, args...) + ) + + cmd.SysProcAttr = osutils.SetPDeathSig() + out, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("%s: %v", out, err) + } + return nil +}