Browse Source

Merge pull request #11799 from dqminh/aufs-dirperm1

aufs: apply dirperm1 by default if supported
Michael Crosby 10 years ago
parent
commit
14fed352cb

+ 45 - 2
daemon/graphdriver/aufs/aufs.go

@@ -23,6 +23,7 @@ package aufs
 import (
 	"bufio"
 	"fmt"
+	"io/ioutil"
 	"os"
 	"os/exec"
 	"path"
@@ -47,6 +48,9 @@ var (
 		graphdriver.FsMagicAufs,
 	}
 	backingFs = "<unknown>"
+
+	enableDirpermLock sync.Once
+	enableDirperm     bool
 )
 
 func init() {
@@ -152,6 +156,7 @@ func (a *Driver) Status() [][2]string {
 		{"Root Dir", a.rootPath()},
 		{"Backing Filesystem", backingFs},
 		{"Dirs", fmt.Sprintf("%d", len(ids))},
+		{"Dirperm1 Supported", fmt.Sprintf("%v", useDirperm())},
 	}
 }
 
@@ -422,7 +427,11 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
 	// Mount options are clipped to page size(4096 bytes). If there are more
 	// layers then these are remounted individually using append.
 
-	b := make([]byte, syscall.Getpagesize()-len(mountLabel)-54) // room for xino & mountLabel
+	offset := 54
+	if useDirperm() {
+		offset += len("dirperm1")
+	}
+	b := make([]byte, syscall.Getpagesize()-len(mountLabel)-offset) // room for xino & mountLabel
 	bp := copy(b, fmt.Sprintf("br:%s=rw", rw))
 
 	firstMount := true
@@ -446,7 +455,11 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
 		}
 
 		if firstMount {
-			data := label.FormatMountLabel(fmt.Sprintf("%s,dio,xino=/dev/shm/aufs.xino", string(b[:bp])), mountLabel)
+			opts := "dio,xino=/dev/shm/aufs.xino"
+			if useDirperm() {
+				opts += ",dirperm1"
+			}
+			data := label.FormatMountLabel(fmt.Sprintf("%s,%s", string(b[:bp]), opts), mountLabel)
 			if err = mount("none", target, "aufs", 0, data); err != nil {
 				return
 			}
@@ -460,3 +473,33 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
 
 	return
 }
+
+// useDirperm checks dirperm1 mount option can be used with the current
+// version of aufs.
+func useDirperm() bool {
+	enableDirpermLock.Do(func() {
+		base, err := ioutil.TempDir("", "docker-aufs-base")
+		if err != nil {
+			log.Errorf("error checking dirperm1: %v", err)
+			return
+		}
+		defer os.RemoveAll(base)
+
+		union, err := ioutil.TempDir("", "docker-aufs-union")
+		if err != nil {
+			log.Errorf("error checking dirperm1: %v", err)
+			return
+		}
+		defer os.RemoveAll(union)
+
+		opts := fmt.Sprintf("br:%s,dirperm1,xino=/dev/shm/aufs.xino", base)
+		if err := mount("none", union, "aufs", 0, opts); err != nil {
+			return
+		}
+		enableDirperm = true
+		if err := Unmount(union); err != nil {
+			log.Errorf("error checking dirperm1: failed to unmount %v", err)
+		}
+	})
+	return enableDirperm
+}

+ 8 - 2
docs/sources/reference/builder.md

@@ -280,8 +280,14 @@ The cache for `RUN` instructions can be invalidated by `ADD` instructions. See
 
 - [Issue 783](https://github.com/docker/docker/issues/783) is about file
   permissions problems that can occur when using the AUFS file system. You
-  might notice it during an attempt to `rm` a file, for example. The issue
-  describes a workaround.
+  might notice it during an attempt to `rm` a file, for example.
+
+  For systems that have recent aufs version (i.e., `dirperm1` mount option can
+  be set), docker will attempt to fix the issue automatically by mounting
+  the layers with `dirperm1` option. More details on `dirperm1` option can be
+  found at [`aufs` man page](http://aufs.sourceforge.net/aufs3/man.html)
+
+  If your system doesnt have support for `dirperm1`, the issue describes a workaround.
 
 ## CMD
 

+ 8 - 1
docs/sources/release-notes.md

@@ -57,7 +57,14 @@ impact on users. This list will be updated as issues are resolved.
 * **Unexpected File Permissions in Containers**
 An idiosyncrasy in AUFS prevents permissions from propagating predictably
 between upper and lower layers. This can cause issues with accessing private
-keys, database instances, etc. For complete information and workarounds see
+keys, database instances, etc.
+
+For systems that have recent aufs version (i.e., `dirperm1` mount option can
+be set), docker will attempt to fix the issue automatically by mounting
+the layers with `dirperm1` option. More details on `dirperm1` option can be
+found at [`aufs` man page](http://aufs.sourceforge.net/aufs3/man.html)
+
+For complete information and workarounds see
 [Github Issue 783](https://github.com/docker/docker/issues/783).
 
 * **Docker Hub incompatible with Safari 8**