Skip to content

Commit 133885a

Browse files
committed
libct: move killing logic to kill
By default, the container has its own PID namespace, and killing (with SIGKILL) its init process from the parent PID namespace also kills all the other processes. Obviously, it does not work that way when the container is sharing its PID namespace with the host or another container, since init is no longer special (it's not PID 1). In this case, killing container's init will result in a bunch of other processes left running (and thus the inability to remove the cgroup). The solution to the above problem is killing all the container processes, not just init. The problem with the current implementation is, the killing logic is implemented in libcontainer's initProcess.wait (rather than kill), and therefore was only available to libcontainer users, but not the runc kill command (which does not call wait as it's not a parent of container's init). To untangle this, the patch moves killing all processes from initProcess.wait to initProcess.kill, and documents the new behavior. In essence, this also makes `runc kill` to automatically kill all container processes when the container does not have its own PID namespace. Document that as well. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 4a1c920 commit 133885a

File tree

4 files changed

+9
-14
lines changed

4 files changed

+9
-14
lines changed

libcontainer/container_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ func (c *Container) start(process *Process) (retErr error) {
360360
// Signal sends a specified signal to container's init, or, if all is true,
361361
// true, to all container's proceses (as determined by container's cgroup).
362362
//
363-
// Setting all=true is useful when s is SIGKILL and the container does not have
363+
// Note all=true is implied when s is SIGKILL and the container does not have
364364
// its own PID namespace. In this scenario, the libcontainer user may be required
365365
// to implement a proper child reaper.
366366
func (c *Container) Signal(s os.Signal, all bool) error {

libcontainer/process_linux.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,6 @@ func (p *initProcess) start() (retErr error) {
616616

617617
func (p *initProcess) wait() (*os.ProcessState, error) {
618618
err := p.cmd.Wait()
619-
// we should kill all processes in cgroup when init is died if we use host PID namespace
620-
if p.sharePidns {
621-
_ = signalAllProcesses(p.manager, unix.SIGKILL)
622-
}
623619
return p.cmd.ProcessState, err
624620
}
625621

@@ -678,6 +674,12 @@ func (p *initProcess) signal(sig os.Signal) error {
678674
if !ok {
679675
return errors.New("os: unsupported signal type")
680676
}
677+
// When a container has its own pidns, init pid is 1, and killing
678+
// init with SIGKILL will kill all processes in its PID namespace.
679+
// Otherwise, we should kill all pids to avoid leftover processes.
680+
if p.sharePidns && s == unix.SIGKILL {
681+
return signalAllProcesses(p.manager, unix.SIGKILL)
682+
}
681683
return unix.Kill(p.pid(), s)
682684
}
683685

libcontainer/state_linux.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/opencontainers/runc/libcontainer/configs"
99
"github.com/opencontainers/runtime-spec/specs-go"
10-
"github.com/sirupsen/logrus"
1110
"golang.org/x/sys/unix"
1211
)
1312

@@ -36,12 +35,6 @@ type containerState interface {
3635
}
3736

3837
func destroy(c *Container) error {
39-
if !c.config.Namespaces.Contains(configs.NEWPID) ||
40-
c.config.Namespaces.PathOf(configs.NEWPID) != "" {
41-
if err := signalAllProcesses(c.cgroupManager, unix.SIGKILL); err != nil {
42-
logrus.Warn(err)
43-
}
44-
}
4538
err := c.cgroupManager.Destroy()
4639
if c.intelRdtManager != nil {
4740
if ierr := c.intelRdtManager.Destroy(); err == nil {

man/runc-kill.8.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ to list available signals.
1818
# OPTIONS
1919
**--all**|**-a**
2020
: Send the signal to all processes inside the container, rather than
21-
the container's init only. This option is useful when the container does not
22-
have its own PID namespace.
21+
the container's init only. This option is implied when the _signal_ is **KILL**
22+
and the container does not have its own PID namespace.
2323

2424
: When this option is set, no error is returned if the container is stopped
2525
or does not exist.

0 commit comments

Comments
 (0)