From d885bfb17602411856081eb77241e8e3e0388d45 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Thu, 13 Oct 2022 11:50:23 +0200 Subject: [PATCH] mount.Umount: EBUSY: try at most 50 times The function is being used in a number of places, notably container removal and cleanup. While container removal already loops over EBUSY, cleanup does not. To make sure that all callers of Unmount get a fair chance of unmounting cleanly, also loop there. I used the same values as containerd: 50 loops with 50ms sleeps. Context: containers/podman/issues/11594 Signed-off-by: Valentin Rothberg --- pkg/mount/unmount_unix.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/pkg/mount/unmount_unix.go b/pkg/mount/unmount_unix.go index 1d1afeee2e..49c523882b 100644 --- a/pkg/mount/unmount_unix.go +++ b/pkg/mount/unmount_unix.go @@ -1,16 +1,30 @@ +//go:build !windows // +build !windows package mount -import "golang.org/x/sys/unix" +import ( + "time" + + "golang.org/x/sys/unix" +) func unmount(target string, flags int) error { - err := unix.Unmount(target, flags) - if err == nil || err == unix.EINVAL { - // Ignore "not mounted" error here. Note the same error - // can be returned if flags are invalid, so this code - // assumes that the flags value is always correct. - return nil + var err error + for i := 0; i < 50; i++ { + err = unix.Unmount(target, flags) + switch err { + case unix.EBUSY: + time.Sleep(50 * time.Millisecond) + continue + case unix.EINVAL, nil: + // Ignore "not mounted" error here. Note the same error + // can be returned if flags are invalid, so this code + // assumes that the flags value is always correct. + return nil + default: + break + } } return &mountError{