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="
--help
-h
--all
-a
"
case "$prev" in

View File

@ -14,10 +14,10 @@ import (
)
func killContainer(container libcontainer.Container) error {
container.Signal(syscall.SIGKILL)
container.Signal(syscall.SIGKILL, false)
for i := 0; i < 100; i++ {
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)
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:
# 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 {
container, err := getContainer(context)
if err != nil {
@ -77,7 +83,7 @@ signal to the init process of the "ubuntu01" container:
if err != nil {
return err
}
if err := container.Signal(signal); err != nil {
if err := container.Signal(signal, context.Bool("all")); err != nil {
return err
}
return nil

View File

@ -145,9 +145,12 @@ type BaseContainer interface {
// 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:
// 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.
//

View File

@ -282,7 +282,10 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
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 {
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)
}
// 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
// exit.
func killCgroupProcesses(m cgroups.Manager) error {
func signalAllProcesses(m cgroups.Manager, s os.Signal) error {
var procs []*os.Process
if err := m.Freeze(configs.Frozen); err != nil {
logrus.Warn(err)
@ -354,7 +354,7 @@ func killCgroupProcesses(m cgroups.Manager) error {
continue
}
procs = append(procs, p)
if err := p.Kill(); err != nil {
if err := p.Signal(s); err != nil {
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
if p.sharePidns {
killCgroupProcesses(p.manager)
signalAllProcesses(p.manager, syscall.SIGKILL)
}
return p.cmd.ProcessState, nil
}

View File

@ -39,7 +39,7 @@ type containerState interface {
func destroy(c *linuxContainer) error {
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)
}
}

View File

@ -2,11 +2,14 @@
runc kill - kill sends the specified signal (default: SIGTERM) to the container's init process
# 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
"<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
For example, if the container id is "ubuntu01" the following will send a "KILL"