From 12aef686af3f37029e619602286f00a40144c52d Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Wed, 5 Sep 2018 14:28:52 -0700 Subject: Enabled bind mounts in sub-containers With multi-gofers, bind mounts in sub-containers should just work. Removed restrictions and added test. There are also a few cleanups along the way, e.g. retry unmounting in case cleanup races with gofer teardown. PiperOrigin-RevId: 211699569 Change-Id: Ic0a69c29d7c31cd7e038909cc686c6ac98703374 --- runsc/container/container.go | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) (limited to 'runsc/container/container.go') 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. -- cgit v1.2.3