Browse code

Remove support for overlay/overlay2 without d_type

Support for running overlay/overlay2 on a backing filesystem
without d_type support (most likely: xfs, as ext4 supports
this by default), was deprecated for some time.

Running without d_type support is problematic, and can
lead to difficult to debug issues ("invalid argument" errors,
or unable to remove files from the container's filesystem).

This patch turns the warning that was previously printed
into an "unsupported" error, so that the overlay/overlay2
drivers are not automatically selected when detecting supported
storage drivers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2017/11/16 09:48:43
Showing 6 changed files
... ...
@@ -1,7 +1,6 @@
1 1
 package graphdriver
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"fmt"
6 5
 	"io"
7 6
 	"os"
... ...
@@ -28,13 +27,6 @@ const (
28 28
 var (
29 29
 	// All registered drivers
30 30
 	drivers map[string]InitFunc
31
-
32
-	// ErrNotSupported returned when driver is not supported.
33
-	ErrNotSupported = errors.New("driver not supported")
34
-	// ErrPrerequisites returned when driver does not meet prerequisites.
35
-	ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
36
-	// ErrIncompatibleFS returned when file system is not supported.
37
-	ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
38 31
 )
39 32
 
40 33
 //CreateOpts contains optional arguments for Create() and CreateReadWrite()
... ...
@@ -248,7 +240,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
248 248
 	for _, name := range list {
249 249
 		driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
250 250
 		if err != nil {
251
-			if isDriverNotSupported(err) {
251
+			if IsDriverNotSupported(err) {
252 252
 				continue
253 253
 			}
254 254
 			return nil, err
... ...
@@ -260,7 +252,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
260 260
 	for name, initFunc := range drivers {
261 261
 		driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
262 262
 		if err != nil {
263
-			if isDriverNotSupported(err) {
263
+			if IsDriverNotSupported(err) {
264 264
 				continue
265 265
 			}
266 266
 			return nil, err
... ...
@@ -270,12 +262,6 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
270 270
 	return nil, fmt.Errorf("No supported storage backend found")
271 271
 }
272 272
 
273
-// isDriverNotSupported returns true if the error initializing
274
-// the graph driver is a non-supported error.
275
-func isDriverNotSupported(err error) bool {
276
-	return err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS
277
-}
278
-
279 273
 // scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
280 274
 func scanPriorDrivers(root string) map[string]bool {
281 275
 	driversMap := make(map[string]bool)
282 276
new file mode 100644
... ...
@@ -0,0 +1,36 @@
0
+package graphdriver
1
+
2
+const (
3
+	// ErrNotSupported returned when driver is not supported.
4
+	ErrNotSupported NotSupportedError = "driver not supported"
5
+	// ErrPrerequisites returned when driver does not meet prerequisites.
6
+	ErrPrerequisites NotSupportedError = "prerequisites for driver not satisfied (wrong filesystem?)"
7
+	// ErrIncompatibleFS returned when file system is not supported.
8
+	ErrIncompatibleFS NotSupportedError = "backing file system is unsupported for this graph driver"
9
+)
10
+
11
+// ErrUnSupported signals that the graph-driver is not supported on the current configuration
12
+type ErrUnSupported interface {
13
+	NotSupported()
14
+}
15
+
16
+// NotSupportedError signals that the graph-driver is not supported on the current configuration
17
+type NotSupportedError string
18
+
19
+func (e NotSupportedError) Error() string {
20
+	return string(e)
21
+}
22
+
23
+// NotSupported signals that a graph-driver is not supported.
24
+func (e NotSupportedError) NotSupported() {}
25
+
26
+// IsDriverNotSupported returns true if the error initializing
27
+// the graph driver is a non-supported error.
28
+func IsDriverNotSupported(err error) bool {
29
+	switch err.(type) {
30
+	case ErrUnSupported:
31
+		return true
32
+	default:
33
+		return false
34
+	}
35
+}
... ...
@@ -42,7 +42,7 @@ func newDriver(t testing.TB, name string, options []string) *Driver {
42 42
 	d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
43 43
 	if err != nil {
44 44
 		t.Logf("graphdriver: %v\n", err)
45
-		if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
45
+		if graphdriver.IsDriverNotSupported(err) {
46 46
 			t.Skipf("Driver %s not supported", name)
47 47
 		}
48 48
 		t.Fatal(err)
... ...
@@ -138,11 +138,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
138 138
 	}
139 139
 
140 140
 	switch fsMagic {
141
-	case graphdriver.FsMagicAufs, graphdriver.FsMagicBtrfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs:
141
+	case graphdriver.FsMagicAufs, graphdriver.FsMagicBtrfs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs:
142 142
 		logrus.Errorf("'overlay' is not supported over %s", backingFs)
143 143
 		return nil, graphdriver.ErrIncompatibleFS
144 144
 	}
145 145
 
146
+	supportsDType, err := fsutils.SupportsDType(testdir)
147
+	if err != nil {
148
+		return nil, err
149
+	}
150
+	if !supportsDType {
151
+		return nil, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
152
+	}
153
+
146 154
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
147 155
 	if err != nil {
148 156
 		return nil, err
... ...
@@ -156,15 +164,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
156 156
 		return nil, err
157 157
 	}
158 158
 
159
-	supportsDType, err := fsutils.SupportsDType(home)
160
-	if err != nil {
161
-		return nil, err
162
-	}
163
-	if !supportsDType {
164
-		// not a fatal error until v17.12 (#27443)
165
-		logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
166
-	}
167
-
168 159
 	d := &Driver{
169 160
 		home:          home,
170 161
 		uidMaps:       uidMaps,
... ...
@@ -153,9 +153,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
153 153
 		backingFs = fsName
154 154
 	}
155 155
 
156
-	// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
157 156
 	switch fsMagic {
158
-	case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs:
157
+	case graphdriver.FsMagicAufs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs:
159 158
 		logrus.Errorf("'overlay2' is not supported over %s", backingFs)
160 159
 		return nil, graphdriver.ErrIncompatibleFS
161 160
 	case graphdriver.FsMagicBtrfs:
... ...
@@ -174,12 +173,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
174 174
 		if opts.overrideKernelCheck {
175 175
 			logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
176 176
 		} else {
177
-			if err := supportsMultipleLowerDir(filepath.Dir(home)); err != nil {
177
+			if err := supportsMultipleLowerDir(testdir); err != nil {
178 178
 				logrus.Debugf("Multiple lower dirs not supported: %v", err)
179 179
 				return nil, graphdriver.ErrNotSupported
180 180
 			}
181 181
 		}
182 182
 	}
183
+	supportsDType, err := fsutils.SupportsDType(testdir)
184
+	if err != nil {
185
+		return nil, err
186
+	}
187
+	if !supportsDType {
188
+		return nil, overlayutils.ErrDTypeNotSupported("overlay2", backingFs)
189
+	}
183 190
 
184 191
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
185 192
 	if err != nil {
... ...
@@ -194,15 +200,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
194 194
 		return nil, err
195 195
 	}
196 196
 
197
-	supportsDType, err := fsutils.SupportsDType(home)
198
-	if err != nil {
199
-		return nil, err
200
-	}
201
-	if !supportsDType {
202
-		// not a fatal error until v17.12 (#27443)
203
-		logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
204
-	}
205
-
206 197
 	d := &Driver{
207 198
 		home:          home,
208 199
 		uidMaps:       uidMaps,
... ...
@@ -3,8 +3,9 @@
3 3
 package overlayutils
4 4
 
5 5
 import (
6
-	"errors"
7 6
 	"fmt"
7
+
8
+	"github.com/docker/docker/daemon/graphdriver"
8 9
 )
9 10
 
10 11
 // ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type.
... ...
@@ -13,6 +14,7 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
13 13
 	if backingFs == "xfs" {
14 14
 		msg += " Reformat the filesystem with ftype=1 to enable d_type support."
15 15
 	}
16
-	msg += " Running without d_type support will no longer be supported in Docker 17.12."
17
-	return errors.New(msg)
16
+	msg += " Backing filesystems without d_type support are not supported."
17
+
18
+	return graphdriver.NotSupportedError(msg)
18 19
 }