github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/pkg/mount/flags.go (about) 1 package mount 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 // Parse fstab type mount options into mount() flags 9 // and device specific data 10 func parseOptions(options string) (int, string) { 11 var ( 12 flag int 13 data []string 14 ) 15 16 flags := map[string]struct { 17 clear bool 18 flag int 19 }{ 20 "defaults": {false, 0}, 21 "ro": {false, RDONLY}, 22 "rw": {true, RDONLY}, 23 "suid": {true, NOSUID}, 24 "nosuid": {false, NOSUID}, 25 "dev": {true, NODEV}, 26 "nodev": {false, NODEV}, 27 "exec": {true, NOEXEC}, 28 "noexec": {false, NOEXEC}, 29 "sync": {false, SYNCHRONOUS}, 30 "async": {true, SYNCHRONOUS}, 31 "dirsync": {false, DIRSYNC}, 32 "remount": {false, REMOUNT}, 33 "mand": {false, MANDLOCK}, 34 "nomand": {true, MANDLOCK}, 35 "atime": {true, NOATIME}, 36 "noatime": {false, NOATIME}, 37 "diratime": {true, NODIRATIME}, 38 "nodiratime": {false, NODIRATIME}, 39 "bind": {false, BIND}, 40 "rbind": {false, RBIND}, 41 "unbindable": {false, UNBINDABLE}, 42 "runbindable": {false, RUNBINDABLE}, 43 "private": {false, PRIVATE}, 44 "rprivate": {false, RPRIVATE}, 45 "shared": {false, SHARED}, 46 "rshared": {false, RSHARED}, 47 "slave": {false, SLAVE}, 48 "rslave": {false, RSLAVE}, 49 "relatime": {false, RELATIME}, 50 "norelatime": {true, RELATIME}, 51 "strictatime": {false, STRICTATIME}, 52 "nostrictatime": {true, STRICTATIME}, 53 } 54 55 for _, o := range strings.Split(options, ",") { 56 // If the option does not exist in the flags table or the flag 57 // is not supported on the platform, 58 // then it is a data value for a specific fs type 59 if f, exists := flags[o]; exists && f.flag != 0 { 60 if f.clear { 61 flag &= ^f.flag 62 } else { 63 flag |= f.flag 64 } 65 } else { 66 data = append(data, o) 67 } 68 } 69 return flag, strings.Join(data, ",") 70 } 71 72 // ParseTmpfsOptions parse fstab type mount options into flags and data 73 func ParseTmpfsOptions(options string) (int, string, error) { 74 flags, data := parseOptions(options) 75 validFlags := map[string]bool{ 76 "": true, 77 "size": true, 78 "mode": true, 79 "uid": true, 80 "gid": true, 81 "nr_inodes": true, 82 "nr_blocks": true, 83 "mpol": true, 84 } 85 for _, o := range strings.Split(data, ",") { 86 opt := strings.SplitN(o, "=", 2) 87 if !validFlags[opt[0]] { 88 return 0, "", fmt.Errorf("Invalid tmpfs option %q", opt) 89 } 90 } 91 return flags, data, nil 92 }