diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go index eda0d7cd53..1d850ed186 100644 --- a/daemon/graphdriver/overlay/overlay.go +++ b/daemon/graphdriver/overlay/overlay.go @@ -3,7 +3,6 @@ package overlay // import "github.com/docker/docker/daemon/graphdriver/overlay" import ( - "bufio" "fmt" "io" "io/ioutil" @@ -123,10 +122,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap return nil, err } - if err := supportsOverlay(); err != nil { - return nil, graphdriver.ErrNotSupported - } - // 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. @@ -136,6 +131,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap testdir = filepath.Dir(testdir) } + if err := overlayutils.SupportsOverlay(testdir, false); err != nil { + logrus.WithField("storage-driver", "overlay").Error(err) + return nil, graphdriver.ErrNotSupported + } + fsMagic, err := graphdriver.GetFSMagic(testdir) if err != nil { return nil, err @@ -199,33 +199,6 @@ func parseOptions(options []string) (*overlayOptions, error) { return o, nil } -func supportsOverlay() error { - // Access overlay filesystem so that Linux loads it (if possible). - mountTarget, err := ioutil.TempDir("", "supportsOverlay") - if err != nil { - logrus.WithError(err).WithField("storage-driver", "overlay2").Error("could not create temporary directory, so assuming that 'overlay' is not supported") - return graphdriver.ErrNotSupported - } - /* The mounting will fail--after the module has been loaded.*/ - defer os.RemoveAll(mountTarget) - unix.Mount("overlay", mountTarget, "overlay", 0, "") - - f, err := os.Open("/proc/filesystems") - if err != nil { - return err - } - defer f.Close() - - s := bufio.NewScanner(f) - for s.Scan() { - if s.Text() == "nodev\toverlay" { - return nil - } - } - logrus.WithField("storage-driver", "overlay").Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.") - return graphdriver.ErrNotSupported -} - func (d *Driver) String() string { return "overlay" } diff --git a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go index 751e1cf186..d257e942d1 100644 --- a/daemon/graphdriver/overlay2/overlay.go +++ b/daemon/graphdriver/overlay2/overlay.go @@ -3,7 +3,6 @@ package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2" import ( - "bufio" "context" "errors" "fmt" @@ -133,10 +132,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap return nil, err } - if err := supportsOverlay(); err != nil { - return nil, graphdriver.ErrNotSupported - } - // require kernel 4.0.0 to ensure multiple lower dirs are supported v, err := kernel.GetKernelVersion() if err != nil { @@ -152,6 +147,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap testdir = filepath.Dir(testdir) } + if err := overlayutils.SupportsOverlay(testdir, true); err != nil { + logger.Error(err) + return nil, graphdriver.ErrNotSupported + } + fsMagic, err := graphdriver.GetFSMagic(testdir) if err != nil { return nil, err @@ -176,16 +176,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap } } - if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 0, Minor: 0}) < 0 { - if opts.overrideKernelCheck { - logger.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update") - } else { - if err := overlayutils.SupportsMultipleLowerDir(testdir); err != nil { - logger.Debugf("Multiple lower dirs not supported: %v", err) - return nil, graphdriver.ErrNotSupported - } - } - } supportsDType, err := fsutils.SupportsDType(testdir) if err != nil { return nil, err @@ -274,33 +264,6 @@ func parseOptions(options []string) (*overlayOptions, error) { return o, nil } -func supportsOverlay() error { - // Access overlay filesystem so that Linux loads it (if possible). - mountTarget, err := ioutil.TempDir("", "supportsOverlay2") - if err != nil { - logrus.WithError(err).WithField("storage-driver", "overlay2").Error("could not create temporary directory, so assuming that 'overlay' is not supported") - return graphdriver.ErrNotSupported - } - /* The mounting will fail--after the module has been loaded.*/ - defer os.RemoveAll(mountTarget) - unix.Mount("overlay", mountTarget, "overlay", 0, "") - - f, err := os.Open("/proc/filesystems") - if err != nil { - return err - } - defer f.Close() - - s := bufio.NewScanner(f) - for s.Scan() { - if s.Text() == "nodev\toverlay" { - return nil - } - } - logger.Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.") - return graphdriver.ErrNotSupported -} - func useNaiveDiff(home string) bool { useNaiveDiffLock.Do(func() { if err := doesSupportNativeDiff(home); err != nil { diff --git a/daemon/graphdriver/overlayutils/overlayutils.go b/daemon/graphdriver/overlayutils/overlayutils.go index 3cd6b2a2a4..e0553a09f7 100644 --- a/daemon/graphdriver/overlayutils/overlayutils.go +++ b/daemon/graphdriver/overlayutils/overlayutils.go @@ -31,13 +31,13 @@ func ErrDTypeNotSupported(driver, backingFs string) error { return graphdriver.NotSupportedError(msg) } -// SupportsMultipleLowerDir checks if the system supports multiple lowerdirs, -// which is required for the overlay2 driver. On 4.x kernels, multiple lowerdirs -// are always available (so this check isn't needed), and backported to RHEL and -// CentOS 3.x kernels (3.10.0-693.el7.x86_64 and up). This function is to detect -// support on those kernels, without doing a kernel version compare. -func SupportsMultipleLowerDir(d string) error { - td, err := ioutil.TempDir(d, "multiple-lowerdir-check") +// SupportsOverlay checks if the system supports overlay filesystem +// by performing an actual overlay mount. +// +// checkMultipleLowers parameter enables check for multiple lowerdirs, +// which is required for the overlay2 driver. +func SupportsOverlay(d string, checkMultipleLowers bool) error { + td, err := ioutil.TempDir(d, "check-overlayfs-support") if err != nil { return err } @@ -54,7 +54,11 @@ func SupportsMultipleLowerDir(d string) error { } mnt := filepath.Join(td, "merged") - opts := fmt.Sprintf("lowerdir=%s:%s,upperdir=%s,workdir=%s", path.Join(td, "lower2"), path.Join(td, "lower1"), path.Join(td, "upper"), path.Join(td, "work")) + lowerDir := path.Join(td, "lower2") + if checkMultipleLowers { + lowerDir += ":" + path.Join(td, "lower1") + } + opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, path.Join(td, "upper"), path.Join(td, "work")) if err := unix.Mount("overlay", mnt, "overlay", 0, opts); err != nil { return errors.Wrap(err, "failed to mount overlay") }