mirror of
https://github.com/moby/moby.git
synced 2026-06-24 08:48:23 +00:00
Merge pull request #52884 from vvoland/containerfs-xplat
internal/containerfs: Make cross platform
This commit is contained in:
@@ -1,14 +1,8 @@
|
||||
//go:build !darwin && !windows
|
||||
|
||||
package containerfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/moby/sys/mount"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// EnsureRemoveAll wraps [os.RemoveAll] to check for specific errors that can
|
||||
@@ -30,8 +24,8 @@ func EnsureRemoveAll(dir string) error {
|
||||
exitOnErr := make(map[string]int)
|
||||
maxRetry := 50
|
||||
|
||||
// Attempt to unmount anything beneath this dir first
|
||||
mount.RecursiveUnmount(dir)
|
||||
// Allow the platform to prepare for removal before os.RemoveAll.
|
||||
prepareRemoveAll(dir)
|
||||
|
||||
for {
|
||||
err := os.RemoveAll(dir)
|
||||
@@ -61,17 +55,17 @@ func EnsureRemoveAll(dir string) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if errors.Is(pe.Err, syscall.ENOTEMPTY) && !notEmptyDir[pe.Path] {
|
||||
if isNotEmptyDirError(pe.Err) && !notEmptyDir[pe.Path] {
|
||||
notEmptyDir[pe.Path] = true
|
||||
continue
|
||||
}
|
||||
|
||||
if !errors.Is(pe.Err, syscall.EBUSY) {
|
||||
return err
|
||||
retry, removeErr := retryRemoveAllError(dir, pe)
|
||||
if removeErr != nil {
|
||||
return removeErr
|
||||
}
|
||||
|
||||
if e := mount.Unmount(pe.Path); e != nil {
|
||||
return errors.Wrapf(e, "error while removing %s", dir)
|
||||
if !retry {
|
||||
return err
|
||||
}
|
||||
|
||||
if exitOnErr[pe.Path] == maxRetry {
|
||||
|
||||
29
daemon/internal/containerfs/rm_unix.go
Normal file
29
daemon/internal/containerfs/rm_unix.go
Normal file
@@ -0,0 +1,29 @@
|
||||
//go:build !windows
|
||||
|
||||
package containerfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/moby/sys/mount"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func prepareRemoveAll(dir string) {
|
||||
mount.RecursiveUnmount(dir)
|
||||
}
|
||||
|
||||
func isNotEmptyDirError(err error) bool {
|
||||
return errors.Is(err, syscall.ENOTEMPTY)
|
||||
}
|
||||
|
||||
func retryRemoveAllError(dir string, pe *os.PathError) (bool, error) {
|
||||
if !errors.Is(pe.Err, syscall.EBUSY) {
|
||||
return false, nil
|
||||
}
|
||||
if err := mount.Unmount(pe.Path); err != nil {
|
||||
return false, errors.Wrapf(err, "error while removing %s", dir)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
@@ -1,8 +1,22 @@
|
||||
package containerfs
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
// EnsureRemoveAll is an alias to [os.RemoveAll] on Windows.
|
||||
func EnsureRemoveAll(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func prepareRemoveAll(string) {
|
||||
}
|
||||
|
||||
func isNotEmptyDirError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func retryRemoveAllError(_ string, pe *os.PathError) (bool, error) {
|
||||
return errors.Is(pe.Err, windows.ERROR_ACCESS_DENIED) ||
|
||||
errors.Is(pe.Err, windows.ERROR_SHARING_VIOLATION) ||
|
||||
errors.Is(pe.Err, windows.ERROR_LOCK_VIOLATION) ||
|
||||
errors.Is(pe.Err, windows.ERROR_DIR_NOT_EMPTY), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user