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="
|
||||
--help
|
||||
-h
|
||||
--all
|
||||
-a
|
||||
"
|
||||
|
||||
case "$prev" in
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
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:
|
||||
|
||||
# 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
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue