Signed-off-by: Jamie Hannaford <jamie.hannaford@rackspace.com>
| ... | ... |
@@ -8,12 +8,25 @@ package mount |
| 8 | 8 |
import "C" |
| 9 | 9 |
|
| 10 | 10 |
const ( |
| 11 |
- RDONLY = C.MNT_RDONLY |
|
| 12 |
- NOSUID = C.MNT_NOSUID |
|
| 13 |
- NOEXEC = C.MNT_NOEXEC |
|
| 11 |
+ // RDONLY will mount the filesystem as read-only. |
|
| 12 |
+ RDONLY = C.MNT_RDONLY |
|
| 13 |
+ |
|
| 14 |
+ // NOSUID will not allow set-user-identifier or set-group-identifier bits to |
|
| 15 |
+ // take effect. |
|
| 16 |
+ NOSUID = C.MNT_NOSUID |
|
| 17 |
+ |
|
| 18 |
+ // NOEXEC will not allow execution of any binaries on the mounted file system. |
|
| 19 |
+ NOEXEC = C.MNT_NOEXEC |
|
| 20 |
+ |
|
| 21 |
+ // SYNCHRONOUS will allow any I/O to the file system to be done synchronously. |
|
| 14 | 22 |
SYNCHRONOUS = C.MNT_SYNCHRONOUS |
| 15 |
- NOATIME = C.MNT_NOATIME |
|
| 16 | 23 |
|
| 24 |
+ // NOATIME will not update the file access time when reading from a file. |
|
| 25 |
+ NOATIME = C.MNT_NOATIME |
|
| 26 |
+) |
|
| 27 |
+ |
|
| 28 |
+// These flags are unsupported. |
|
| 29 |
+const ( |
|
| 17 | 30 |
BIND = 0 |
| 18 | 31 |
DIRSYNC = 0 |
| 19 | 32 |
MANDLOCK = 0 |
| ... | ... |
@@ -5,26 +5,81 @@ import ( |
| 5 | 5 |
) |
| 6 | 6 |
|
| 7 | 7 |
const ( |
| 8 |
- RDONLY = syscall.MS_RDONLY |
|
| 9 |
- NOSUID = syscall.MS_NOSUID |
|
| 10 |
- NODEV = syscall.MS_NODEV |
|
| 11 |
- NOEXEC = syscall.MS_NOEXEC |
|
| 8 |
+ // RDONLY will mount the file system read-only. |
|
| 9 |
+ RDONLY = syscall.MS_RDONLY |
|
| 10 |
+ |
|
| 11 |
+ // NOSUID will not allow set-user-identifier or set-group-identifier bits to |
|
| 12 |
+ // take effect. |
|
| 13 |
+ NOSUID = syscall.MS_NOSUID |
|
| 14 |
+ |
|
| 15 |
+ // NODEV will not interpret character or block special devices on the file |
|
| 16 |
+ // system. |
|
| 17 |
+ NODEV = syscall.MS_NODEV |
|
| 18 |
+ |
|
| 19 |
+ // NOEXEC will not allow execution of any binaries on the mounted file system. |
|
| 20 |
+ NOEXEC = syscall.MS_NOEXEC |
|
| 21 |
+ |
|
| 22 |
+ // SYNCHRONOUS will allow I/O to the file system to be done synchronously. |
|
| 12 | 23 |
SYNCHRONOUS = syscall.MS_SYNCHRONOUS |
| 13 |
- DIRSYNC = syscall.MS_DIRSYNC |
|
| 14 |
- REMOUNT = syscall.MS_REMOUNT |
|
| 15 |
- MANDLOCK = syscall.MS_MANDLOCK |
|
| 16 |
- NOATIME = syscall.MS_NOATIME |
|
| 17 |
- NODIRATIME = syscall.MS_NODIRATIME |
|
| 18 |
- BIND = syscall.MS_BIND |
|
| 19 |
- RBIND = syscall.MS_BIND | syscall.MS_REC |
|
| 20 |
- UNBINDABLE = syscall.MS_UNBINDABLE |
|
| 24 |
+ |
|
| 25 |
+ // DIRSYNC will force all directory updates within the file system to be done |
|
| 26 |
+ // synchronously. This affects the following system calls: creat, link, |
|
| 27 |
+ // unlink, symlink, mkdir, rmdir, mknod and rename. |
|
| 28 |
+ DIRSYNC = syscall.MS_DIRSYNC |
|
| 29 |
+ |
|
| 30 |
+ // REMOUNT will attempt to remount an already-mounted file system. This is |
|
| 31 |
+ // commonly used to change the mount flags for a file system, especially to |
|
| 32 |
+ // make a readonly file system writeable. It does not change device or mount |
|
| 33 |
+ // point. |
|
| 34 |
+ REMOUNT = syscall.MS_REMOUNT |
|
| 35 |
+ |
|
| 36 |
+ // MANDLOCK will force mandatory locks on a filesystem. |
|
| 37 |
+ MANDLOCK = syscall.MS_MANDLOCK |
|
| 38 |
+ |
|
| 39 |
+ // NOATIME will not update the file access time when reading from a file. |
|
| 40 |
+ NOATIME = syscall.MS_NOATIME |
|
| 41 |
+ |
|
| 42 |
+ // NODIRATIME will not update the directory access time. |
|
| 43 |
+ NODIRATIME = syscall.MS_NODIRATIME |
|
| 44 |
+ |
|
| 45 |
+ // BIND remounts a subtree somewhere else. |
|
| 46 |
+ BIND = syscall.MS_BIND |
|
| 47 |
+ |
|
| 48 |
+ // RBIND remounts a subtree and all possible submounts somewhere else. |
|
| 49 |
+ RBIND = syscall.MS_BIND | syscall.MS_REC |
|
| 50 |
+ |
|
| 51 |
+ // UNBINDABLE creates a mount which cannot be cloned through a bind operation. |
|
| 52 |
+ UNBINDABLE = syscall.MS_UNBINDABLE |
|
| 53 |
+ |
|
| 54 |
+ // RUNBINDABLE marks the entire mount tree as UNBINDABLE. |
|
| 21 | 55 |
RUNBINDABLE = syscall.MS_UNBINDABLE | syscall.MS_REC |
| 22 |
- PRIVATE = syscall.MS_PRIVATE |
|
| 23 |
- RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC |
|
| 24 |
- SLAVE = syscall.MS_SLAVE |
|
| 25 |
- RSLAVE = syscall.MS_SLAVE | syscall.MS_REC |
|
| 26 |
- SHARED = syscall.MS_SHARED |
|
| 27 |
- RSHARED = syscall.MS_SHARED | syscall.MS_REC |
|
| 28 |
- RELATIME = syscall.MS_RELATIME |
|
| 56 |
+ |
|
| 57 |
+ // PRIVATE creates a mount which carries no propagation abilities. |
|
| 58 |
+ PRIVATE = syscall.MS_PRIVATE |
|
| 59 |
+ |
|
| 60 |
+ // RPRIVATE marks the entire mount tree as PRIVATE. |
|
| 61 |
+ RPRIVATE = syscall.MS_PRIVATE | syscall.MS_REC |
|
| 62 |
+ |
|
| 63 |
+ // SLAVE creates a mount which receives propagation from its master, but not |
|
| 64 |
+ // vice versa. |
|
| 65 |
+ SLAVE = syscall.MS_SLAVE |
|
| 66 |
+ |
|
| 67 |
+ // RSLAVE marks the entire mount tree as SLAVE. |
|
| 68 |
+ RSLAVE = syscall.MS_SLAVE | syscall.MS_REC |
|
| 69 |
+ |
|
| 70 |
+ // SHARED creates a mount which provides the ability to create mirrors of |
|
| 71 |
+ // that mount such that mounts and unmounts within any of the mirrors |
|
| 72 |
+ // propagate to the other mirrors. |
|
| 73 |
+ SHARED = syscall.MS_SHARED |
|
| 74 |
+ |
|
| 75 |
+ // RSHARED marks the entire mount tree as SHARED. |
|
| 76 |
+ RSHARED = syscall.MS_SHARED | syscall.MS_REC |
|
| 77 |
+ |
|
| 78 |
+ // RELATIME updates inode access times relative to modify or change time. |
|
| 79 |
+ RELATIME = syscall.MS_RELATIME |
|
| 80 |
+ |
|
| 81 |
+ // STRICTATIME allows to explicitly request full atime updates. This makes |
|
| 82 |
+ // it possible for the kernel to default to relatime or noatime but still |
|
| 83 |
+ // allow userspace to override it. |
|
| 29 | 84 |
STRICTATIME = syscall.MS_STRICTATIME |
| 30 | 85 |
) |
| ... | ... |
@@ -4,11 +4,12 @@ import ( |
| 4 | 4 |
"time" |
| 5 | 5 |
) |
| 6 | 6 |
|
| 7 |
+// GetMounts retrieves a list of mounts for the current running process. |
|
| 7 | 8 |
func GetMounts() ([]*MountInfo, error) {
|
| 8 | 9 |
return parseMountTable() |
| 9 | 10 |
} |
| 10 | 11 |
|
| 11 |
-// Looks at /proc/self/mountinfo to determine of the specified |
|
| 12 |
+// Mounted looks at /proc/self/mountinfo to determine of the specified |
|
| 12 | 13 |
// mountpoint has been mounted |
| 13 | 14 |
func Mounted(mountpoint string) (bool, error) {
|
| 14 | 15 |
entries, err := parseMountTable() |
| ... | ... |
@@ -25,9 +26,10 @@ func Mounted(mountpoint string) (bool, error) {
|
| 25 | 25 |
return false, nil |
| 26 | 26 |
} |
| 27 | 27 |
|
| 28 |
-// Mount the specified options at the target path only if |
|
| 29 |
-// the target is not mounted |
|
| 30 |
-// Options must be specified as fstab style |
|
| 28 |
+// Mount will mount filesystem according to the specified configuration, on the |
|
| 29 |
+// condition that the target path is *not* already mounted. Options must be |
|
| 30 |
+// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See |
|
| 31 |
+// flags.go for supported option flags. |
|
| 31 | 32 |
func Mount(device, target, mType, options string) error {
|
| 32 | 33 |
flag, _ := parseOptions(options) |
| 33 | 34 |
if flag&REMOUNT != REMOUNT {
|
| ... | ... |
@@ -38,9 +40,10 @@ func Mount(device, target, mType, options string) error {
|
| 38 | 38 |
return ForceMount(device, target, mType, options) |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
-// Mount the specified options at the target path |
|
| 42 |
-// reguardless if the target is mounted or not |
|
| 43 |
-// Options must be specified as fstab style |
|
| 41 |
+// ForceMount will mount a filesystem according to the specified configuration, |
|
| 42 |
+// *regardless* if the target path is not already mounted. Options must be |
|
| 43 |
+// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See |
|
| 44 |
+// flags.go for supported option flags. |
|
| 44 | 45 |
func ForceMount(device, target, mType, options string) error {
|
| 45 | 46 |
flag, data := parseOptions(options) |
| 46 | 47 |
if err := mount(device, target, mType, uintptr(flag), data); err != nil {
|
| ... | ... |
@@ -49,7 +52,7 @@ func ForceMount(device, target, mType, options string) error {
|
| 49 | 49 |
return nil |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 |
-// Unmount the target only if it is mounted |
|
| 52 |
+// Unmount will unmount the target filesystem, so long as it is mounted. |
|
| 53 | 53 |
func Unmount(target string) error {
|
| 54 | 54 |
if mounted, err := Mounted(target); err != nil || !mounted {
|
| 55 | 55 |
return err |
| ... | ... |
@@ -57,7 +60,8 @@ func Unmount(target string) error {
|
| 57 | 57 |
return ForceUnmount(target) |
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 |
-// Unmount the target reguardless if it is mounted or not |
|
| 60 |
+// ForceUnmount will force an unmount of the target filesystem, regardless if |
|
| 61 |
+// it is mounted or not. |
|
| 61 | 62 |
func ForceUnmount(target string) (err error) {
|
| 62 | 63 |
// Simple retry logic for unmount |
| 63 | 64 |
for i := 0; i < 10; i++ {
|
| ... | ... |
@@ -1,7 +1,40 @@ |
| 1 | 1 |
package mount |
| 2 | 2 |
|
| 3 |
+// MountInfo reveals information about a particular mounted filesystem. This |
|
| 4 |
+// struct is populated from the content in the /proc/<pid>/mountinfo file. |
|
| 3 | 5 |
type MountInfo struct {
|
| 4 |
- Id, Parent, Major, Minor int |
|
| 5 |
- Root, Mountpoint, Opts, Optional string |
|
| 6 |
- Fstype, Source, VfsOpts string |
|
| 6 |
+ // Id is a unique identifier of the mount (may be reused after umount). |
|
| 7 |
+ Id int |
|
| 8 |
+ |
|
| 9 |
+ // Parent indicates the ID of the mount parent (or of self for the top of the |
|
| 10 |
+ // mount tree). |
|
| 11 |
+ Parent int |
|
| 12 |
+ |
|
| 13 |
+ // Major indicates one half of the device ID which identifies the device class. |
|
| 14 |
+ Major int |
|
| 15 |
+ |
|
| 16 |
+ // Minor indicates one half of the device ID which identifies a specific |
|
| 17 |
+ // instance of device. |
|
| 18 |
+ Minor int |
|
| 19 |
+ |
|
| 20 |
+ // Root of the mount within the filesystem. |
|
| 21 |
+ Root string |
|
| 22 |
+ |
|
| 23 |
+ // Mountpoint indicates the mount point relative to the process's root. |
|
| 24 |
+ Mountpoint string |
|
| 25 |
+ |
|
| 26 |
+ // Opts represents mount-specific options. |
|
| 27 |
+ Opts string |
|
| 28 |
+ |
|
| 29 |
+ // Optional represents optional fields. |
|
| 30 |
+ Optional string |
|
| 31 |
+ |
|
| 32 |
+ // Fstype indicates the type of filesystem, such as EXT3. |
|
| 33 |
+ Fstype string |
|
| 34 |
+ |
|
| 35 |
+ // Source indicates filesystem specific information or "none". |
|
| 36 |
+ Source string |
|
| 37 |
+ |
|
| 38 |
+ // VfsOpts represents per super block options. |
|
| 39 |
+ VfsOpts string |
|
| 7 | 40 |
} |
| ... | ... |
@@ -13,7 +13,8 @@ import ( |
| 13 | 13 |
"unsafe" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts |
|
| 16 |
+// Parse /proc/self/mountinfo because comparing Dev and ino does not work from |
|
| 17 |
+// bind mounts. |
|
| 17 | 18 |
func parseMountTable() ([]*MountInfo, error) {
|
| 18 | 19 |
var rawEntries *C.struct_statfs |
| 19 | 20 |
|
| ... | ... |
@@ -28,7 +28,8 @@ const ( |
| 28 | 28 |
mountinfoFormat = "%d %d %d:%d %s %s %s %s" |
| 29 | 29 |
) |
| 30 | 30 |
|
| 31 |
-// Parse /proc/self/mountinfo because comparing Dev and ino does not work from bind mounts |
|
| 31 |
+// Parse /proc/self/mountinfo because comparing Dev and ino does not work from |
|
| 32 |
+// bind mounts |
|
| 32 | 33 |
func parseMountTable() ([]*MountInfo, error) {
|
| 33 | 34 |
f, err := os.Open("/proc/self/mountinfo")
|
| 34 | 35 |
if err != nil {
|
| ... | ... |
@@ -80,7 +81,9 @@ func parseInfoFile(r io.Reader) ([]*MountInfo, error) {
|
| 80 | 80 |
return out, nil |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
-// PidMountInfo collects the mounts for a specific Pid |
|
| 83 |
+// PidMountInfo collects the mounts for a specific process ID. If the process |
|
| 84 |
+// ID is unknown, it is better to use `GetMounts` which will inspect |
|
| 85 |
+// "/proc/self/mountinfo" instead. |
|
| 84 | 86 |
func PidMountInfo(pid int) ([]*MountInfo, error) {
|
| 85 | 87 |
f, err := os.Open(fmt.Sprintf("/proc/%d/mountinfo", pid))
|
| 86 | 88 |
if err != nil {
|
| ... | ... |
@@ -2,34 +2,50 @@ |
| 2 | 2 |
|
| 3 | 3 |
package mount |
| 4 | 4 |
|
| 5 |
+// MakeShared ensures a mounted filesystem has the SHARED mount option enabled. |
|
| 6 |
+// See the supported options in flags.go for further reference. |
|
| 5 | 7 |
func MakeShared(mountPoint string) error {
|
| 6 | 8 |
return ensureMountedAs(mountPoint, "shared") |
| 7 | 9 |
} |
| 8 | 10 |
|
| 11 |
+// MakeRShared ensures a mounted filesystem has the RSHARED mount option enabled. |
|
| 12 |
+// See the supported options in flags.go for further reference. |
|
| 9 | 13 |
func MakeRShared(mountPoint string) error {
|
| 10 | 14 |
return ensureMountedAs(mountPoint, "rshared") |
| 11 | 15 |
} |
| 12 | 16 |
|
| 17 |
+// MakePrivate ensures a mounted filesystem has the PRIVATE mount option enabled. |
|
| 18 |
+// See the supported options in flags.go for further reference. |
|
| 13 | 19 |
func MakePrivate(mountPoint string) error {
|
| 14 | 20 |
return ensureMountedAs(mountPoint, "private") |
| 15 | 21 |
} |
| 16 | 22 |
|
| 23 |
+// MakeRPrivate ensures a mounted filesystem has the RPRIVATE mount option |
|
| 24 |
+// enabled. See the supported options in flags.go for further reference. |
|
| 17 | 25 |
func MakeRPrivate(mountPoint string) error {
|
| 18 | 26 |
return ensureMountedAs(mountPoint, "rprivate") |
| 19 | 27 |
} |
| 20 | 28 |
|
| 29 |
+// MakeSlave ensures a mounted filesystem has the SLAVE mount option enabled. |
|
| 30 |
+// See the supported options in flags.go for further reference. |
|
| 21 | 31 |
func MakeSlave(mountPoint string) error {
|
| 22 | 32 |
return ensureMountedAs(mountPoint, "slave") |
| 23 | 33 |
} |
| 24 | 34 |
|
| 35 |
+// MakeRSlave ensures a mounted filesystem has the RSLAVE mount option enabled. |
|
| 36 |
+// See the supported options in flags.go for further reference. |
|
| 25 | 37 |
func MakeRSlave(mountPoint string) error {
|
| 26 | 38 |
return ensureMountedAs(mountPoint, "rslave") |
| 27 | 39 |
} |
| 28 | 40 |
|
| 41 |
+// MakeUnbindable ensures a mounted filesystem has the UNBINDABLE mount option |
|
| 42 |
+// enabled. See the supported options in flags.go for further reference. |
|
| 29 | 43 |
func MakeUnbindable(mountPoint string) error {
|
| 30 | 44 |
return ensureMountedAs(mountPoint, "unbindable") |
| 31 | 45 |
} |
| 32 | 46 |
|
| 47 |
+// MakeRUnbindable ensures a mounted filesystem has the RUNBINDABLE mount |
|
| 48 |
+// option enabled. See the supported options in flags.go for further reference. |
|
| 33 | 49 |
func MakeRUnbindable(mountPoint string) error {
|
| 34 | 50 |
return ensureMountedAs(mountPoint, "runbindable") |
| 35 | 51 |
} |