github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/pkg/mount/mounter_linux.go (about)

     1  package mount
     2  
     3  import (
     4  	"golang.org/x/sys/unix"
     5  )
     6  
     7  const (
     8  	// ptypes is the set propagation types.
     9  	ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE
    10  
    11  	// pflags is the full set valid flags for a change propagation call.
    12  	pflags = ptypes | unix.MS_REC | unix.MS_SILENT
    13  
    14  	// broflags is the combination of bind and read only
    15  	broflags = unix.MS_BIND | unix.MS_RDONLY
    16  )
    17  
    18  // isremount returns true if either device name or flags identify a remount request, false otherwise.
    19  func isremount(device string, flags uintptr) bool {
    20  	switch {
    21  	// We treat device "" and "none" as a remount request to provide compatibility with
    22  	// requests that don't explicitly set MS_REMOUNT such as those manipulating bind mounts.
    23  	case flags&unix.MS_REMOUNT != 0, device == "", device == "none":
    24  		return true
    25  	default:
    26  		return false
    27  	}
    28  }
    29  
    30  func mount(device, target, mType string, flags uintptr, data string) error {
    31  	oflags := flags &^ ptypes
    32  	if !isremount(device, flags) || data != "" {
    33  		// Initial call applying all non-propagation flags for mount
    34  		// or remount with changed data
    35  		if err := unix.Mount(device, target, mType, oflags, data); err != nil {
    36  			return err
    37  		}
    38  	}
    39  
    40  	if flags&ptypes != 0 {
    41  		// Change the propagation type.
    42  		if err := unix.Mount("", target, "", flags&pflags, ""); err != nil {
    43  			return err
    44  		}
    45  	}
    46  
    47  	if oflags&broflags == broflags {
    48  		// Remount the bind to apply read only.
    49  		return unix.Mount("", target, "", oflags|unix.MS_REMOUNT, "")
    50  	}
    51  
    52  	return nil
    53  }
    54  
    55  func unmount(target string, flag int) error {
    56  	return unix.Unmount(target, flag)
    57  }