mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #2897 from crosbymichael/aufs-42
Increase max image depth to 127
This commit is contained in:
commit
f5ab2516d8
4 changed files with 113 additions and 20 deletions
|
@ -26,11 +26,11 @@ import (
|
||||||
"github.com/dotcloud/docker/archive"
|
"github.com/dotcloud/docker/archive"
|
||||||
"github.com/dotcloud/docker/graphdriver"
|
"github.com/dotcloud/docker/graphdriver"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -313,24 +313,44 @@ func (a *Driver) Cleanup() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Driver) aufsMount(ro []string, rw, target string) error {
|
func (a *Driver) aufsMount(ro []string, rw, target string) (err error) {
|
||||||
rwBranch := fmt.Sprintf("%v=rw", rw)
|
defer func() {
|
||||||
roBranches := ""
|
if err != nil {
|
||||||
for _, layer := range ro {
|
Unmount(target)
|
||||||
roBranches += fmt.Sprintf("%v=ro+wh:", layer)
|
}
|
||||||
}
|
}()
|
||||||
branches := fmt.Sprintf("br:%v:%v,xino=/dev/shm/aufs.xino", rwBranch, roBranches)
|
|
||||||
|
|
||||||
//if error, try to load aufs kernel module
|
if err = a.tryMount(ro, rw, target); err != nil {
|
||||||
if err := mount("none", target, "aufs", 0, branches); err != nil {
|
if err = a.mountRw(rw, target); err != nil {
|
||||||
log.Printf("Kernel does not support AUFS, trying to load the AUFS module with modprobe...")
|
return
|
||||||
if err := exec.Command("modprobe", "aufs").Run(); err != nil {
|
|
||||||
return fmt.Errorf("Unable to load the AUFS module")
|
|
||||||
}
|
}
|
||||||
log.Printf("...module loaded.")
|
|
||||||
if err := mount("none", target, "aufs", 0, branches); err != nil {
|
for _, layer := range ro {
|
||||||
return fmt.Errorf("Unable to mount using aufs %s", err)
|
branch := fmt.Sprintf("append:%s=ro+wh", layer)
|
||||||
|
if err = mount("none", target, "aufs", syscall.MS_REMOUNT, branch); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to mount using the aufs fast path, if this fails then
|
||||||
|
// append ro layers.
|
||||||
|
func (a *Driver) tryMount(ro []string, rw, target string) (err error) {
|
||||||
|
var (
|
||||||
|
rwBranch = fmt.Sprintf("%s=rw", rw)
|
||||||
|
roBranches = fmt.Sprintf("%s=ro+wh:", strings.Join(ro, "=ro+wh:"))
|
||||||
|
)
|
||||||
|
return mount("none", target, "aufs", 0, fmt.Sprintf("br:%v:%v,xino=/dev/shm/aufs.xino", rwBranch, roBranches))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Driver) mountRw(rw, target string) error {
|
||||||
|
return mount("none", target, "aufs", 0, fmt.Sprintf("br:%s,xino=/dev/shm/aufs.xino", rw))
|
||||||
|
}
|
||||||
|
|
||||||
|
func rollbackMount(target string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
Unmount(target)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package aufs
|
package aufs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
"github.com/dotcloud/docker/archive"
|
"github.com/dotcloud/docker/archive"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -621,3 +625,70 @@ func TestApplyDiff(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hash(c string) string {
|
||||||
|
h := sha256.New()
|
||||||
|
fmt.Fprint(h, c)
|
||||||
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMountMoreThan42Layers(t *testing.T) {
|
||||||
|
d := newDriver(t)
|
||||||
|
defer os.RemoveAll(tmp)
|
||||||
|
defer d.Cleanup()
|
||||||
|
var last string
|
||||||
|
var expected int
|
||||||
|
|
||||||
|
for i := 1; i < 127; i++ {
|
||||||
|
expected++
|
||||||
|
var (
|
||||||
|
parent = fmt.Sprintf("%d", i-1)
|
||||||
|
current = fmt.Sprintf("%d", i)
|
||||||
|
)
|
||||||
|
|
||||||
|
if parent == "0" {
|
||||||
|
parent = ""
|
||||||
|
} else {
|
||||||
|
parent = hash(parent)
|
||||||
|
}
|
||||||
|
current = hash(current)
|
||||||
|
|
||||||
|
if err := d.Create(current, parent); err != nil {
|
||||||
|
t.Logf("Current layer %d", i)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
point, err := d.Get(current)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("Current layer %d", i)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
f, err := os.Create(path.Join(point, current))
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("Current layer %d", i)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
if i%10 == 0 {
|
||||||
|
if err := os.Remove(path.Join(point, parent)); err != nil {
|
||||||
|
t.Logf("Current layer %d", i)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
expected--
|
||||||
|
}
|
||||||
|
last = current
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the actual mount for the top most image
|
||||||
|
point, err := d.Get(last)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
files, err := ioutil.ReadDir(point)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(files) != expected {
|
||||||
|
t.Fatalf("Expected %d got %d", expected, len(files))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@ package aufs
|
||||||
|
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
||||||
func mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
|
func mount(source string, target string, fstype string, flags uintptr, data string) error {
|
||||||
return syscall.Mount(source, target, fstype, flags, data)
|
return syscall.Mount(source, target, fstype, flags, data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Set the max depth to the aufs restriction
|
// Set the max depth to the aufs default that most
|
||||||
const MaxImageDepth = 42
|
// kernels are compiled with
|
||||||
|
// For more information see: http://sourceforge.net/p/aufs/aufs3-standalone/ci/aufs3.12/tree/config.mk
|
||||||
|
const MaxImageDepth = 127
|
||||||
|
|
||||||
var defaultDns = []string{"8.8.8.8", "8.8.4.4"}
|
var defaultDns = []string{"8.8.8.8", "8.8.4.4"}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue