diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-11-07 13:54:47 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-07 13:55:36 -0800 |
commit | 13b48f2e6a186321084fa8159e8cc2659ed221a2 (patch) | |
tree | 8bf0f439df3781468734de92f306391b8c9e8955 | |
parent | c92b9b7086b89fd8e7f5913bf74d04761163e24b (diff) |
AsyncBarrier should be run after all defers in destroyContainerFS.
destroyContainerFS must wait for all async operations to finish before
returning. In an attempt to do this, we call fs.AsyncBarrier() at the end of
the function. However, there are many defer'd DecRefs which end up running
AFTER the AsyncBarrier() call.
This CL fixes this by calling fs.AsyncBarrier() in the first defer statement,
thus ensuring that it runs at the end of the function, after all other defers.
PiperOrigin-RevId: 220523545
Change-Id: I5e96ee9ea6d86eeab788ff964484c50ef7f64a2f
-rw-r--r-- | runsc/boot/fs.go | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index e52c89fe4..3f3f9bef6 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -638,6 +638,19 @@ func setExecutablePath(ctx context.Context, mns *fs.MountNamespace, procArgs *ke // destroyContainerFS cleans up the filesystem by unmounting all mounts for the // given container and deleting the container root directory. func destroyContainerFS(ctx context.Context, cid string, k *kernel.Kernel) error { + defer func() { + // Flushing dirent references triggers many async close + // operations. We must wait for those to complete before + // returning, otherwise the caller may kill the gofer before + // they complete, causing a cascade of failing RPCs. + // + // This must take place in the first deferred function, so that + // it runs after all the other deferred DecRef() calls in this + // function. + log.Infof("Waiting for async filesystem operations to complete") + fs.AsyncBarrier() + }() + // First get a reference to the container root directory. mns := k.RootMountNamespace() mnsRoot := mns.Root() @@ -687,12 +700,5 @@ func destroyContainerFS(ctx context.Context, cid string, k *kernel.Kernel) error return fmt.Errorf("error removing directory %q: %v", containerRoot, err) } - // Flushing dirent references triggers many async close operations. We - // must wait for those to complete before returning, otherwise the - // caller may kill the gofer before they complete, causing a cascade of - // failing RPCs. - log.Infof("Waiting for async filesystem operations to complete") - fs.AsyncBarrier() - return nil } |