From 281abd2c8aff542e3b0309eda15536177bcec713 Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Thu, 26 Mar 2015 06:02:21 +0000 Subject: [PATCH 1/3] aufs: apply dirperm1 by default if supported Automatically detect support for aufs `dirperm1` option and apply it. `dirperm1` tells aufs to check the permission bits of the directory on the topmost branch and ignore the permission bits on all lower branches. It can be used to fix aufs' permission bug (i.e., upper layer having broader mask than the lower layer). More information about the bug can be found at https://github.com/docker/docker/issues/783 `dirperm1` man page is at: http://aufs.sourceforge.net/aufs3/man.html Signed-off-by: Daniel, Dao Quang Minh --- daemon/graphdriver/aufs/aufs.go | 46 +++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index bc4b5c0816..573f413722 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/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 = "" + + enableDirpermLock sync.Once + enableDirperm bool ) func init() { @@ -422,7 +426,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 +454,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 +472,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 +} From d7bbe2fcb5bf44f2fbcfa472e2a06c83d5d3aca1 Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Thu, 26 Mar 2015 07:46:13 +0000 Subject: [PATCH 2/3] document dirperm1 fix for #783 in known issues Since `dirperm1` requires a more recent aufs patch than many current OS release, we cant remove #783 completely. This documents that docker will apply `dirperm1` automatically for systems that support it Signed-off-by: Daniel, Dao Quang Minh --- docs/sources/reference/builder.md | 10 ++++++++-- docs/sources/release-notes.md | 9 ++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/sources/reference/builder.md b/docs/sources/reference/builder.md index 9e56abf639..025b253b02 100644 --- a/docs/sources/reference/builder.md +++ b/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 diff --git a/docs/sources/release-notes.md b/docs/sources/release-notes.md index 37ae6761aa..fe79d881dc 100644 --- a/docs/sources/release-notes.md +++ b/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** From d68d5f2e4bf7f527e06d85ec4ed8cd3917a3fd7f Mon Sep 17 00:00:00 2001 From: "Daniel, Dao Quang Minh" Date: Thu, 26 Mar 2015 17:58:49 +0000 Subject: [PATCH 3/3] print dirperm1 supported status in docker info It's easier for users to check if their systems support dirperm1 just by using docker info Signed-off-by: Daniel, Dao Quang Minh --- daemon/graphdriver/aufs/aufs.go | 1 + 1 file changed, 1 insertion(+) diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index 573f413722..7d36be4dd5 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -156,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())}, } }