Browse code

Merge pull request #35527 from thaJeztah/feature-detect-overlay2

Detect overlay2 support on pre-4.0 kernels

Victor Vieux authored on 2017/11/30 06:51:26
Showing 2 changed files
... ...
@@ -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