From 9573cee2d1bb983af20d6205d5a891e7da81004c Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 8 May 2014 19:58:33 +0200 Subject: [PATCH] libcontainer: Create dirs/files as needed for bind mounts If you specify a bind mount in a place that doesn't have a file yet we create that (and parent directories). This is needed because otherwise you can't use volumes like e.g. /dev/log, as that gets covered by the /dev tmpfs mounts. Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- mount/init.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/mount/init.go b/mount/init.go index cfe61d15..b0a3ef10 100644 --- a/mount/init.go +++ b/mount/init.go @@ -91,6 +91,28 @@ func mountSystem(rootfs string, container *libcontainer.Container) error { return nil } +func createIfNotExists(path string, isDir bool) error { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + if isDir { + if err := os.MkdirAll(path, 0755); err != nil { + return err + } + } else { + if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { + return err + } + f, err := os.OpenFile(path, os.O_CREATE, 0755) + if err != nil { + return err + } + f.Close() + } + } + } + return nil +} + func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error { for _, m := range bindMounts.OfType("bind") { var ( @@ -100,6 +122,15 @@ func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error { if !m.Writable { flags = flags | syscall.MS_RDONLY } + + stat, err := os.Stat(m.Source) + if err != nil { + return err + } + if err := createIfNotExists(dest, stat.IsDir()); err != nil { + return fmt.Errorf("Creating new bind-mount target, %s\n", err) + } + if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil { return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err) }