github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/daemon/graphdriver/aufs/mount.go (about) 1 // +build linux 2 3 package aufs // import "github.com/docker/docker/daemon/graphdriver/aufs" 4 5 import ( 6 "os/exec" 7 "syscall" 8 9 "github.com/docker/docker/pkg/mount" 10 ) 11 12 // Unmount the target specified. 13 func Unmount(target string) error { 14 const ( 15 EINVAL = 22 // if auplink returns this, 16 retries = 3 // retry a few times 17 ) 18 19 for i := 0; ; i++ { 20 out, err := exec.Command("auplink", target, "flush").CombinedOutput() 21 if err == nil { 22 break 23 } 24 rc := 0 25 if exiterr, ok := err.(*exec.ExitError); ok { 26 if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { 27 rc = status.ExitStatus() 28 } 29 } 30 if i >= retries || rc != EINVAL { 31 logger.WithError(err).WithField("method", "Unmount").Warnf("auplink flush failed: %s", out) 32 break 33 } 34 // auplink failed to find target in /proc/self/mounts because 35 // kernel can't guarantee continuity while reading from it 36 // while mounts table is being changed 37 logger.Debugf("auplink flush error (retrying %d/%d): %s", i+1, retries, out) 38 } 39 40 return mount.Unmount(target) 41 }