diff options
Diffstat (limited to 'runsc/container/container.go')
-rw-r--r-- | runsc/container/container.go | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/runsc/container/container.go b/runsc/container/container.go index a3454eb8f..a4a3ed56d 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -520,24 +520,35 @@ func (c *Container) Destroy() error { c.Status = Stopped c.Sandbox = nil + if err := c.destroyGofer(); err != nil { + return fmt.Errorf("error destroying gofer: %v", err) + } + + if err := os.RemoveAll(c.Root); err != nil && !os.IsNotExist(err) { + return fmt.Errorf("error deleting container root directory %q: %v", c.Root, err) + } + + return nil +} + +func (c *Container) destroyGofer() error { if c.GoferPid != 0 { log.Debugf("Killing gofer for container %q, PID: %d", c.ID, c.GoferPid) if err := syscall.Kill(c.GoferPid, syscall.SIGKILL); err != nil { log.Warningf("error sending signal %d to pid %d: %v", syscall.SIGKILL, c.GoferPid, err) - } else { - c.GoferPid = 0 } } - if err := destroyFS(c.Spec); err != nil { - return fmt.Errorf("error destroying container fs: %v", err) - } - - if err := os.RemoveAll(c.Root); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("error deleting container root directory %q: %v", c.Root, err) + // Gofer process may take some time to teardown. Retry in case of failure. + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + b := backoff.WithContext(backoff.NewConstantBackOff(100*time.Millisecond), ctx) + err := backoff.Retry(func() error { return destroyFS(c.Spec) }, b) + if err == nil { + // Success! + c.GoferPid = 0 } - - return nil + return err } // IsRunning returns true if the sandbox or gofer process is running. @@ -549,8 +560,9 @@ func (c *Container) IsRunning() bool { // Send a signal 0 to the gofer process. if err := syscall.Kill(c.GoferPid, 0); err == nil { log.Warningf("Found orphan gofer process, pid: %d", c.GoferPid) - // Attempt to kill gofer if it's orphan. - syscall.Kill(c.GoferPid, syscall.SIGKILL) + if err := c.destroyGofer(); err != nil { + log.Warningf("Error destroying gofer: %v", err) + } // Don't wait for gofer to die. Return 'running' and hope gofer is dead // next time around. |