Skip to content

Commit

Permalink
runc delete, container.Destroy: kill all processes
Browse files Browse the repository at this point in the history
(For a container with no private PID namespace, that is).

When runc delete (or container.Destroy) is called on a stopped
container without private PID namespace and there are processes
in its cgroup, kill those.

Add a test case.

Signed-off-by: Kir Kolyshkin <[email protected]>
  • Loading branch information
kolyshkin committed Nov 10, 2023
1 parent 9160468 commit 7e571fd
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
11 changes: 11 additions & 0 deletions libcontainer/state_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ type containerState interface {
}

func destroy(c *Container) error {
// Usually, when a container init is gone, all other processes in its
// cgroup are killed by the kernel. This is not the case for a shared
// PID namespace container, which may have some processes left after
// its init is killed or exited.
//
// As the container without init process running is considered stopped,
// and destroy is supposed to remove all the container resources, we need
// to kill those processes here.
if !c.config.Namespaces.IsPrivate(configs.NEWPID) {
_ = signalAllProcesses(c.cgroupManager, unix.SIGKILL)
}
err := c.cgroupManager.Destroy()
if c.intelRdtManager != nil {
if ierr := c.intelRdtManager.Destroy(); err == nil {
Expand Down
21 changes: 18 additions & 3 deletions tests/integration/delete.bats
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,19 @@ function teardown() {
[ "$status" -eq 0 ]
}

# Issue 4047, case "runc delete -f".
# See also: "kill KILL [host pidns + init gone]" test in kill.bats.
# Issue 4047, case "runc delete".
@test "runc delete [host pidns + init gone]" {
test_runc_delete_host_pidns
}

# Issue 4047, case "runc delete --force" (different code path).
# shellcheck disable=SC2030
@test "runc delete --force [host pidns + init gone]" {
test_runc_delete_host_pidns --force
}

# See also: "kill KILL [host pidns + init gone]" test in kill.bats.
function test_runc_delete_host_pidns() {
requires cgroups_freezer

update_config ' .linux.namespaces -= [{"type": "pid"}]'
Expand All @@ -91,6 +101,7 @@ function teardown() {
fi

runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
# shellcheck disable=SC2031
[ "$status" -eq 0 ]
cgpath=$(get_cgroup_path "pids")
init_pid=$(cat "$cgpath"/cgroup.procs)
Expand All @@ -113,10 +124,14 @@ function teardown() {
kill -0 "$p"
done

runc delete -f test_busybox
# Must kill those processes and remove container.
# shellcheck disable=SC2031
runc delete "$@" test_busybox
# shellcheck disable=SC2031
[ "$status" -eq 0 ]

runc state test_busybox
# shellcheck disable=SC2031
[ "$status" -ne 0 ] # "Container does not exist"

# Make sure all processes are gone.
Expand Down

0 comments on commit 7e571fd

Please sign in to comment.