From b7c7b851dce28bb679e0289168da382d7cdad74b Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 13 May 2014 15:42:21 +0200 Subject: [PATCH 1/4] libcontainer: Ensure bind mount target files are inside rootfs Before we create any files to bind-mount on, make sure they are inside the container rootfs, handling for instance absolute symbolic links inside the container. Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- pkg/libcontainer/mount/init.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/libcontainer/mount/init.go b/pkg/libcontainer/mount/init.go index 12f833a966..16fb758e57 100644 --- a/pkg/libcontainer/mount/init.go +++ b/pkg/libcontainer/mount/init.go @@ -12,6 +12,7 @@ import ( "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/mount/nodes" "github.com/dotcloud/docker/pkg/system" + "github.com/dotcloud/docker/utils" ) // default mount point flags @@ -127,6 +128,12 @@ func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error { if err != nil { return err } + + dest, err = utils.FollowSymlinkInScope(dest, rootfs) + if err != nil { + return err + } + if err := createIfNotExists(dest, stat.IsDir()); err != nil { return fmt.Errorf("Creating new bind-mount target, %s", err) } From dcf81f95fdfe3ac8e97602d2ef2fef03288c15b1 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 13 May 2014 10:34:30 -0700 Subject: [PATCH 2/4] Move Follow symlink to pkg Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- {utils => pkg/symlink}/fs.go | 33 +------------------------- {utils => pkg/symlink}/fs_test.go | 2 +- {utils => pkg/symlink}/testdata/fs/a/d | 0 {utils => pkg/symlink}/testdata/fs/a/e | 0 {utils => pkg/symlink}/testdata/fs/a/f | 0 {utils => pkg/symlink}/testdata/fs/b/h | 0 {utils => pkg/symlink}/testdata/fs/g | 0 utils/utils.go | 31 ++++++++++++++++++++++++ 8 files changed, 33 insertions(+), 33 deletions(-) rename {utils => pkg/symlink}/fs.go (64%) rename {utils => pkg/symlink}/fs_test.go (99%) rename {utils => pkg/symlink}/testdata/fs/a/d (100%) rename {utils => pkg/symlink}/testdata/fs/a/e (100%) rename {utils => pkg/symlink}/testdata/fs/a/f (100%) rename {utils => pkg/symlink}/testdata/fs/b/h (100%) rename {utils => pkg/symlink}/testdata/fs/g (100%) diff --git a/utils/fs.go b/pkg/symlink/fs.go similarity index 64% rename from utils/fs.go rename to pkg/symlink/fs.go index e07ced75d7..e91d33db4b 100644 --- a/utils/fs.go +++ b/pkg/symlink/fs.go @@ -1,43 +1,12 @@ -package utils +package symlink import ( "fmt" "os" "path/filepath" "strings" - "syscall" ) -// TreeSize walks a directory tree and returns its total size in bytes. -func TreeSize(dir string) (size int64, err error) { - data := make(map[uint64]struct{}) - err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error { - // Ignore directory sizes - if fileInfo == nil { - return nil - } - - s := fileInfo.Size() - if fileInfo.IsDir() || s == 0 { - return nil - } - - // Check inode to handle hard links correctly - inode := fileInfo.Sys().(*syscall.Stat_t).Ino - // inode is not a uint64 on all platforms. Cast it to avoid issues. - if _, exists := data[uint64(inode)]; exists { - return nil - } - // inode is not a uint64 on all platforms. Cast it to avoid issues. - data[uint64(inode)] = struct{}{} - - size += s - - return nil - }) - return -} - // FollowSymlink will follow an existing link and scope it to the root // path provided. func FollowSymlinkInScope(link, root string) (string, error) { diff --git a/utils/fs_test.go b/pkg/symlink/fs_test.go similarity index 99% rename from utils/fs_test.go rename to pkg/symlink/fs_test.go index 9affc00e91..1f12aa3a60 100644 --- a/utils/fs_test.go +++ b/pkg/symlink/fs_test.go @@ -1,4 +1,4 @@ -package utils +package symlink import ( "io/ioutil" diff --git a/utils/testdata/fs/a/d b/pkg/symlink/testdata/fs/a/d similarity index 100% rename from utils/testdata/fs/a/d rename to pkg/symlink/testdata/fs/a/d diff --git a/utils/testdata/fs/a/e b/pkg/symlink/testdata/fs/a/e similarity index 100% rename from utils/testdata/fs/a/e rename to pkg/symlink/testdata/fs/a/e diff --git a/utils/testdata/fs/a/f b/pkg/symlink/testdata/fs/a/f similarity index 100% rename from utils/testdata/fs/a/f rename to pkg/symlink/testdata/fs/a/f diff --git a/utils/testdata/fs/b/h b/pkg/symlink/testdata/fs/b/h similarity index 100% rename from utils/testdata/fs/b/h rename to pkg/symlink/testdata/fs/b/h diff --git a/utils/testdata/fs/g b/pkg/symlink/testdata/fs/g similarity index 100% rename from utils/testdata/fs/g rename to pkg/symlink/testdata/fs/g diff --git a/utils/utils.go b/utils/utils.go index 4ef44b5617..7ffcc06b93 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -21,6 +21,7 @@ import ( "strconv" "strings" "sync" + "syscall" "time" "github.com/dotcloud/docker/dockerversion" @@ -1091,3 +1092,33 @@ func ParseKeyValueOpt(opt string) (string, string, error) { } return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil } + +// TreeSize walks a directory tree and returns its total size in bytes. +func TreeSize(dir string) (size int64, err error) { + data := make(map[uint64]struct{}) + err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error { + // Ignore directory sizes + if fileInfo == nil { + return nil + } + + s := fileInfo.Size() + if fileInfo.IsDir() || s == 0 { + return nil + } + + // Check inode to handle hard links correctly + inode := fileInfo.Sys().(*syscall.Stat_t).Ino + // inode is not a uint64 on all platforms. Cast it to avoid issues. + if _, exists := data[uint64(inode)]; exists { + return nil + } + // inode is not a uint64 on all platforms. Cast it to avoid issues. + data[uint64(inode)] = struct{}{} + + size += s + + return nil + }) + return +} From ca040b1a377c467a9504ffa256ae77d9e3d29f0c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 13 May 2014 10:54:08 -0700 Subject: [PATCH 3/4] Update code to handle new path to Follow Symlink func Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- daemon/volumes.go | 4 ++-- pkg/libcontainer/mount/init.go | 4 ++-- server/buildfile.go | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/daemon/volumes.go b/daemon/volumes.go index a15e3084b2..ac01c6a982 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -10,7 +10,7 @@ import ( "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/daemon/execdriver" - "github.com/dotcloud/docker/utils" + "github.com/dotcloud/docker/pkg/symlink" ) type BindMap struct { @@ -213,7 +213,7 @@ func createVolumes(container *Container) error { } // Create the mountpoint - rootVolPath, err := utils.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs) + rootVolPath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs) if err != nil { return err } diff --git a/pkg/libcontainer/mount/init.go b/pkg/libcontainer/mount/init.go index 16fb758e57..e5f2b43cab 100644 --- a/pkg/libcontainer/mount/init.go +++ b/pkg/libcontainer/mount/init.go @@ -11,8 +11,8 @@ import ( "github.com/dotcloud/docker/pkg/label" "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/mount/nodes" + "github.com/dotcloud/docker/pkg/symlink" "github.com/dotcloud/docker/pkg/system" - "github.com/dotcloud/docker/utils" ) // default mount point flags @@ -129,7 +129,7 @@ func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error { return err } - dest, err = utils.FollowSymlinkInScope(dest, rootfs) + dest, err = symlink.FollowSymlinkInScope(dest, rootfs) if err != nil { return err } diff --git a/server/buildfile.go b/server/buildfile.go index eeafbb5b4c..faaac0d3d4 100644 --- a/server/buildfile.go +++ b/server/buildfile.go @@ -20,6 +20,7 @@ import ( "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/daemon" "github.com/dotcloud/docker/nat" + "github.com/dotcloud/docker/pkg/symlink" "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/runconfig" "github.com/dotcloud/docker/utils" @@ -404,7 +405,7 @@ func (b *buildFile) addContext(container *daemon.Container, orig, dest string, r ) if destPath != container.RootfsPath() { - destPath, err = utils.FollowSymlinkInScope(destPath, container.RootfsPath()) + destPath, err = symlink.FollowSymlinkInScope(destPath, container.RootfsPath()) if err != nil { return err } From ea7647099fcabd73077a403d461e9a0778dda12f Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Tue, 13 May 2014 11:27:24 -0700 Subject: [PATCH 4/4] Add MAINTAINERS file to symlink pkg Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- pkg/symlink/MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 pkg/symlink/MAINTAINERS diff --git a/pkg/symlink/MAINTAINERS b/pkg/symlink/MAINTAINERS new file mode 100644 index 0000000000..68a97d2fc2 --- /dev/null +++ b/pkg/symlink/MAINTAINERS @@ -0,0 +1,2 @@ +Michael Crosby (@crosbymichael) +Victor Vieux (@vieux)