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:
parent
99a60237cd
commit
e58671e530
|
@ -325,6 +325,8 @@ _runc_kill() {
|
||||||
local boolean_options="
|
local boolean_options="
|
||||||
--help
|
--help
|
||||||
-h
|
-h
|
||||||
|
--all
|
||||||
|
-a
|
||||||
"
|
"
|
||||||
|
|
||||||
case "$prev" in
|
case "$prev" in
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
8
kill.go
8
kill.go
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
//
|
//
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue