blob: 3ef2ce6f0dd8dc9e80d6a0abafca463c7f7a623d [file] [log] [blame]
package mount
import (
"syscall"
)
const (
// ptypes is the set propagation types.
ptypes = syscall.MS_SHARED | syscall.MS_PRIVATE | syscall.MS_SLAVE | syscall.MS_UNBINDABLE
// pflags is the full set valid flags for a change propagation call.
pflags = ptypes | syscall.MS_REC | syscall.MS_SILENT
// broflags is the combination of bind and read only
broflags = syscall.MS_BIND | syscall.MS_RDONLY
)
// 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.
case flags&syscall.MS_REMOUNT != 0, device == "", device == "none":
return true
default:
return false
}
}
func mount(device, target, mType string, flags uintptr, data string) error {
oflags := flags &^ ptypes
if !isremount(device, flags) {
// Initial call applying all non-propagation flags.
if err := syscall.Mount(device, target, mType, oflags, data); err != nil {
return err
}
}
if flags&ptypes != 0 {
// Change the propagation type.
if err := syscall.Mount("", target, "", flags&pflags, ""); err != nil {
return err
}
}
if oflags&broflags == broflags {
// Remount the bind to apply read only.
return syscall.Mount("", target, "", oflags|syscall.MS_REMOUNT, "")
}
return nil
}
func unmount(target string, flag int) error {
return syscall.Unmount(target, flag)
}