aufs: apply dirperm1 by default if supported
| ... | ... |
@@ -23,6 +23,7 @@ package aufs |
| 23 | 23 |
import ( |
| 24 | 24 |
"bufio" |
| 25 | 25 |
"fmt" |
| 26 |
+ "io/ioutil" |
|
| 26 | 27 |
"os" |
| 27 | 28 |
"os/exec" |
| 28 | 29 |
"path" |
| ... | ... |
@@ -47,6 +48,9 @@ var ( |
| 47 | 47 |
graphdriver.FsMagicAufs, |
| 48 | 48 |
} |
| 49 | 49 |
backingFs = "<unknown>" |
| 50 |
+ |
|
| 51 |
+ enableDirpermLock sync.Once |
|
| 52 |
+ enableDirperm bool |
|
| 50 | 53 |
) |
| 51 | 54 |
|
| 52 | 55 |
func init() {
|
| ... | ... |
@@ -152,6 +156,7 @@ func (a *Driver) Status() [][2]string {
|
| 152 | 152 |
{"Root Dir", a.rootPath()},
|
| 153 | 153 |
{"Backing Filesystem", backingFs},
|
| 154 | 154 |
{"Dirs", fmt.Sprintf("%d", len(ids))},
|
| 155 |
+ {"Dirperm1 Supported", fmt.Sprintf("%v", useDirperm())},
|
|
| 155 | 156 |
} |
| 156 | 157 |
} |
| 157 | 158 |
|
| ... | ... |
@@ -422,7 +427,11 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro |
| 422 | 422 |
// Mount options are clipped to page size(4096 bytes). If there are more |
| 423 | 423 |
// layers then these are remounted individually using append. |
| 424 | 424 |
|
| 425 |
- b := make([]byte, syscall.Getpagesize()-len(mountLabel)-54) // room for xino & mountLabel |
|
| 425 |
+ offset := 54 |
|
| 426 |
+ if useDirperm() {
|
|
| 427 |
+ offset += len("dirperm1")
|
|
| 428 |
+ } |
|
| 429 |
+ b := make([]byte, syscall.Getpagesize()-len(mountLabel)-offset) // room for xino & mountLabel |
|
| 426 | 430 |
bp := copy(b, fmt.Sprintf("br:%s=rw", rw))
|
| 427 | 431 |
|
| 428 | 432 |
firstMount := true |
| ... | ... |
@@ -446,7 +455,11 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro |
| 446 | 446 |
} |
| 447 | 447 |
|
| 448 | 448 |
if firstMount {
|
| 449 |
- data := label.FormatMountLabel(fmt.Sprintf("%s,dio,xino=/dev/shm/aufs.xino", string(b[:bp])), mountLabel)
|
|
| 449 |
+ opts := "dio,xino=/dev/shm/aufs.xino" |
|
| 450 |
+ if useDirperm() {
|
|
| 451 |
+ opts += ",dirperm1" |
|
| 452 |
+ } |
|
| 453 |
+ data := label.FormatMountLabel(fmt.Sprintf("%s,%s", string(b[:bp]), opts), mountLabel)
|
|
| 450 | 454 |
if err = mount("none", target, "aufs", 0, data); err != nil {
|
| 451 | 455 |
return |
| 452 | 456 |
} |
| ... | ... |
@@ -460,3 +473,33 @@ func (a *Driver) aufsMount(ro []string, rw, target, mountLabel string) (err erro |
| 460 | 460 |
|
| 461 | 461 |
return |
| 462 | 462 |
} |
| 463 |
+ |
|
| 464 |
+// useDirperm checks dirperm1 mount option can be used with the current |
|
| 465 |
+// version of aufs. |
|
| 466 |
+func useDirperm() bool {
|
|
| 467 |
+ enableDirpermLock.Do(func() {
|
|
| 468 |
+ base, err := ioutil.TempDir("", "docker-aufs-base")
|
|
| 469 |
+ if err != nil {
|
|
| 470 |
+ log.Errorf("error checking dirperm1: %v", err)
|
|
| 471 |
+ return |
|
| 472 |
+ } |
|
| 473 |
+ defer os.RemoveAll(base) |
|
| 474 |
+ |
|
| 475 |
+ union, err := ioutil.TempDir("", "docker-aufs-union")
|
|
| 476 |
+ if err != nil {
|
|
| 477 |
+ log.Errorf("error checking dirperm1: %v", err)
|
|
| 478 |
+ return |
|
| 479 |
+ } |
|
| 480 |
+ defer os.RemoveAll(union) |
|
| 481 |
+ |
|
| 482 |
+ opts := fmt.Sprintf("br:%s,dirperm1,xino=/dev/shm/aufs.xino", base)
|
|
| 483 |
+ if err := mount("none", union, "aufs", 0, opts); err != nil {
|
|
| 484 |
+ return |
|
| 485 |
+ } |
|
| 486 |
+ enableDirperm = true |
|
| 487 |
+ if err := Unmount(union); err != nil {
|
|
| 488 |
+ log.Errorf("error checking dirperm1: failed to unmount %v", err)
|
|
| 489 |
+ } |
|
| 490 |
+ }) |
|
| 491 |
+ return enableDirperm |
|
| 492 |
+} |
| ... | ... |
@@ -280,8 +280,14 @@ The cache for `RUN` instructions can be invalidated by `ADD` instructions. See |
| 280 | 280 |
|
| 281 | 281 |
- [Issue 783](https://github.com/docker/docker/issues/783) is about file |
| 282 | 282 |
permissions problems that can occur when using the AUFS file system. You |
| 283 |
- might notice it during an attempt to `rm` a file, for example. The issue |
|
| 284 |
- describes a workaround. |
|
| 283 |
+ might notice it during an attempt to `rm` a file, for example. |
|
| 284 |
+ |
|
| 285 |
+ For systems that have recent aufs version (i.e., `dirperm1` mount option can |
|
| 286 |
+ be set), docker will attempt to fix the issue automatically by mounting |
|
| 287 |
+ the layers with `dirperm1` option. More details on `dirperm1` option can be |
|
| 288 |
+ found at [`aufs` man page](http://aufs.sourceforge.net/aufs3/man.html) |
|
| 289 |
+ |
|
| 290 |
+ If your system doesnt have support for `dirperm1`, the issue describes a workaround. |
|
| 285 | 291 |
|
| 286 | 292 |
## CMD |
| 287 | 293 |
|
| ... | ... |
@@ -57,7 +57,14 @@ impact on users. This list will be updated as issues are resolved. |
| 57 | 57 |
* **Unexpected File Permissions in Containers** |
| 58 | 58 |
An idiosyncrasy in AUFS prevents permissions from propagating predictably |
| 59 | 59 |
between upper and lower layers. This can cause issues with accessing private |
| 60 |
-keys, database instances, etc. For complete information and workarounds see |
|
| 60 |
+keys, database instances, etc. |
|
| 61 |
+ |
|
| 62 |
+For systems that have recent aufs version (i.e., `dirperm1` mount option can |
|
| 63 |
+be set), docker will attempt to fix the issue automatically by mounting |
|
| 64 |
+the layers with `dirperm1` option. More details on `dirperm1` option can be |
|
| 65 |
+found at [`aufs` man page](http://aufs.sourceforge.net/aufs3/man.html) |
|
| 66 |
+ |
|
| 67 |
+For complete information and workarounds see |
|
| 61 | 68 |
[Github Issue 783](https://github.com/docker/docker/issues/783). |
| 62 | 69 |
|
| 63 | 70 |
* **Docker Hub incompatible with Safari 8** |