Add --all flag to kill

This allows a user to send a signal to all the processes in the
container within a single atomic action to avoid new processes being
forked off before the signal can be sent.

This is basically taking functionality that we already use being
`delete` and exposing it ok the `kill` command by adding a flag.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-11-07 15:22:27 -08:00
parent 99a60237cd
commit e58671e530
9 changed files with 28 additions and 11 deletions

View File

@ -325,6 +325,8 @@ _runc_kill() {
local boolean_options=" local boolean_options="
--help --help
-h -h
--all
-a
" "
case "$prev" in case "$prev" in

View File

@ -14,10 +14,10 @@ import (
) )
func killContainer(container libcontainer.Container) error { func killContainer(container libcontainer.Container) error {
container.Signal(syscall.SIGKILL) container.Signal(syscall.SIGKILL, false)
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(syscall.Signal(0)); err != nil { if err := container.Signal(syscall.Signal(0), false); err != nil {
destroy(container) destroy(container)
return nil return nil
} }

View File

@ -62,6 +62,12 @@ For example, if the container id is "ubuntu01" the following will send a "KILL"
signal to the init process of the "ubuntu01" container: signal to the init process of the "ubuntu01" container:
# runc kill ubuntu01 KILL`, # runc kill ubuntu01 KILL`,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "send the specified signal to all processes inside the container",
},
},
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
container, err := getContainer(context) container, err := getContainer(context)
if err != nil { if err != nil {
@ -77,7 +83,7 @@ signal to the init process of the "ubuntu01" container:
if err != nil { if err != nil {
return err return err
} }
if err := container.Signal(signal); err != nil { if err := container.Signal(signal, context.Bool("all")); err != nil {
return err return err
} }
return nil return nil

View File

@ -145,9 +145,12 @@ type BaseContainer interface {
// Signal sends the provided signal code to the container's initial process. // Signal sends the provided signal code to the container's initial process.
// //
// If all is specified the signal is sent to all processes in the container
// including the initial process.
//
// errors: // errors:
// SystemError - System error. // SystemError - System error.
Signal(s os.Signal) error Signal(s os.Signal, all bool) error
// Exec signals the container to exec the users process at the end of the init. // Exec signals the container to exec the users process at the end of the init.
// //

View File

@ -282,7 +282,10 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
return nil return nil
} }
func (c *linuxContainer) Signal(s os.Signal) error { func (c *linuxContainer) Signal(s os.Signal, all bool) error {
if all {
return signalAllProcesses(c.cgroupManager, s)
}
if err := c.initProcess.signal(s); err != nil { if err := c.initProcess.signal(s); err != nil {
return newSystemErrorWithCause(err, "signaling init process") return newSystemErrorWithCause(err, "signaling init process")
} }

View File

@ -334,10 +334,10 @@ func setOomScoreAdj(oomScoreAdj int, pid int) error {
return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0600) return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0600)
} }
// killCgroupProcesses freezes then iterates over all the processes inside the // signalAllProcesses freezes then iterates over all the processes inside the
// manager's cgroups sending a SIGKILL to each process then waiting for them to // manager's cgroups sending a SIGKILL to each process then waiting for them to
// exit. // exit.
func killCgroupProcesses(m cgroups.Manager) error { func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
var procs []*os.Process var procs []*os.Process
if err := m.Freeze(configs.Frozen); err != nil { if err := m.Freeze(configs.Frozen); err != nil {
logrus.Warn(err) logrus.Warn(err)
@ -354,7 +354,7 @@ func killCgroupProcesses(m cgroups.Manager) error {
continue continue
} }
procs = append(procs, p) procs = append(procs, p)
if err := p.Kill(); err != nil { if err := p.Signal(s); err != nil {
logrus.Warn(err) logrus.Warn(err)
} }
} }

View File

@ -379,7 +379,7 @@ func (p *initProcess) wait() (*os.ProcessState, error) {
} }
// we should kill all processes in cgroup when init is died if we use host PID namespace // we should kill all processes in cgroup when init is died if we use host PID namespace
if p.sharePidns { if p.sharePidns {
killCgroupProcesses(p.manager) signalAllProcesses(p.manager, syscall.SIGKILL)
} }
return p.cmd.ProcessState, nil return p.cmd.ProcessState, nil
} }

View File

@ -39,7 +39,7 @@ type containerState interface {
func destroy(c *linuxContainer) error { func destroy(c *linuxContainer) error {
if !c.config.Namespaces.Contains(configs.NEWPID) { if !c.config.Namespaces.Contains(configs.NEWPID) {
if err := killCgroupProcesses(c.cgroupManager); err != nil { if err := signalAllProcesses(c.cgroupManager, syscall.SIGKILL); err != nil {
logrus.Warn(err) logrus.Warn(err)
} }
} }

View File

@ -2,11 +2,14 @@
runc kill - kill sends the specified signal (default: SIGTERM) to the container's init process runc kill - kill sends the specified signal (default: SIGTERM) to the container's init process
# SYNOPSIS # SYNOPSIS
runc kill <container-id> <signal> runc kill [command options] <container-id> <signal>
Where "<container-id>" is the name for the instance of the container and Where "<container-id>" is the name for the instance of the container and
"<signal>" is the signal to be sent to the init process. "<signal>" is the signal to be sent to the init process.
# OPTIONS
--all, -a send the specified signal to all processes inside the container
# EXAMPLE # EXAMPLE
For example, if the container id is "ubuntu01" the following will send a "KILL" For example, if the container id is "ubuntu01" the following will send a "KILL"