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  }