2020-04-16 05:23:37 -04:00
|
|
|
package mount
|
2017-05-10 17:13:36 -04:00
|
|
|
|
|
|
|
import (
|
2017-08-07 05:52:40 -04:00
|
|
|
"golang.org/x/sys/unix"
|
2017-05-10 17:13:36 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// ptypes is the set propagation types.
|
2017-08-07 05:52:40 -04:00
|
|
|
ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE
|
2017-05-10 17:13:36 -04:00
|
|
|
|
|
|
|
// pflags is the full set valid flags for a change propagation call.
|
2017-08-07 05:52:40 -04:00
|
|
|
pflags = ptypes | unix.MS_REC | unix.MS_SILENT
|
2017-05-10 17:13:36 -04:00
|
|
|
|
|
|
|
// broflags is the combination of bind and read only
|
2017-08-07 05:52:40 -04:00
|
|
|
broflags = unix.MS_BIND | unix.MS_RDONLY
|
2017-05-10 17:13:36 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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.
|
2017-08-07 05:52:40 -04:00
|
|
|
case flags&unix.MS_REMOUNT != 0, device == "", device == "none":
|
2017-05-10 17:13:36 -04:00
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func mount(device, target, mType string, flags uintptr, data string) error {
|
|
|
|
oflags := flags &^ ptypes
|
2017-08-07 05:52:40 -04:00
|
|
|
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 {
|
2018-12-31 00:45:37 -05:00
|
|
|
return &mountError{
|
|
|
|
op: "mount",
|
|
|
|
source: device,
|
|
|
|
target: target,
|
|
|
|
flags: oflags,
|
|
|
|
data: data,
|
|
|
|
err: err,
|
|
|
|
}
|
2017-05-10 17:13:36 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if flags&ptypes != 0 {
|
|
|
|
// Change the propagation type.
|
2017-08-07 05:52:40 -04:00
|
|
|
if err := unix.Mount("", target, "", flags&pflags, ""); err != nil {
|
2018-12-31 00:45:37 -05:00
|
|
|
return &mountError{
|
|
|
|
op: "remount",
|
|
|
|
target: target,
|
|
|
|
flags: flags & pflags,
|
|
|
|
err: err,
|
|
|
|
}
|
2017-05-10 17:13:36 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if oflags&broflags == broflags {
|
|
|
|
// Remount the bind to apply read only.
|
2018-12-31 00:45:37 -05:00
|
|
|
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,
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-05-10 17:13:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|