@@ -44,6 +44,7 @@ const upperdirKey = "containerd.io/snapshot/overlay.upperdir"
4444type SnapshotterConfig struct {
4545 asyncRemove bool
4646 upperdirLabel bool
47+ mountOptions []string
4748}
4849
4950// Opt is an option to configure the overlay snapshotter
@@ -67,13 +68,21 @@ func WithUpperdirLabel(config *SnapshotterConfig) error {
6768 return nil
6869}
6970
71+ // WithMountOptions defines the default mount options used for the overlay mount.
72+ // NOTE: Options are not applied to bind mounts.
73+ func WithMountOptions (options []string ) Opt {
74+ return func (config * SnapshotterConfig ) error {
75+ config .mountOptions = append (config .mountOptions , options ... )
76+ return nil
77+ }
78+ }
79+
7080type snapshotter struct {
7181 root string
7282 ms * storage.MetaStore
7383 asyncRemove bool
7484 upperdirLabel bool
75- indexOff bool
76- userxattr bool // whether to enable "userxattr" mount option
85+ options []string
7786}
7887
7988// NewSnapshotter returns a Snapshotter which uses overlayfs. The overlayfs
@@ -105,22 +114,44 @@ func NewSnapshotter(root string, opts ...Opt) (snapshots.Snapshotter, error) {
105114 if err := os .Mkdir (filepath .Join (root , "snapshots" ), 0700 ); err != nil && ! os .IsExist (err ) {
106115 return nil , err
107116 }
108- // figure out whether "userxattr" option is recognized by the kernel && needed
109- userxattr , err := overlayutils .NeedsUserXAttr (root )
110- if err != nil {
111- logrus .WithError (err ).Warnf ("cannot detect whether \" userxattr\" option needs to be used, assuming to be %v" , userxattr )
117+
118+ if ! hasOption (config .mountOptions , "userxattr" , false ) {
119+ // figure out whether "userxattr" option is recognized by the kernel && needed
120+ userxattr , err := overlayutils .NeedsUserXAttr (root )
121+ if err != nil {
122+ logrus .WithError (err ).Warnf ("cannot detect whether \" userxattr\" option needs to be used, assuming to be %v" , userxattr )
123+ }
124+ if userxattr {
125+ config .mountOptions = append (config .mountOptions , "userxattr" )
126+ }
127+ }
128+
129+ if ! hasOption (config .mountOptions , "index" , false ) && supportsIndex () {
130+ config .mountOptions = append (config .mountOptions , "index=off" )
112131 }
113132
114133 return & snapshotter {
115134 root : root ,
116135 ms : ms ,
117136 asyncRemove : config .asyncRemove ,
118137 upperdirLabel : config .upperdirLabel ,
119- indexOff : supportsIndex (),
120- userxattr : userxattr ,
138+ options : config .mountOptions ,
121139 }, nil
122140}
123141
142+ func hasOption (options []string , key string , hasValue bool ) bool {
143+ for _ , option := range options {
144+ if hasValue {
145+ if strings .HasPrefix (option , key ) && len (option ) > len (key ) && option [len (key )] == '=' {
146+ return true
147+ }
148+ } else if option == key {
149+ return true
150+ }
151+ }
152+ return false
153+ }
154+
124155// Stat returns the info for an active or committed snapshot by name or
125156// key.
126157//
@@ -453,17 +484,8 @@ func (o *snapshotter) mounts(s storage.Snapshot) []mount.Mount {
453484 },
454485 }
455486 }
456- var options []string
457-
458- // set index=off when mount overlayfs
459- if o .indexOff {
460- options = append (options , "index=off" )
461- }
462-
463- if o .userxattr {
464- options = append (options , "userxattr" )
465- }
466487
488+ options := o .options
467489 if s .Kind == snapshots .KindActive {
468490 options = append (options ,
469491 fmt .Sprintf ("workdir=%s" , o .workPath (s .ID )),
0 commit comments