Files
docker-cli/vendor/github.com/docker/docker/pkg/system/rm.go
T
Sebastiaan van Stijn c318ec8a33 vendor: update docker/docker and moby/sys
diffs and relevant changes:

docker/docker: https://github.com/docker/docker/compare/c2cc352355d4c26be60be8ea3a1acfddc20fdfd3...af34b94a78a194ae9bce48a200241d08c05b7187
  - replace pkg/symlink with github.com/moby/sys/symlink

moby/sys: https://github.com/moby/sys/compare/6154f11e6840c0d6b0dbb23f4125a6134b3013c9...1bc8673b57550ddf85262eb0fed0aac651a37dab

changes:
    - mount, mountinfo: Add support for OpenBSD in addition to FreeBSD
    - mount, mountinfo: Exclude macOS (darwin)
    - mount.RecursiveUnmount(): minor improvements
    - mount.RecursiveUnmount: add a fast path
    - mount: bump mountinfo to v0.3.1
    - mount: Some refactor and improved GoDoc about Windows support
    - mount: use MNT_* flags from golang.org/x/sys/unix on freebsd (reduces use of cgo)
    - mountinfo.Mounted: add fast path for Linux using openat2
    - mountinfo.Mounted: optimize by adding fast paths
    - mountinfo: correctness improvements
    - mountinfo: deprecate PidMountInfo
    - mountinfo: fix not showing package doc, typos
    - mountinfo: fix path unescaping
    - mountinfo: make GetMountinfoFromReader Linux-specific
    - mountinfo: rename FstypeFilter -> FSTypeFilter, fix FilterFunc docs
    - mountinfo: use idiomatic naming for fields
    - Migrate github.com/docker/docker/pkg/symlink

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-11-10 22:31:52 +01:00

79 lines
1.9 KiB
Go

// +build !darwin,!windows
package system // import "github.com/docker/docker/pkg/system"
import (
"os"
"syscall"
"time"
"github.com/moby/sys/mount"
"github.com/pkg/errors"
)
// 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
func EnsureRemoveAll(dir string) error {
notExistErr := make(map[string]bool)
// track retries
exitOnErr := make(map[string]int)
maxRetry := 50
// Attempt to unmount anything beneath this dir first
mount.RecursiveUnmount(dir)
for {
err := os.RemoveAll(dir)
if err == nil {
return nil
}
pe, ok := err.(*os.PathError)
if !ok {
return err
}
if os.IsNotExist(err) {
if notExistErr[pe.Path] {
return err
}
notExistErr[pe.Path] = true
// There is a race where some subdir can be removed but after the parent
// dir entries have been read.
// So the path could be from `os.Remove(subdir)`
// If the reported non-existent path is not the passed in `dir` we
// should just retry, but otherwise return with no error.
if pe.Path == dir {
return nil
}
continue
}
if pe.Err != syscall.EBUSY {
return err
}
if e := mount.Unmount(pe.Path); e != nil {
return errors.Wrapf(e, "error while removing %s", dir)
}
if exitOnErr[pe.Path] == maxRetry {
return err
}
exitOnErr[pe.Path]++
time.Sleep(100 * time.Millisecond)
}
}