Fix/improve overlay support check

Before this commit, overlay check was performed by looking for
`overlay` in /proc/filesystem. This obviously might not work
for rootless Docker (fs is there, but one can't use it as non-root).

This commit changes the check to perform the actual mount, by reusing
the code previously written to check for multiple lower dirs support.

The old check is removed from both drivers, as well as the additional
check for the multiple lower dirs support in overlay2 since it's now
a part of the main check.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin 2019-11-07 15:03:29 -08:00
parent d5687079ad
commit 649e4c8889
3 changed files with 22 additions and 82 deletions

View File

@ -3,7 +3,6 @@
package overlay // import "github.com/docker/docker/daemon/graphdriver/overlay" package overlay // import "github.com/docker/docker/daemon/graphdriver/overlay"
import ( import (
"bufio"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -123,10 +122,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err 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. // 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 // This covers situations where /var/lib/docker/overlay is a mount, and on a different
// filesystem than /var/lib/docker. // filesystem than /var/lib/docker.
@ -136,6 +131,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
testdir = filepath.Dir(testdir) 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) fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil { if err != nil {
return nil, err return nil, err
@ -199,33 +199,6 @@ func parseOptions(options []string) (*overlayOptions, error) {
return o, nil 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 { func (d *Driver) String() string {
return "overlay" return "overlay"
} }

View File

@ -3,7 +3,6 @@
package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2" package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2"
import ( import (
"bufio"
"context" "context"
"errors" "errors"
"fmt" "fmt"
@ -133,10 +132,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, err return nil, err
} }
if err := supportsOverlay(); err != nil {
return nil, graphdriver.ErrNotSupported
}
// require kernel 4.0.0 to ensure multiple lower dirs are supported // require kernel 4.0.0 to ensure multiple lower dirs are supported
v, err := kernel.GetKernelVersion() v, err := kernel.GetKernelVersion()
if err != nil { if err != nil {
@ -152,6 +147,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
testdir = filepath.Dir(testdir) testdir = filepath.Dir(testdir)
} }
if err := overlayutils.SupportsOverlay(testdir, true); err != nil {
logger.Error(err)
return nil, graphdriver.ErrNotSupported
}
fsMagic, err := graphdriver.GetFSMagic(testdir) fsMagic, err := graphdriver.GetFSMagic(testdir)
if err != nil { if err != nil {
return nil, err 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) supportsDType, err := fsutils.SupportsDType(testdir)
if err != nil { if err != nil {
return nil, err return nil, err
@ -274,33 +264,6 @@ func parseOptions(options []string) (*overlayOptions, error) {
return o, nil 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 { func useNaiveDiff(home string) bool {
useNaiveDiffLock.Do(func() { useNaiveDiffLock.Do(func() {
if err := doesSupportNativeDiff(home); err != nil { if err := doesSupportNativeDiff(home); err != nil {

View File

@ -31,13 +31,13 @@ func ErrDTypeNotSupported(driver, backingFs string) error {
return graphdriver.NotSupportedError(msg) return graphdriver.NotSupportedError(msg)
} }
// SupportsMultipleLowerDir checks if the system supports multiple lowerdirs, // SupportsOverlay checks if the system supports overlay filesystem
// which is required for the overlay2 driver. On 4.x kernels, multiple lowerdirs // by performing an actual overlay mount.
// 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 // checkMultipleLowers parameter enables check for multiple lowerdirs,
// support on those kernels, without doing a kernel version compare. // which is required for the overlay2 driver.
func SupportsMultipleLowerDir(d string) error { func SupportsOverlay(d string, checkMultipleLowers bool) error {
td, err := ioutil.TempDir(d, "multiple-lowerdir-check") td, err := ioutil.TempDir(d, "check-overlayfs-support")
if err != nil { if err != nil {
return err return err
} }
@ -54,7 +54,11 @@ func SupportsMultipleLowerDir(d string) error {
} }
mnt := filepath.Join(td, "merged") 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 { if err := unix.Mount("overlay", mnt, "overlay", 0, opts); err != nil {
return errors.Wrap(err, "failed to mount overlay") return errors.Wrap(err, "failed to mount overlay")
} }