aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/moby/sys/mount/mounter_linux.go
blob: 0c477cc3d79df7462b8e2abacb7cf281701cf350 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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
}