Browse Source

dummy driver: Use cp --reflink=auto to copy directories

On systems that supports reflinking (i.e. btrfs) this means the dummy
backend is much faster at copying files and will be sharing file data in
a CoW fashion.

On my (btrfs) system this makes "docker run ubuntu echo hello world" go
from about 3 seconds to about 1 second. Not instant, but clearly better.

cp --reflink=auto is availible since coreutils 7.5 (around 2009), so this
seems pretty ok to rely on.

cp is also better at preserving file metadata than tar, so for instance
it will copy xattrs.
Alexander Larsson 11 years ago
parent
commit
242fd4b3ef
1 changed files with 10 additions and 2 deletions
  1. 10 2
      graphdriver/dummy/driver.go

+ 10 - 2
graphdriver/dummy/driver.go

@@ -2,9 +2,9 @@ package dummy
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"github.com/dotcloud/docker/archive"
 	"github.com/dotcloud/docker/graphdriver"
 	"github.com/dotcloud/docker/graphdriver"
 	"os"
 	"os"
+	"os/exec"
 	"path"
 	"path"
 )
 )
 
 
@@ -35,6 +35,14 @@ func (d *Driver) Cleanup() error {
 	return nil
 	return nil
 }
 }
 
 
+func copyDir(src, dst string) error {
+	cmd := exec.Command("cp", "-aT", "--reflink=auto", src, dst)
+	if err := cmd.Run(); err != nil {
+		return err
+	}
+	return nil
+}
+
 func (d *Driver) Create(id string, parent string) error {
 func (d *Driver) Create(id string, parent string) error {
 	dir := d.dir(id)
 	dir := d.dir(id)
 	if err := os.MkdirAll(path.Dir(dir), 0700); err != nil {
 	if err := os.MkdirAll(path.Dir(dir), 0700); err != nil {
@@ -50,7 +58,7 @@ func (d *Driver) Create(id string, parent string) error {
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("%s: %s", parent, err)
 		return fmt.Errorf("%s: %s", parent, err)
 	}
 	}
-	if err := archive.CopyWithTar(parentDir, dir); err != nil {
+	if err := copyDir(parentDir, dir); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil