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>
This commit is contained in:
Sebastiaan van Stijn 2017-11-16 01:48:43 +01:00
parent f9c8fa305e
commit 0abb8dec3f
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 62 additions and 42 deletions

View file

@ -1,7 +1,6 @@
package graphdriver
import (
"errors"
"fmt"
"io"
"os"
@ -28,13 +27,6 @@ const (
var (
// All registered drivers
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()
@ -248,7 +240,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
for _, name := range list {
driver, err := getBuiltinDriver(name, config.Root, config.DriverOptions, config.UIDMaps, config.GIDMaps)
if err != nil {
if isDriverNotSupported(err) {
if IsDriverNotSupported(err) {
continue
}
return nil, err
@ -260,7 +252,7 @@ func New(name string, pg plugingetter.PluginGetter, config Options) (Driver, err
for name, initFunc := range drivers {
driver, err := initFunc(filepath.Join(config.Root, name), config.DriverOptions, config.UIDMaps, config.GIDMaps)
if err != nil {
if isDriverNotSupported(err) {
if IsDriverNotSupported(err) {
continue
}
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")
}
// 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
func scanPriorDrivers(root string) map[string]bool {
driversMap := make(map[string]bool)

View file

@ -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
}
}

View file

@ -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})
if err != nil {
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.Fatal(err)

View file

@ -138,11 +138,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
}
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)
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)
if err != nil {
return nil, err
@ -156,15 +164,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
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{
home: home,
uidMaps: uidMaps,

View file

@ -153,9 +153,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
backingFs = fsName
}
// check if they are running over btrfs, aufs, zfs, overlay, or ecryptfs
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)
return nil, graphdriver.ErrIncompatibleFS
case graphdriver.FsMagicBtrfs:
@ -174,12 +173,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
if opts.overrideKernelCheck {
logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
} else {
if err := supportsMultipleLowerDir(filepath.Dir(home)); err != nil {
if err := supportsMultipleLowerDir(testdir); err != nil {
logrus.Debugf("Multiple lower dirs not supported: %v", err)
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)
if err != nil {
@ -194,15 +200,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
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{
home: home,
uidMaps: uidMaps,

View file

@ -3,8 +3,9 @@
package overlayutils
import (
"errors"
"fmt"
"github.com/docker/docker/daemon/graphdriver"
)
// ErrDTypeNotSupported denotes that the backing filesystem doesn't support d_type.
@ -13,6 +14,7 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
if backingFs == "xfs" {
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)
}