From 307f13b129cc1c8c845a7b361836a2550458e3c5 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 13 Dec 2017 11:30:24 +0000 Subject: [PATCH] Defer dockerRm until we are finished with the contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was introduced by #191 but somehow did not trigger either for me in local testing or in CI. It did trigger in initial CI of https://github.com/linuxkit/linuxkit/pull/2811 which can be seen at https://linuxkit.datakit.ci/linuxkit/linuxkit/pr/2811?history=1637690296123e9a15307b3a41b290da6e27e7cc The error is: Failed to docker rm container «...»: «...»: aufs: unmount error after retries: «...»: device or resource busy No doubt because we were still holding an open fd while trying to remove the container. Unclear why this didn't repro for me (docker 17.11.0-ce with overlay2) or whatever CI uses. Signed-off-by: Ian Campbell --- src/moby/image.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/moby/image.go b/src/moby/image.go index 3b3426ebe..22def6cfc 100644 --- a/src/moby/image.go +++ b/src/moby/image.go @@ -82,7 +82,7 @@ func tarPrefix(path string, tw tarWriter) error { } // ImageTar takes a Docker image and outputs it to a tar stream -func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull bool, resolv string) error { +func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull bool, resolv string) (e error) { log.Debugf("image tar: %s %s", ref, prefix) if prefix != "" && prefix[len(prefix)-1] != byte('/') { return fmt.Errorf("prefix does not end with /: %s", prefix) @@ -119,12 +119,13 @@ func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull if err != nil { return fmt.Errorf("Failed to docker export container from container %s: %v", container, err) } - defer contents.Close() + defer func() { + contents.Close() - err = dockerRm(container) - if err != nil { - return fmt.Errorf("Failed to docker rm container %s: %v", container, err) - } + if err := dockerRm(container); e == nil && err != nil { + e = fmt.Errorf("Failed to docker rm container %s: %v", container, err) + } + }() // now we need to filter out some files from the resulting tar archive