mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
af3bbcc00c
As caught by staticcheck (after disabling the default exclusion rules); Based on the comment, this break was indeed meant to break the loop and return the error. ``` daemon/graphdriver/aufs/mount.go:54:4: SA4011: ineffective break statement. Did you mean to break out of the outer loop? (staticcheck) break ^ ``` Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
// +build linux
|
|
|
|
package aufs // import "github.com/docker/docker/daemon/graphdriver/aufs"
|
|
|
|
import (
|
|
"os/exec"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/docker/docker/pkg/mount"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// Unmount the target specified.
|
|
func Unmount(target string) error {
|
|
const retries = 5
|
|
|
|
// auplink flush
|
|
for i := 0; ; i++ {
|
|
out, err := exec.Command("auplink", target, "flush").CombinedOutput()
|
|
if err == nil {
|
|
break
|
|
}
|
|
rc := 0
|
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
|
rc = status.ExitStatus()
|
|
}
|
|
}
|
|
if i >= retries || rc != int(unix.EINVAL) {
|
|
logger.WithError(err).WithField("method", "Unmount").Warnf("auplink flush failed: %s", out)
|
|
break
|
|
}
|
|
// auplink failed to find target in /proc/self/mounts because
|
|
// kernel can't guarantee continuity while reading from it
|
|
// while mounts table is being changed
|
|
logger.Debugf("auplink flush error (retrying %d/%d): %s", i+1, retries, out)
|
|
}
|
|
|
|
// unmount
|
|
var err error
|
|
for i := 0; i < retries; i++ {
|
|
err = mount.Unmount(target)
|
|
switch errors.Cause(err) {
|
|
case nil:
|
|
return nil
|
|
case unix.EBUSY:
|
|
logger.Debugf("aufs unmount %s failed with EBUSY (retrying %d/%d)", target, i+1, retries)
|
|
time.Sleep(100 * time.Millisecond)
|
|
continue // try again
|
|
default:
|
|
// any other error is fatal
|
|
return err
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|