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 (
 import (
 	"bufio"
 	"bufio"
 	"fmt"
 	"fmt"
+	"io/ioutil"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"path"
 	"path"
@@ -47,6 +48,9 @@ var (
 		graphdriver.FsMagicAufs,
 		graphdriver.FsMagicAufs,
 	}
 	}
 	backingFs = "<unknown>"
 	backingFs = "<unknown>"
+
+	enableDirpermLock sync.Once
+	enableDirperm     bool
 )
 )
 
 
 func init() {
 func init() {
@@ -152,6 +156,7 @@ func (a *Driver) Status() [][2]string {
 		{"Root Dir", a.rootPath()},
 		{"Root Dir", a.rootPath()},
 		{"Backing Filesystem", backingFs},
 		{"Backing Filesystem", backingFs},
 		{"Dirs", fmt.Sprintf("%d", len(ids))},
 		{"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
 	// Mount options are clipped to page size(4096 bytes). If there are more
 	// layers then these are remounted individually using append.
 	// 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))
 	bp := copy(b, fmt.Sprintf("br:%s=rw", rw))
 
 
 	firstMount := true
 	firstMount := true
@@ -446,7 +455,11 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
 		}
 		}
 
 
 		if firstMount {
 		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 {
 			if err = mount("none", target, "aufs", 0, data); err != nil {
 				return
 				return
 			}
 			}
@@ -460,3 +473,33 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro
 
 
 	return
 	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
 - [Issue 783](https://github.com/docker/docker/issues/783) is about file
   permissions problems that can occur when using the AUFS file system. You
   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
 ## 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**
 * **Unexpected File Permissions in Containers**
 An idiosyncrasy in AUFS prevents permissions from propagating predictably
 An idiosyncrasy in AUFS prevents permissions from propagating predictably
 between upper and lower layers. This can cause issues with accessing private
 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).
 [Github Issue 783](https://github.com/docker/docker/issues/783).
 
 
 * **Docker Hub incompatible with Safari 8**
 * **Docker Hub incompatible with Safari 8**