Merge pull request #35514 from thaJeztah/disable-overlay-without-d_type

Remove support for overlay/overlay2 without d_type
Upstream-commit: bd8a9c25ee257384ca24cf32e61b6b0ef71f521d
Component: engine
This commit is contained in:
Victor Vieux
2017-12-06 14:13:58 -08:00
committed by GitHub
9 changed files with 124 additions and 49 deletions
@@ -89,7 +89,16 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, graphdriver.ErrNotSupported
}
fsMagic, err := graphdriver.GetFSMagic(root)
// Perform feature detection on /var/lib/docker/aufs if it's an existing directory.
// This covers situations where /var/lib/docker/aufs is a mount, and on a different
// filesystem than /var/lib/docker.
// If the path does not exist, fall back to using /var/lib/docker for feature detection.
testdir := root
if _, err := os.Stat(testdir); os.IsNotExist(err) {
testdir = filepath.Dir(testdir)
}
fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil {
return nil, err
}
@@ -51,7 +51,16 @@ type btrfsOptions struct {
// An error is returned if BTRFS is not supported.
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
fsMagic, err := graphdriver.GetFSMagic(home)
// Perform feature detection on /var/lib/docker/btrfs if it's an existing directory.
// This covers situations where /var/lib/docker/btrfs is a mount, and on a different
// filesystem than /var/lib/docker.
// If the path does not exist, fall back to using /var/lib/docker for feature detection.
testdir := home
if _, err := os.Stat(testdir); os.IsNotExist(err) {
testdir = filepath.Dir(testdir)
}
fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil {
return nil, err
}
+14 -16
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)
@@ -291,6 +277,18 @@ func scanPriorDrivers(root string) map[string]bool {
return driversMap
}
// IsInitialized checks if the driver's home-directory exists and is non-empty.
func IsInitialized(driverHome string) bool {
_, err := os.Stat(driverHome)
if os.IsNotExist(err) {
return false
}
if err != nil {
logrus.Warnf("graphdriver.IsInitialized: stat failed: %v", err)
}
return !isEmptyDir(driverHome)
}
// isEmptyDir checks if a directory is empty. It is used to check if prior
// storage-driver directories exist. If an error occurs, it also assumes the
// directory is not empty (which preserves the behavior _before_ this check
@@ -3,8 +3,6 @@
package graphdriver
import (
"path/filepath"
"github.com/docker/docker/pkg/mount"
"golang.org/x/sys/unix"
)
@@ -82,7 +80,7 @@ var (
// GetFSMagic returns the filesystem id given the path.
func GetFSMagic(rootpath string) (FsMagic, error) {
var buf unix.Statfs_t
if err := unix.Statfs(filepath.Dir(rootpath), &buf); err != nil {
if err := unix.Statfs(rootpath, &buf); err != nil {
return 0, err
}
return FsMagic(buf.Type), nil
@@ -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
}
}
@@ -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)
@@ -10,6 +10,7 @@ import (
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"github.com/docker/docker/daemon/graphdriver"
@@ -119,7 +120,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, graphdriver.ErrNotSupported
}
fsMagic, err := graphdriver.GetFSMagic(home)
// Perform feature detection on /var/lib/docker/overlay if it's an existing directory.
// This covers situations where /var/lib/docker/overlay is a mount, and on a different
// filesystem than /var/lib/docker.
// If the path does not exist, fall back to using /var/lib/docker for feature detection.
testdir := home
if _, err := os.Stat(testdir); os.IsNotExist(err) {
testdir = filepath.Dir(testdir)
}
fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil {
return nil, err
}
@@ -128,11 +138,23 @@ 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 {
if !graphdriver.IsInitialized(home) {
return nil, overlayutils.ErrDTypeNotSupported("overlay", backingFs)
}
// allow running without d_type only for existing setups (#27443)
logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs))
}
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
if err != nil {
return nil, err
@@ -146,15 +168,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,
@@ -136,7 +136,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err
}
fsMagic, err := graphdriver.GetFSMagic(home)
// Perform feature detection on /var/lib/docker/overlay2 if it's an existing directory.
// This covers situations where /var/lib/docker/overlay2 is a mount, and on a different
// filesystem than /var/lib/docker.
// If the path does not exist, fall back to using /var/lib/docker for feature detection.
testdir := home
if _, err := os.Stat(testdir); os.IsNotExist(err) {
testdir = filepath.Dir(testdir)
}
fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil {
return nil, err
}
@@ -144,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:
@@ -165,12 +173,23 @@ 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 {
if !graphdriver.IsInitialized(home) {
return nil, overlayutils.ErrDTypeNotSupported("overlay2", backingFs)
}
// allow running without d_type only for existing setups (#27443)
logrus.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs))
}
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps)
if err != nil {
@@ -185,15 +204,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,
@@ -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)
}