123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- package mount
- import (
- "fmt"
- "strings"
- )
- var flags = map[string]struct {
- clear bool
- flag int
- }{
- "defaults": {false, 0},
- "ro": {false, RDONLY},
- "rw": {true, RDONLY},
- "suid": {true, NOSUID},
- "nosuid": {false, NOSUID},
- "dev": {true, NODEV},
- "nodev": {false, NODEV},
- "exec": {true, NOEXEC},
- "noexec": {false, NOEXEC},
- "sync": {false, SYNCHRONOUS},
- "async": {true, SYNCHRONOUS},
- "dirsync": {false, DIRSYNC},
- "remount": {false, REMOUNT},
- "mand": {false, MANDLOCK},
- "nomand": {true, MANDLOCK},
- "atime": {true, NOATIME},
- "noatime": {false, NOATIME},
- "diratime": {true, NODIRATIME},
- "nodiratime": {false, NODIRATIME},
- "bind": {false, BIND},
- "rbind": {false, RBIND},
- "unbindable": {false, UNBINDABLE},
- "runbindable": {false, RUNBINDABLE},
- "private": {false, PRIVATE},
- "rprivate": {false, RPRIVATE},
- "shared": {false, SHARED},
- "rshared": {false, RSHARED},
- "slave": {false, SLAVE},
- "rslave": {false, RSLAVE},
- "relatime": {false, RELATIME},
- "norelatime": {true, RELATIME},
- "strictatime": {false, STRICTATIME},
- "nostrictatime": {true, STRICTATIME},
- }
- var validFlags = map[string]bool{
- "": true,
- "size": true,
- "mode": true,
- "uid": true,
- "gid": true,
- "nr_inodes": true,
- "nr_blocks": true,
- "mpol": true,
- }
- var propagationFlags = map[string]bool{
- "bind": true,
- "rbind": true,
- "unbindable": true,
- "runbindable": true,
- "private": true,
- "rprivate": true,
- "shared": true,
- "rshared": true,
- "slave": true,
- "rslave": true,
- }
- // MergeTmpfsOptions merge mount options to make sure there is no duplicate.
- func MergeTmpfsOptions(options []string) ([]string, error) {
- // We use collisions maps to remove duplicates.
- // For flag, the key is the flag value (the key for propagation flag is -1)
- // For data=value, the key is the data
- flagCollisions := map[int]bool{}
- dataCollisions := map[string]bool{}
- var newOptions []string
- // We process in reverse order
- for i := len(options) - 1; i >= 0; i-- {
- option := options[i]
- if option == "defaults" {
- continue
- }
- if f, ok := flags[option]; ok && f.flag != 0 {
- // There is only one propagation mode
- key := f.flag
- if propagationFlags[option] {
- key = -1
- }
- // Check to see if there is collision for flag
- if !flagCollisions[key] {
- // We prepend the option and add to collision map
- newOptions = append([]string{option}, newOptions...)
- flagCollisions[key] = true
- }
- continue
- }
- opt := strings.SplitN(option, "=", 2)
- if len(opt) != 2 || !validFlags[opt[0]] {
- return nil, fmt.Errorf("Invalid tmpfs option %q", opt)
- }
- if !dataCollisions[opt[0]] {
- // We prepend the option and add to collision map
- newOptions = append([]string{option}, newOptions...)
- dataCollisions[opt[0]] = true
- }
- }
- return newOptions, nil
- }
- // Parse fstab type mount options into mount() flags
- // and device specific data
- func parseOptions(options string) (int, string) {
- var (
- flag int
- data []string
- )
- for _, o := range strings.Split(options, ",") {
- // If the option does not exist in the flags table or the flag
- // is not supported on the platform,
- // then it is a data value for a specific fs type
- if f, exists := flags[o]; exists && f.flag != 0 {
- if f.clear {
- flag &= ^f.flag
- } else {
- flag |= f.flag
- }
- } else {
- data = append(data, o)
- }
- }
- return flag, strings.Join(data, ",")
- }
- // ParseTmpfsOptions parse fstab type mount options into flags and data
- func ParseTmpfsOptions(options string) (int, string, error) {
- flags, data := parseOptions(options)
- for _, o := range strings.Split(data, ",") {
- opt := strings.SplitN(o, "=", 2)
- if !validFlags[opt[0]] {
- return 0, "", fmt.Errorf("Invalid tmpfs option %q", opt)
- }
- }
- return flags, data, nil
- }
|