Procházet zdrojové kódy

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 před 7 roky
rodič
revize
0abb8dec3f

+ 2 - 16
daemon/graphdriver/driver.go

@@ -1,7 +1,6 @@
 package graphdriver
 package graphdriver
 
 
 import (
 import (
-	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"os"
 	"os"
@@ -28,13 +27,6 @@ const (
 var (
 var (
 	// All registered drivers
 	// All registered drivers
 	drivers map[string]InitFunc
 	drivers map[string]InitFunc
-
-	// ErrNotSupported returned when driver is not supported.
-	ErrNotSupported = errors.New("driver not supported")
-	// ErrPrerequisites returned when driver does not meet prerequisites.
-	ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
-	// ErrIncompatibleFS returned when file system is not supported.
-	ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
 )
 )
 
 
 //CreateOpts contains optional arguments for Create() and CreateReadWrite()
 //CreateOpts contains optional arguments for Create() and CreateReadWrite()
@@ -248,7 +240,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
 	for _, name := range list {
 	for _, name := range list {
 		driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
 		driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
 		if err != nil {
 		if err != nil {
-			if isDriverNotSupported(err) {
+			if IsDriverNotSupported(err) {
 				continue
 				continue
 			}
 			}
 			return nil, err
 			return nil, err
@@ -260,7 +252,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
 	for name, initFunc := range drivers {
 	for name, initFunc := range drivers {
 		driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
 		driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
 		if err != nil {
 		if err != nil {
-			if isDriverNotSupported(err) {
+			if IsDriverNotSupported(err) {
 				continue
 				continue
 			}
 			}
 			return nil, err
 			return nil, err
@@ -270,12 +262,6 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
 	return nil, fmt.Errorf("No supported storage backend found")
 	return nil, fmt.Errorf("No supported storage backend found")
 }
 }
 
 
-// isDriverNotSupported returns true if the error initializing
-// the graph driver is a non-supported error.
-func isDriverNotSupported(err error) bool {
-	return err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS
-}
-
 // scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
 // scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
 func scanPriorDrivers(root string) map[string]bool {
 func scanPriorDrivers(root string) map[string]bool {
 	driversMap := make(map[string]bool)
 	driversMap := make(map[string]bool)

+ 36 - 0
daemon/graphdriver/errors.go

@@ -0,0 +1,36 @@
+package graphdriver
+
+const (
+	// ErrNotSupported returned when driver is not supported.
+	ErrNotSupported NotSupportedError = "driver not supported"
+	// ErrPrerequisites returned when driver does not meet prerequisites.
+	ErrPrerequisites NotSupportedError = "prerequisites for driver not satisfied (wrong filesystem?)"
+	// ErrIncompatibleFS returned when file system is not supported.
+	ErrIncompatibleFS NotSupportedError = "backing file system is unsupported for this graph driver"
+)
+
+// ErrUnSupported signals that the graph-driver is not supported on the current configuration
+type ErrUnSupported interface {
+	NotSupported()
+}
+
+// NotSupportedError signals that the graph-driver is not supported on the current configuration
+type NotSupportedError string
+
+func (e NotSupportedError) Error() string {
+	return string(e)
+}
+
+// NotSupported signals that a graph-driver is not supported.
+func (e NotSupportedError) NotSupported() {}
+
+// IsDriverNotSupported returns true if the error initializing
+// the graph driver is a non-supported error.
+func IsDriverNotSupported(err error) bool {
+	switch err.(type) {
+	case ErrUnSupported:
+		return true
+	default:
+		return false
+	}
+}

+ 1 - 1
daemon/graphdriver/graphtest/graphtest_unix.go

@@ -42,7 +42,7 @@ func newDriver(t testing.TB, name string, options []string) *Driver {
 	d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
 	d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
 	if err != nil {
 	if err != nil {
 		t.Logf("graphdriver: %v\n", err)
 		t.Logf("graphdriver: %v\n", err)
-		if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
+		if graphdriver.IsDriverNotSupported(err) {
 			t.Skipf("Driver %s not supported", name)
 			t.Skipf("Driver %s not supported", name)
 		}
 		}
 		t.Fatal(err)
 		t.Fatal(err)

+ 9 - 10
daemon/graphdriver/overlay/overlay.go

@@ -138,11 +138,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 	}
 	}
 
 
 	switch fsMagic {
 	switch fsMagic {
-	case graphdriver.FsMagicAufs, graphdriver.FsMagicBtrfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs:
+	case graphdriver.FsMagicAufs, graphdriver.FsMagicBtrfs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs:
 		logrus.Errorf("'overlay' is not supported over %s", backingFs)
 		logrus.Errorf("'overlay' is not supported over %s", backingFs)
 		return nil, graphdriver.ErrIncompatibleFS
 		return nil, graphdriver.ErrIncompatibleFS
 	}
 	}
 
 
+	supportsDType, err := fsutils.SupportsDType(testdir)
+	if err != nil {
+		return nil, err
+	}
+	if !supportsDType {
+		return nil, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
+	}
+
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -156,15 +164,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	supportsDType, err := fsutils.SupportsDType(home)
-	if err != nil {
-		return nil, err
-	}
-	if !supportsDType {
-		// not a fatal error until v17.12 (#27443)
-		logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
-	}
-
 	d := &Driver{
 	d := &Driver{
 		home:          home,
 		home:          home,
 		uidMaps:       uidMaps,
 		uidMaps:       uidMaps,

+ 9 - 12
daemon/graphdriver/overlay2/overlay.go

@@ -153,9 +153,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 		backingFs = fsName
 		backingFs = fsName
 	}
 	}
 
 
-	// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
 	switch fsMagic {
 	switch fsMagic {
-	case graphdriver.FsMagicAufs, graphdriver.FsMagicZfs, graphdriver.FsMagicOverlay, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs:
+	case graphdriver.FsMagicAufs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs:
 		logrus.Errorf("'overlay2' is not supported over %s", backingFs)
 		logrus.Errorf("'overlay2' is not supported over %s", backingFs)
 		return nil, graphdriver.ErrIncompatibleFS
 		return nil, graphdriver.ErrIncompatibleFS
 	case graphdriver.FsMagicBtrfs:
 	case graphdriver.FsMagicBtrfs:
@@ -174,12 +173,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 		if opts.overrideKernelCheck {
 		if opts.overrideKernelCheck {
 			logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
 			logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
 		} else {
 		} else {
-			if err := supportsMultipleLowerDir(filepath.Dir(home)); err != nil {
+			if err := supportsMultipleLowerDir(testdir); err != nil {
 				logrus.Debugf("Multiple lower dirs not supported: %v", err)
 				logrus.Debugf("Multiple lower dirs not supported: %v", err)
 				return nil, graphdriver.ErrNotSupported
 				return nil, graphdriver.ErrNotSupported
 			}
 			}
 		}
 		}
 	}
 	}
+	supportsDType, err := fsutils.SupportsDType(testdir)
+	if err != nil {
+		return nil, err
+	}
+	if !supportsDType {
+		return nil, overlayutils.ErrDTypeNotSupported("overlay2", backingFs)
+	}
 
 
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
 	rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
 	if err != nil {
 	if err != nil {
@@ -194,15 +200,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	supportsDType, err := fsutils.SupportsDType(home)
-	if err != nil {
-		return nil, err
-	}
-	if !supportsDType {
-		// not a fatal error until v17.12 (#27443)
-		logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
-	}
-
 	d := &Driver{
 	d := &Driver{
 		home:          home,
 		home:          home,
 		uidMaps:       uidMaps,
 		uidMaps:       uidMaps,

+ 5 - 3
daemon/graphdriver/overlayutils/overlayutils.go

@@ -3,8 +3,9 @@
 package overlayutils
 package overlayutils
 
 
 import (
 import (
-	"errors"
 	"fmt"
 	"fmt"
+
+	"github.com/docker/docker/daemon/graphdriver"
 )
 )
 
 
 // ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type.
 // ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type.
@@ -13,6 +14,7 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
 	if backingFs == "xfs" {
 	if backingFs == "xfs" {
 		msg += " Reformat the filesystem with ftype=1 to enable d_type support."
 		msg += " Reformat the filesystem with ftype=1 to enable d_type support."
 	}
 	}
-	msg += " Running without d_type support will no longer be supported in Docker 17.12."
-	return errors.New(msg)
+	msg += " Backing filesystems without d_type support are not supported."
+
+	return graphdriver.NotSupportedError(msg)
 }
 }