| package docker |
| |
| import ( |
| "fmt" |
| "github.com/dotcloud/docker/utils" |
| "os" |
| "os/exec" |
| "path/filepath" |
| "syscall" |
| "time" |
| ) |
| |
| func Unmount(target string) error { |
| if err := exec.Command("auplink", target, "flush").Run(); err != nil { |
| utils.Debugf("[warning]: couldn't run auplink before unmount: %s", err) |
| } |
| if err := syscall.Unmount(target, 0); err != nil { |
| return err |
| } |
| // Even though we just unmounted the filesystem, AUFS will prevent deleting the mntpoint |
| // for some time. We'll just keep retrying until it succeeds. |
| for retries := 0; retries < 1000; retries++ { |
| err := os.Remove(target) |
| if err == nil { |
| // rm mntpoint succeeded |
| return nil |
| } |
| if os.IsNotExist(err) { |
| // mntpoint doesn't exist anymore. Success. |
| return nil |
| } |
| // fmt.Printf("(%v) Remove %v returned: %v\n", retries, target, err) |
| time.Sleep(10 * time.Millisecond) |
| } |
| return fmt.Errorf("Umount: Failed to umount %v", target) |
| } |
| |
| func Mounted(mountpoint string) (bool, error) { |
| mntpoint, err := os.Stat(mountpoint) |
| if err != nil { |
| if os.IsNotExist(err) { |
| return false, nil |
| } |
| return false, err |
| } |
| parent, err := os.Stat(filepath.Join(mountpoint, "..")) |
| if err != nil { |
| return false, err |
| } |
| mntpointSt := mntpoint.Sys().(*syscall.Stat_t) |
| parentSt := parent.Sys().(*syscall.Stat_t) |
| return mntpointSt.Dev != parentSt.Dev, nil |
| } |