runc kill: drop -a option

As of previous commit, this is implied in a particular scenario. In
fact, this is the one and only scenario that justifies the use of -a.

Drop the option from the documentation. For backward compatibility, do
recognize it, and retain the feature of ignoring the "container is
stopped" error when set.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2023-05-12 12:55:17 -07:00
parent 9583b3d1c2
commit f8ad20f500
6 changed files with 27 additions and 38 deletions

View File

@@ -14,10 +14,10 @@ import (
) )
func killContainer(container *libcontainer.Container) error { func killContainer(container *libcontainer.Container) error {
_ = container.Signal(unix.SIGKILL, false) _ = container.Signal(unix.SIGKILL)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
if err := container.Signal(unix.Signal(0), false); err != nil { if err := container.Signal(unix.Signal(0)); err != nil {
destroy(container) destroy(container)
return nil return nil
} }

13
kill.go
View File

@@ -1,10 +1,12 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
"github.com/opencontainers/runc/libcontainer"
"github.com/urfave/cli" "github.com/urfave/cli"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@@ -24,8 +26,9 @@ signal to the init process of the "ubuntu01" container:
# runc kill ubuntu01 KILL`, # runc kill ubuntu01 KILL`,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.BoolFlag{ cli.BoolFlag{
Name: "all, a", Name: "all, a",
Usage: "send the specified signal to all processes inside the container", Usage: "(obsoleted, do not use)",
Hidden: true,
}, },
}, },
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
@@ -49,7 +52,11 @@ signal to the init process of the "ubuntu01" container:
if err != nil { if err != nil {
return err return err
} }
return container.Signal(signal, context.Bool("all")) err = container.Signal(signal)
if errors.Is(err, libcontainer.ErrNotRunning) && context.Bool("all") {
err = nil
}
return err
}, },
} }

View File

@@ -357,32 +357,18 @@ func (c *Container) start(process *Process) (retErr error) {
return nil return nil
} }
// Signal sends a specified signal to container's init, or, if all is true, // Signal sends a specified signal to container's init.
// to all container's processes (as determined by container's cgroup).
// //
// Note all=true is implied when s is SIGKILL and the container does not have // When s is SIGKILL and the container does not have its own PID namespace, all
// its own PID namespace. In this scenario, the libcontainer user may be required // the container's processes are killed. In this scenario, the libcontainer
// to implement a proper child reaper. // user may be required to implement a proper child reaper.
func (c *Container) Signal(s os.Signal, all bool) error { func (c *Container) Signal(s os.Signal) error {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
status, err := c.currentStatus() status, err := c.currentStatus()
if err != nil { if err != nil {
return err return err
} }
if all {
sig, ok := s.(unix.Signal)
if !ok {
return errors.New("unsupported signal type")
}
if status == Stopped && !c.cgroupManager.Exists() {
// Avoid calling signalAllProcesses which may print
// a warning trying to freeze a non-existing cgroup.
return nil
}
return c.ignoreCgroupError(signalAllProcesses(c.cgroupManager, sig))
}
// To avoid a PID reuse attack, don't kill non-running container. // To avoid a PID reuse attack, don't kill non-running container.
switch status { switch status {
case Running, Created, Paused: case Running, Created, Paused:

View File

@@ -1400,7 +1400,7 @@ func testPidnsInitKill(t *testing.T, config *configs.Config) {
ok(t, err) ok(t, err)
// Kill the container. // Kill the container.
err = container.Signal(syscall.SIGKILL, false) err = container.Signal(syscall.SIGKILL)
ok(t, err) ok(t, err)
_, err = process1.Wait() _, err = process1.Wait()
if err == nil { if err == nil {

View File

@@ -4,7 +4,7 @@
**runc-kill** - send a specified signal to container **runc-kill** - send a specified signal to container
# SYNOPSIS # SYNOPSIS
**runc kill** [**--all**|**-a**] _container-id_ [_signal_] **runc kill** _container-id_ [_signal_]
# DESCRIPTION # DESCRIPTION
@@ -15,15 +15,6 @@ A different signal can be specified either by its name (with or without the
**SIG** prefix), or its numeric value. Use **kill**(1) with **-l** option **SIG** prefix), or its numeric value. Use **kill**(1) with **-l** option
to list available signals. to list available signals.
# OPTIONS
**--all**|**-a**
: Send the signal to all processes inside the container, rather than
the container's init only. This option is implied when the _signal_ is **KILL**
and the container does not have its own PID namespace.
: When this option is set, no error is returned if the container is stopped
or does not exist.
# EXAMPLES # EXAMPLES
The following will send a **KILL** signal to the init process of the The following will send a **KILL** signal to the init process of the

View File

@@ -22,7 +22,12 @@ function teardown() {
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
wait_for_container 10 1 test_busybox stopped wait_for_container 10 1 test_busybox stopped
# we should ensure kill work after the container stopped # Check that kill errors on a stopped container.
runc kill test_busybox 0
[ "$status" -ne 0 ]
[[ "$output" == *"container not running"* ]]
# Check that -a (now obsoleted) makes kill return no error for a stopped container.
runc kill -a test_busybox 0 runc kill -a test_busybox 0
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
@@ -31,7 +36,7 @@ function teardown() {
} }
# This is roughly the same as TestPIDHostInitProcessWait in libcontainer/integration. # This is roughly the same as TestPIDHostInitProcessWait in libcontainer/integration.
@test "kill --all KILL [host pidns]" { @test "kill KILL [host pidns]" {
# kill -a currently requires cgroup freezer. # kill -a currently requires cgroup freezer.
requires cgroups_freezer requires cgroups_freezer
@@ -65,7 +70,7 @@ function teardown() {
kill -0 "$p" kill -0 "$p"
done done
runc kill -a test_busybox KILL runc kill test_busybox KILL
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
wait_for_container 10 1 test_busybox stopped wait_for_container 10 1 test_busybox stopped