package mount import ( "golang.org/x/sys/unix" ) const ( // ptypes is the set propagation types. ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE // pflags is the full set valid flags for a change propagation call. pflags = ptypes | unix.MS_REC | unix.MS_SILENT // broflags is the combination of bind and read only broflags = unix.MS_BIND | unix.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&unix.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) || data != "" { // Initial call applying all non-propagation flags for mount // or remount with changed data if err := unix.Mount(device, target, mType, oflags, data); err != nil { return &mountError{ op: "mount", source: device, target: target, flags: oflags, data: data, err: err, } } } if flags&ptypes != 0 { // Change the propagation type. if err := unix.Mount("", target, "", flags&pflags, ""); err != nil { return &mountError{ op: "remount", target: target, flags: flags & pflags, err: err, } } } if oflags&broflags == broflags { // Remount the bind to apply read only. if err := unix.Mount("", target, "", oflags|unix.MS_REMOUNT, ""); err != nil { return &mountError{ op: "remount-ro", target: target, flags: oflags | unix.MS_REMOUNT, err: err, } } } return nil }