mounter_linux.go 1.5 KB

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