func EnsureRemoveAll(dir string) error {
	notExistErr := make(map[string]bool)
	exitOnErr := make(map[string]int)
	maxRetry := 5
	mount.RecursiveUnmount(dir)
	for {
		err := os.RemoveAll(dir)
		if err == nil {
			return err
		}
		pe, ok := err.(*os.PathError)
		if !ok {
			return err
		}
		if os.IsNotExist(err) {
			if notExistErr[pe.Path] {
				return err
			}
			notExistErr[pe.Path] = true
			if pe.Path == dir {
				return nil
			}
			continue
		}
		if pe.Err != syscall.EBUSY {
			return err
		}
		if mounted, _ := mount.Mounted(pe.Path); mounted {
			if e := mount.Unmount(pe.Path); e != nil {
				if mounted, _ := mount.Mounted(pe.Path); mounted {
					return errors.Wrapf(e, "error while removing %s", dir)
				}
			}
		}
		if exitOnErr[pe.Path] == maxRetry {
			return err
		}
		exitOnErr[pe.Path]++
		time.Sleep(100 * time.Millisecond)
	}
}
EnsureRemoveAll wraps `os.RemoveAll` to check for specific errors that can
often be remedied.
Only use `EnsureRemoveAll` if you really want to make every effort to remove
a directory.

Because of the way `os.Remove` (and by extension `os.RemoveAll`) works, there
can be a race between reading directory entries and then actually attempting
to remove everything in the directory.
These types of errors do not need to be returned since it's ok for the dir to
be gone we can just retry the remove operation.

This should not return a `os.ErrNotExist` kind of error under any circumstances
package system
import (
	"os"
	"syscall"
	"time"
	"github.com/docker/docker/pkg/mount"
	"github.com/pkg/errors"
)