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  }