mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Kill all processes in cgroup even if init process Wait fails
If the cgroup's init process doesn't complete successfully, Wait returns a non-nil error. We should still kill all the process in the cgroup if process namespace is shared. Otherwise, it may result in process leak. Fixes #2632 Signed-off-by: Chaitanya Bandi <kbandi@cs.stonybrook.edu>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
@@ -1660,6 +1661,59 @@ func TestPIDHost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPIDHostInitProcessWait(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
rootfs, err := newRootfs()
|
||||
ok(t, err)
|
||||
defer remove(rootfs)
|
||||
|
||||
pidns := "/proc/1/ns/pid"
|
||||
|
||||
// Run a container with two long-running processes.
|
||||
config := newTemplateConfig(rootfs)
|
||||
config.Namespaces.Add(configs.NEWPID, pidns)
|
||||
container, err := newContainerWithName("test", config)
|
||||
ok(t, err)
|
||||
defer func() {
|
||||
_ = container.Destroy()
|
||||
}()
|
||||
|
||||
process1 := &libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"sleep", "100"},
|
||||
Env: standardEnvironment,
|
||||
Init: true,
|
||||
}
|
||||
err = container.Run(process1)
|
||||
ok(t, err)
|
||||
|
||||
process2 := &libcontainer.Process{
|
||||
Cwd: "/",
|
||||
Args: []string{"sleep", "100"},
|
||||
Env: standardEnvironment,
|
||||
Init: false,
|
||||
}
|
||||
err = container.Run(process2)
|
||||
ok(t, err)
|
||||
|
||||
// Kill the init process and Wait for it.
|
||||
err = process1.Signal(syscall.SIGKILL)
|
||||
ok(t, err)
|
||||
_, err = process1.Wait()
|
||||
if err == nil {
|
||||
t.Fatal("expected Wait to indicate failure")
|
||||
}
|
||||
|
||||
// The non-init process must've been killed.
|
||||
err = process2.Signal(syscall.Signal(0))
|
||||
if err == nil || err.Error() != "no such process" {
|
||||
t.Fatalf("expected process to have been killed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitJoinPID(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
|
||||
@@ -511,14 +511,11 @@ func (p *initProcess) start() (retErr error) {
|
||||
|
||||
func (p *initProcess) wait() (*os.ProcessState, error) {
|
||||
err := p.cmd.Wait()
|
||||
if err != nil {
|
||||
return p.cmd.ProcessState, err
|
||||
}
|
||||
// we should kill all processes in cgroup when init is died if we use host PID namespace
|
||||
if p.sharePidns {
|
||||
signalAllProcesses(p.manager, unix.SIGKILL)
|
||||
}
|
||||
return p.cmd.ProcessState, nil
|
||||
return p.cmd.ProcessState, err
|
||||
}
|
||||
|
||||
func (p *initProcess) terminate() error {
|
||||
|
||||
Reference in New Issue
Block a user