@@ -45,6 +45,7 @@ const upperdirKey = "containerd.io/snapshot/overlay.upperdir"
4545type SnapshotterConfig struct {
4646 asyncRemove bool
4747 upperdirLabel bool
48+ mountOptions []string
4849}
4950
5051// Opt is an option to configure the overlay snapshotter
@@ -68,13 +69,21 @@ func WithUpperdirLabel(config *SnapshotterConfig) error {
6869 return nil
6970}
7071
72+ // WithMountOptions defines the default mount options used for the overlay mount.
73+ // NOTE: Options are not applied to bind mounts.
74+ func WithMountOptions (options []string ) Opt {
75+ return func (config * SnapshotterConfig ) error {
76+ config .mountOptions = append (config .mountOptions , options ... )
77+ return nil
78+ }
79+ }
80+
7181type snapshotter struct {
7282 root string
7383 ms * storage.MetaStore
7484 asyncRemove bool
7585 upperdirLabel bool
76- indexOff bool
77- userxattr bool // whether to enable "userxattr" mount option
86+ options []string
7887}
7988
8089// NewSnapshotter returns a Snapshotter which uses overlayfs. The overlayfs
@@ -106,22 +115,44 @@ func NewSnapshotter(root string, opts ...Opt) (snapshots.Snapshotter, error) {
106115 if err := os .Mkdir (filepath .Join (root , "snapshots" ), 0700 ); err != nil && ! os .IsExist (err ) {
107116 return nil , err
108117 }
109- // figure out whether "userxattr" option is recognized by the kernel && needed
110- userxattr , err := overlayutils .NeedsUserXAttr (root )
111- if err != nil {
112- logrus .WithError (err ).Warnf ("cannot detect whether \" userxattr\" option needs to be used, assuming to be %v" , userxattr )
118+
119+ if ! hasOption (config .mountOptions , "userxattr" , false ) {
120+ // figure out whether "userxattr" option is recognized by the kernel && needed
121+ userxattr , err := overlayutils .NeedsUserXAttr (root )
122+ if err != nil {
123+ logrus .WithError (err ).Warnf ("cannot detect whether \" userxattr\" option needs to be used, assuming to be %v" , userxattr )
124+ }
125+ if userxattr {
126+ config .mountOptions = append (config .mountOptions , "userxattr" )
127+ }
128+ }
129+
130+ if ! hasOption (config .mountOptions , "index" , false ) && supportsIndex () {
131+ config .mountOptions = append (config .mountOptions , "index=off" )
113132 }
114133
115134 return & snapshotter {
116135 root : root ,
117136 ms : ms ,
118137 asyncRemove : config .asyncRemove ,
119138 upperdirLabel : config .upperdirLabel ,
120- indexOff : supportsIndex (),
121- userxattr : userxattr ,
139+ options : config .mountOptions ,
122140 }, nil
123141}
124142
143+ func hasOption (options []string , key string , hasValue bool ) bool {
144+ for _ , option := range options {
145+ if hasValue {
146+ if strings .HasPrefix (option , key ) && len (option ) > len (key ) && option [len (key )] == '=' {
147+ return true
148+ }
149+ } else if option == key {
150+ return true
151+ }
152+ }
153+ return false
154+ }
155+
125156// Stat returns the info for an active or committed snapshot by name or
126157// key.
127158//
@@ -507,17 +538,8 @@ func (o *snapshotter) mounts(s storage.Snapshot) []mount.Mount {
507538 },
508539 }
509540 }
510- var options []string
511-
512- // set index=off when mount overlayfs
513- if o .indexOff {
514- options = append (options , "index=off" )
515- }
516-
517- if o .userxattr {
518- options = append (options , "userxattr" )
519- }
520541
542+ options := o .options
521543 if s .Kind == snapshots .KindActive {
522544 options = append (options ,
523545 fmt .Sprintf ("workdir=%s" , o .workPath (s .ID )),
0 commit comments