7bc96aec |
package mount
import ( |
069fdc8a |
"golang.org/x/sys/unix" |
7bc96aec |
)
|
b3b14b97 |
const (
// ptypes is the set propagation types. |
069fdc8a |
ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE |
b3b14b97 |
// pflags is the full set valid flags for a change propagation call. |
069fdc8a |
pflags = ptypes | unix.MS_REC | unix.MS_SILENT |
b3b14b97 |
// broflags is the combination of bind and read only |
069fdc8a |
broflags = unix.MS_BIND | unix.MS_RDONLY |
b3b14b97 |
)
// isremount returns true if either device name or flags identify a remount request, false otherwise.
func isremount(device string, flags uintptr) bool {
switch {
// We treat device "" and "none" as a remount request to provide compatibility with
// requests that don't explicitly set MS_REMOUNT such as those manipulating bind mounts. |
069fdc8a |
case flags&unix.MS_REMOUNT != 0, device == "", device == "none": |
b3b14b97 |
return true
default:
return false
}
}
func mount(device, target, mType string, flags uintptr, data string) error {
oflags := flags &^ ptypes |
3a1ab5b4 |
if !isremount(device, flags) || data != "" {
// Initial call applying all non-propagation flags for mount
// or remount with changed data |
069fdc8a |
if err := unix.Mount(device, target, mType, oflags, data); err != nil { |
b3b14b97 |
return err
} |
f231539e |
}
|
b3b14b97 |
if flags&ptypes != 0 {
// Change the propagation type. |
069fdc8a |
if err := unix.Mount("", target, "", flags&pflags, ""); err != nil { |
b3b14b97 |
return err
} |
f231539e |
} |
b3b14b97 |
if oflags&broflags == broflags {
// Remount the bind to apply read only. |
069fdc8a |
return unix.Mount("", target, "", oflags|unix.MS_REMOUNT, "") |
b3b14b97 |
}
|
f231539e |
return nil |
7bc96aec |
}
func unmount(target string, flag int) error { |
069fdc8a |
return unix.Unmount(target, flag) |
7bc96aec |
} |