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 <alexl@redhat.com> (github: alexlarsson)
This commit is contained in:
Alexander Larsson 2014-05-08 19:58:33 +02:00
parent b64310a3ce
commit 9573cee2d1
1 changed files with 31 additions and 0 deletions

View File

@ -91,6 +91,28 @@ func mountSystem(rootfs string, container *libcontainer.Container) error {
return nil 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 { func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error {
for _, m := range bindMounts.OfType("bind") { for _, m := range bindMounts.OfType("bind") {
var ( var (
@ -100,6 +122,15 @@ func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error {
if !m.Writable { if !m.Writable {
flags = flags | syscall.MS_RDONLY 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 { if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err) return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
} }