diff --git a/daemon/graphdriver/overlay/copy.go b/daemon/graphdriver/copy/copy.go similarity index 89% rename from daemon/graphdriver/overlay/copy.go rename to daemon/graphdriver/copy/copy.go index f7e35e2bd3..d7abccbea5 100644 --- a/daemon/graphdriver/overlay/copy.go +++ b/daemon/graphdriver/copy/copy.go @@ -1,6 +1,6 @@ // +build linux -package overlay +package copy import ( "fmt" @@ -15,10 +15,13 @@ import ( "golang.org/x/sys/unix" ) -type copyFlags int +type Mode int const ( - copyHardlink copyFlags = 1 << iota + // Content creates a new file, and copies the content of the file + Content Mode = iota + // Hardlink creates a new hardlink to the existing file + Hardlink ) func copyRegular(srcPath, dstPath string, mode os.FileMode) error { @@ -52,7 +55,9 @@ func copyXattr(srcPath, dstPath, attr string) error { return nil } -func copyDir(srcDir, dstDir string, flags copyFlags) error { +// DirCopy copies or hardlinks the contents of one directory to another, +// properly handling xattrs, and soft links +func DirCopy(srcDir, dstDir string, copyMode Mode) error { err := filepath.Walk(srcDir, func(srcPath string, f os.FileInfo, err error) error { if err != nil { return err @@ -78,12 +83,13 @@ func copyDir(srcDir, dstDir string, flags copyFlags) error { switch f.Mode() & os.ModeType { case 0: // Regular file - if flags©Hardlink != 0 { + if copyMode == Hardlink { isHardlink = true if err := os.Link(srcPath, dstPath); err != nil { return err } } else { + // Always fall back to Content copymode if err := copyRegular(srcPath, dstPath, f.Mode()); err != nil { return err } diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go index 9012722c20..3db84bc229 100644 --- a/daemon/graphdriver/overlay/overlay.go +++ b/daemon/graphdriver/overlay/overlay.go @@ -13,6 +13,7 @@ import ( "strconv" "github.com/docker/docker/daemon/graphdriver" + "github.com/docker/docker/daemon/graphdriver/copy" "github.com/docker/docker/daemon/graphdriver/overlayutils" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/containerfs" @@ -327,7 +328,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr return err } - return copyDir(parentUpperDir, upperDir, 0) + return copy.DirCopy(parentUpperDir, upperDir, copy.Content) } func (d *Driver) dir(id string) string { @@ -443,7 +444,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64 } }() - if err = copyDir(parentRootDir, tmpRootDir, copyHardlink); err != nil { + if err = copy.DirCopy(parentRootDir, tmpRootDir, copy.Hardlink); err != nil { return 0, err }