From 7cd224594733e5fa0560cb912e3cf2dcef168370 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 26 Feb 2014 17:21:09 -0800 Subject: [PATCH] Ensure that loopback devices are mounted inside the conatiner Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- pkg/libcontainer/nsinit/mount.go | 53 +++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/pkg/libcontainer/nsinit/mount.go b/pkg/libcontainer/nsinit/mount.go index a73e97e375..55c2655ab0 100644 --- a/pkg/libcontainer/nsinit/mount.go +++ b/pkg/libcontainer/nsinit/mount.go @@ -37,6 +37,9 @@ func setupNewMountNamespace(rootfs, console string, readonly bool) error { if err := copyDevNodes(rootfs); err != nil { return fmt.Errorf("copy dev nodes %s", err) } + if err := setupLoopbackDevices(rootfs); err != nil { + return fmt.Errorf("setup loopback devices %s", err) + } if err := setupDev(rootfs); err != nil { return err } @@ -76,21 +79,57 @@ func copyDevNodes(rootfs string) error { "urandom", "tty", } { - stat, err := os.Stat(filepath.Join("/dev", node)) + if err := copyDevNode(rootfs, node); err != nil { + return err + } + } + return nil +} + +func setupLoopbackDevices(rootfs string) error { + for i := 0; ; i++ { + var ( + device = fmt.Sprintf("loop%d", i) + source = filepath.Join("/dev", device) + dest = filepath.Join(rootfs, "dev", device) + ) + + if _, err := os.Stat(source); err != nil { + if !os.IsNotExist(err) { + return err + } + return nil + } + if _, err := os.Stat(dest); err == nil { + os.Remove(dest) + } + f, err := os.Create(dest) if err != nil { return err } - var ( - dest = filepath.Join(rootfs, "dev", node) - st = stat.Sys().(*syscall.Stat_t) - ) - if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) { - return fmt.Errorf("copy %s %s", node, err) + f.Close() + if err := system.Mount(source, dest, "none", syscall.MS_BIND, ""); err != nil { + return err } } return nil } +func copyDevNode(rootfs, node string) error { + stat, err := os.Stat(filepath.Join("/dev", node)) + if err != nil { + return err + } + var ( + dest = filepath.Join(rootfs, "dev", node) + st = stat.Sys().(*syscall.Stat_t) + ) + if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) { + return fmt.Errorf("copy %s %s", node, err) + } + return nil +} + // setupDev symlinks the current processes pipes into the // appropriate destination on the containers rootfs func setupDev(rootfs string) error {