github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/pkg/mount/mount.go (about) 1 package mount 2 3 import ( 4 "sort" 5 "strings" 6 ) 7 8 // GetMounts retrieves a list of mounts for the current running process. 9 func GetMounts() ([]*Info, error) { 10 return parseMountTable() 11 } 12 13 // Mounted determines if a specified mountpoint has been mounted. 14 // On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab. 15 func Mounted(mountpoint string) (bool, error) { 16 entries, err := parseMountTable() 17 if err != nil { 18 return false, err 19 } 20 21 // Search the table for the mountpoint 22 for _, e := range entries { 23 if e.Mountpoint == mountpoint { 24 return true, nil 25 } 26 } 27 return false, nil 28 } 29 30 // Mount will mount filesystem according to the specified configuration, on the 31 // condition that the target path is *not* already mounted. Options must be 32 // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See 33 // flags.go for supported option flags. 34 func Mount(device, target, mType, options string) error { 35 flag, _ := parseOptions(options) 36 if flag&REMOUNT != REMOUNT { 37 if mounted, err := Mounted(target); err != nil || mounted { 38 return err 39 } 40 } 41 return ForceMount(device, target, mType, options) 42 } 43 44 // ForceMount will mount a filesystem according to the specified configuration, 45 // *regardless* if the target path is not already mounted. Options must be 46 // specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See 47 // flags.go for supported option flags. 48 func ForceMount(device, target, mType, options string) error { 49 flag, data := parseOptions(options) 50 return mount(device, target, mType, uintptr(flag), data) 51 } 52 53 // Unmount lazily unmounts a filesystem on supported platforms, otherwise 54 // does a normal unmount. 55 func Unmount(target string) error { 56 if mounted, err := Mounted(target); err != nil || !mounted { 57 return err 58 } 59 return unmount(target, mntDetach) 60 } 61 62 // RecursiveUnmount unmounts the target and all mounts underneath, starting with 63 // the deepsest mount first. 64 func RecursiveUnmount(target string) error { 65 mounts, err := GetMounts() 66 if err != nil { 67 return err 68 } 69 70 // Make the deepest mount be first 71 sort.Sort(sort.Reverse(byMountpoint(mounts))) 72 73 for i, m := range mounts { 74 if !strings.HasPrefix(m.Mountpoint, target) { 75 continue 76 } 77 if err := Unmount(m.Mountpoint); err != nil && i == len(mounts)-1 { 78 if mounted, err := Mounted(m.Mountpoint); err != nil || mounted { 79 return err 80 } 81 // Ignore errors for submounts and continue trying to unmount others 82 // The final unmount should fail if there ane any submounts remaining 83 } 84 } 85 return nil 86 }