Detect overlay2 support on pre-4.0 kernels
| ... | ... |
@@ -100,3 +100,35 @@ func doesSupportNativeDiff(d string) error {
|
| 100 | 100 |
|
| 101 | 101 |
return nil |
| 102 | 102 |
} |
| 103 |
+ |
|
| 104 |
+// supportsMultipleLowerDir checks if the system supports multiple lowerdirs, |
|
| 105 |
+// which is required for the overlay2 driver. On 4.x kernels, multiple lowerdirs |
|
| 106 |
+// are always available (so this check isn't needed), and backported to RHEL and |
|
| 107 |
+// CentOS 3.x kernels (3.10.0-693.el7.x86_64 and up). This function is to detect |
|
| 108 |
+// support on those kernels, without doing a kernel version compare. |
|
| 109 |
+func supportsMultipleLowerDir(d string) error {
|
|
| 110 |
+ td, err := ioutil.TempDir(d, "multiple-lowerdir-check") |
|
| 111 |
+ if err != nil {
|
|
| 112 |
+ return err |
|
| 113 |
+ } |
|
| 114 |
+ defer func() {
|
|
| 115 |
+ if err := os.RemoveAll(td); err != nil {
|
|
| 116 |
+ logrus.Warnf("Failed to remove check directory %v: %v", td, err)
|
|
| 117 |
+ } |
|
| 118 |
+ }() |
|
| 119 |
+ |
|
| 120 |
+ for _, dir := range []string{"lower1", "lower2", "upper", "work", "merged"} {
|
|
| 121 |
+ if err := os.Mkdir(filepath.Join(td, dir), 0755); err != nil {
|
|
| 122 |
+ return err |
|
| 123 |
+ } |
|
| 124 |
+ } |
|
| 125 |
+ |
|
| 126 |
+ 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"))
|
|
| 127 |
+ if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", 0, opts); err != nil {
|
|
| 128 |
+ return errors.Wrap(err, "failed to mount overlay") |
|
| 129 |
+ } |
|
| 130 |
+ if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil {
|
|
| 131 |
+ logrus.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
|
|
| 132 |
+ } |
|
| 133 |
+ return nil |
|
| 134 |
+} |
| ... | ... |
@@ -16,8 +16,6 @@ import ( |
| 16 | 16 |
"strings" |
| 17 | 17 |
"sync" |
| 18 | 18 |
|
| 19 |
- "github.com/sirupsen/logrus" |
|
| 20 |
- |
|
| 21 | 19 |
"github.com/docker/docker/daemon/graphdriver" |
| 22 | 20 |
"github.com/docker/docker/daemon/graphdriver/overlayutils" |
| 23 | 21 |
"github.com/docker/docker/daemon/graphdriver/quota" |
| ... | ... |
@@ -32,9 +30,9 @@ import ( |
| 32 | 32 |
"github.com/docker/docker/pkg/parsers" |
| 33 | 33 |
"github.com/docker/docker/pkg/parsers/kernel" |
| 34 | 34 |
"github.com/docker/docker/pkg/system" |
| 35 |
- units "github.com/docker/go-units" |
|
| 36 |
- |
|
| 35 |
+ "github.com/docker/go-units" |
|
| 37 | 36 |
"github.com/opencontainers/selinux/go-selinux/label" |
| 37 |
+ "github.com/sirupsen/logrus" |
|
| 38 | 38 |
"golang.org/x/sys/unix" |
| 39 | 39 |
) |
| 40 | 40 |
|
| ... | ... |
@@ -137,12 +135,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap |
| 137 | 137 |
if err != nil {
|
| 138 | 138 |
return nil, err |
| 139 | 139 |
} |
| 140 |
- if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 0, Minor: 0}) < 0 {
|
|
| 141 |
- if !opts.overrideKernelCheck {
|
|
| 142 |
- return nil, graphdriver.ErrNotSupported |
|
| 143 |
- } |
|
| 144 |
- logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
|
|
| 145 |
- } |
|
| 146 | 140 |
|
| 147 | 141 |
fsMagic, err := graphdriver.GetFSMagic(home) |
| 148 | 142 |
if err != nil {
|
| ... | ... |
@@ -169,6 +161,17 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap |
| 169 | 169 |
} |
| 170 | 170 |
} |
| 171 | 171 |
|
| 172 |
+ if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 0, Minor: 0}) < 0 {
|
|
| 173 |
+ if opts.overrideKernelCheck {
|
|
| 174 |
+ logrus.Warn("Using pre-4.0.0 kernel for overlay2, mount failures may require kernel update")
|
|
| 175 |
+ } else {
|
|
| 176 |
+ if err := supportsMultipleLowerDir(filepath.Dir(home)); err != nil {
|
|
| 177 |
+ logrus.Debugf("Multiple lower dirs not supported: %v", err)
|
|
| 178 |
+ return nil, graphdriver.ErrNotSupported |
|
| 179 |
+ } |
|
| 180 |
+ } |
|
| 181 |
+ } |
|
| 182 |
+ |
|
| 172 | 183 |
rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) |
| 173 | 184 |
if err != nil {
|
| 174 | 185 |
return nil, err |