diff options
author | Fabricio Voznika <fvoznika@google.com> | 2018-09-28 12:20:56 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-28 12:22:21 -0700 |
commit | 2496d9b4b6343154525f73e9583a4a60bebcfa30 (patch) | |
tree | 3ac4c3c1ea5813a2c3a32ea8b4d05e01db0d99d1 /runsc/container/container.go | |
parent | fb65b0b471621b430969fe1c3009bee68209bf67 (diff) |
Make runsc kill and delete more conformant to the "spec"
PiperOrigin-RevId: 214976251
Change-Id: I631348c3886f41f63d0e77e7c4f21b3ede2ab521
Diffstat (limited to 'runsc/container/container.go')
-rw-r--r-- | runsc/container/container.go | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/runsc/container/container.go b/runsc/container/container.go index 44b7dad8a..e65800b8d 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -72,6 +72,21 @@ func validateID(id string) error { // Containers must write their metadata files after any change to their internal // states. The entire container directory is deleted when the container is // destroyed. +// +// When the container is stopped, all processes that belong to the container +// must be stopped before Destroy() returns. containerd makes roughly the +// following calls to stop a container: +// - First it attempts to kill the container process with +// 'runsc kill SIGTERM'. After some time, it escalates to SIGKILL. In a +// separate thread, it's waiting on the container. As soon as the wait +// returns, it moves on to the next step: +// - It calls 'runsc kill --all SIGKILL' to stop every process that belongs to +// the container. 'kill --all SIGKILL' waits for all processes before +// returning. +// - Containerd waits for stdin, stdout and stderr to drain and be closed. +// - It calls 'runsc delete'. runc implementation kills --all SIGKILL once +// again just to be sure, waits, and then proceeds with remaining teardown. +// type Container struct { // ID is the container ID. ID string `json:"id"` @@ -451,7 +466,8 @@ func (c *Container) WaitPID(pid int32, clearStatus bool) (syscall.WaitStatus, er return c.Sandbox.WaitPID(c.ID, pid, clearStatus) } -// Signal sends the signal to the container. +// Signal sends the signal to the container. If all is true and signal is +// SIGKILL, then waits for all processes to exit before returning. // Signal returns an error if the container is already stopped. // TODO: Distinguish different error types. func (c *Container) Signal(sig syscall.Signal, all bool) error { @@ -534,8 +550,8 @@ func (c *Container) Processes() ([]*control.Process, error) { return c.Sandbox.Processes(c.ID) } -// Destroy frees all resources associated with the container. It fails fast and -// is idempotent. +// Destroy stops all processes and frees all resources associated with the +// container. It fails fast and is idempotent. func (c *Container) Destroy() error { log.Debugf("Destroy container %q", c.ID) |