diff --git a/containerd/main.go b/containerd/main.go index 635c089..531dfe5 100644 --- a/containerd/main.go +++ b/containerd/main.go @@ -134,10 +134,7 @@ func daemon(context *cli.Context) error { // setup a standard reaper so that we don't leave any zombies if we are still alive // this is just good practice because we are spawning new processes s := make(chan os.Signal, 2048) - signal.Notify(s, syscall.SIGCHLD, syscall.SIGTERM, syscall.SIGINT) - if err := osutils.SetSubreaper(1); err != nil { - logrus.WithField("error", err).Error("containerd: set subpreaper") - } + signal.Notify(s, syscall.SIGTERM, syscall.SIGINT) sv, err := supervisor.New( context.String("state-dir"), context.String("runtime"), @@ -169,10 +166,6 @@ func daemon(context *cli.Context) error { } for ss := range s { switch ss { - case syscall.SIGCHLD: - if _, err := osutils.Reap(); err != nil { - logrus.WithField("error", err).Warn("containerd: reap child processes") - } default: logrus.Infof("stopping containerd after receiving %s", ss) server.Stop() diff --git a/runtime/container.go b/runtime/container.go index e935cd0..aced304 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -478,6 +478,7 @@ func (c *container) Exec(pid string, pspec specs.ProcessSpec, s Stdio) (pp Proce } func (c *container) startCmd(pid string, cmd *exec.Cmd, p *process) error { + p.cmd = cmd if err := cmd.Start(); err != nil { if exErr, ok := err.(*exec.Error); ok { if exErr.Err == exec.ErrNotFound || exErr.Err == os.ErrNotExist { @@ -699,6 +700,9 @@ func (c *container) waitForStart(p *process, cmd *exec.Cmd) error { // isAlive checks if the shim that launched the container is still alive func isAlive(cmd *exec.Cmd) (bool, error) { + if _, err := syscall.Wait4(cmd.Process.Pid, nil, syscall.WNOHANG, nil); err == nil { + return true, nil + } if err := syscall.Kill(cmd.Process.Pid, 0); err != nil { if err == syscall.ESRCH { return false, nil diff --git a/runtime/process.go b/runtime/process.go index 4b40b21..a4bedde 100644 --- a/runtime/process.go +++ b/runtime/process.go @@ -6,6 +6,7 @@ import ( "io" "io/ioutil" "os" + "os/exec" "path/filepath" "strconv" "syscall" @@ -39,6 +40,8 @@ type Process interface { SystemPid() int // State returns if the process is running or not State() State + // Wait reaps the shim process if avaliable + Wait() } type processConfig struct { @@ -139,6 +142,7 @@ type process struct { container *container spec specs.ProcessSpec stdio Stdio + cmd *exec.Cmd } func (p *process) ID() string { @@ -219,6 +223,13 @@ func (p *process) getPidFromFile() (int, error) { return i, nil } +// Wait will reap the shim process +func (p *process) Wait() { + if p.cmd != nil { + p.cmd.Wait() + } +} + func getExitPipe(path string) (*os.File, error) { if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { return nil, err diff --git a/supervisor/sort_test.go b/supervisor/sort_test.go index 2fd8680..406523b 100644 --- a/supervisor/sort_test.go +++ b/supervisor/sort_test.go @@ -61,6 +61,10 @@ func (p *testProcess) State() runtime.State { return runtime.Running } +func (p *testProcess) Wait() { + +} + func TestSortProcesses(t *testing.T) { p := []runtime.Process{ &testProcess{"ls"}, diff --git a/supervisor/supervisor.go b/supervisor/supervisor.go index ba80632..012eef2 100644 --- a/supervisor/supervisor.go +++ b/supervisor/supervisor.go @@ -274,6 +274,7 @@ func (s *Supervisor) SendTask(evt Task) { func (s *Supervisor) exitHandler() { for p := range s.monitor.Exits() { + p.Wait() e := &ExitTask{ Process: p, }