Browse code

Perform fsmagic detection on driver's home-dir if it exists

The fsmagic check was always performed on "data-root" (`/var/lib/docker`),
not on the storage-driver's home directory (e.g. `/var/lib/docker/<somedriver>`).

This caused detection to be done on the wrong filesystem in situations
where `/var/lib/docker/<somedriver>` was a mount, and a different
filesystem than `/var/lib/docker` itself.

This patch checks if the storage-driver's home directory exists, and only
falls back to `/var/lib/docker` if it doesn't exist.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2017/12/05 07:45:26
Showing 5 changed files
... ...
@@ -89,7 +89,16 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
89 89
 		return nil, graphdriver.ErrNotSupported
90 90
 	}
91 91
 
92
-	fsMagic, err := graphdriver.GetFSMagic(root)
92
+	// Perform feature detection on /var/lib/docker/aufs if it's an existing directory.
93
+	// This covers situations where /var/lib/docker/aufs is a mount, and on a different
94
+	// filesystem than /var/lib/docker.
95
+	// If the path does not exist, fall back to using /var/lib/docker for feature detection.
96
+	testdir := root
97
+	if _, err := os.Stat(testdir); os.IsNotExist(err) {
98
+		testdir = filepath.Dir(testdir)
99
+	}
100
+
101
+	fsMagic, err := graphdriver.GetFSMagic(testdir)
93 102
 	if err != nil {
94 103
 		return nil, err
95 104
 	}
... ...
@@ -51,7 +51,16 @@ type btrfsOptions struct {
51 51
 // An error is returned if BTRFS is not supported.
52 52
 func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
53 53
 
54
-	fsMagic, err := graphdriver.GetFSMagic(home)
54
+	// Perform feature detection on /var/lib/docker/btrfs if it's an existing directory.
55
+	// This covers situations where /var/lib/docker/btrfs is a mount, and on a different
56
+	// filesystem than /var/lib/docker.
57
+	// If the path does not exist, fall back to using /var/lib/docker for feature detection.
58
+	testdir := home
59
+	if _, err := os.Stat(testdir); os.IsNotExist(err) {
60
+		testdir = filepath.Dir(testdir)
61
+	}
62
+
63
+	fsMagic, err := graphdriver.GetFSMagic(testdir)
55 64
 	if err != nil {
56 65
 		return nil, err
57 66
 	}
... ...
@@ -3,8 +3,6 @@
3 3
 package graphdriver
4 4
 
5 5
 import (
6
-	"path/filepath"
7
-
8 6
 	"github.com/docker/docker/pkg/mount"
9 7
 	"golang.org/x/sys/unix"
10 8
 )
... ...
@@ -82,7 +80,7 @@ var (
82 82
 // GetFSMagic returns the filesystem id given the path.
83 83
 func GetFSMagic(rootpath string) (FsMagic, error) {
84 84
 	var buf unix.Statfs_t
85
-	if err := unix.Statfs(filepath.Dir(rootpath), &buf); err != nil {
85
+	if err := unix.Statfs(rootpath, &buf); err != nil {
86 86
 		return 0, err
87 87
 	}
88 88
 	return FsMagic(buf.Type), nil
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"os"
11 11
 	"os/exec"
12 12
 	"path"
13
+	"path/filepath"
13 14
 	"strconv"
14 15
 
15 16
 	"github.com/docker/docker/daemon/graphdriver"
... ...
@@ -119,7 +120,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
119 119
 		return nil, graphdriver.ErrNotSupported
120 120
 	}
121 121
 
122
-	fsMagic, err := graphdriver.GetFSMagic(home)
122
+	// Perform feature detection on /var/lib/docker/overlay if it's an existing directory.
123
+	// This covers situations where /var/lib/docker/overlay is a mount, and on a different
124
+	// filesystem than /var/lib/docker.
125
+	// If the path does not exist, fall back to using /var/lib/docker for feature detection.
126
+	testdir := home
127
+	if _, err := os.Stat(testdir); os.IsNotExist(err) {
128
+		testdir = filepath.Dir(testdir)
129
+	}
130
+
131
+	fsMagic, err := graphdriver.GetFSMagic(testdir)
123 132
 	if err != nil {
124 133
 		return nil, err
125 134
 	}
... ...
@@ -136,7 +136,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
136 136
 		return nil, err
137 137
 	}
138 138
 
139
-	fsMagic, err := graphdriver.GetFSMagic(home)
139
+	// Perform feature detection on /var/lib/docker/overlay2 if it's an existing directory.
140
+	// This covers situations where /var/lib/docker/overlay2 is a mount, and on a different
141
+	// filesystem than /var/lib/docker.
142
+	// If the path does not exist, fall back to using /var/lib/docker for feature detection.
143
+	testdir := home
144
+	if _, err := os.Stat(testdir); os.IsNotExist(err) {
145
+		testdir = filepath.Dir(testdir)
146
+	}
147
+
148
+	fsMagic, err := graphdriver.GetFSMagic(testdir)
140 149
 	if err != nil {
141 150
 		return nil, err
142 151
 	}