summaryrefslogtreecommitdiffhomepage
path: root/runsc/container/container.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-09-05 14:28:52 -0700
committerShentubot <shentubot@google.com>2018-09-05 14:30:09 -0700
commit12aef686af3f37029e619602286f00a40144c52d (patch)
tree89b4d8378fc647dacaa4828c1689645d8338f7e9 /runsc/container/container.go
parent0c7cfca0da234ae34497c420a23fea91a47a566c (diff)
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
Diffstat (limited to 'runsc/container/container.go')
-rw-r--r--runsc/container/container.go36
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.