From 92e6db7beba8ad58e425119cc9885c355a5755e7 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 13 Jan 2014 11:13:49 -0800 Subject: [PATCH] Improve chroot driver by mounting proc Add -driver flag to dockerinit Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- execdriver/chroot/driver.go | 12 ++++++------ execdriver/driver.go | 1 + execdriver/lxc/driver.go | 6 ++++++ mount/mount.go | 16 +++++++++++++--- sysinit/sysinit.go | 16 +++++++++++++++- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/execdriver/chroot/driver.go b/execdriver/chroot/driver.go index 6a9d4784c2..b404f180e5 100644 --- a/execdriver/chroot/driver.go +++ b/execdriver/chroot/driver.go @@ -1,11 +1,8 @@ package chroot import ( - "fmt" "github.com/dotcloud/docker/execdriver" - "io/ioutil" "os/exec" - "path" "time" ) @@ -16,15 +13,18 @@ func NewDriver() (execdriver.Driver, error) { return &driver{}, nil } +func (d *driver) String() string { + return "chroot" +} + func (d *driver) Start(c *execdriver.Process) error { - data, _ := ioutil.ReadFile(c.SysInitPath) - ioutil.WriteFile(path.Join(c.Rootfs, ".dockerinit"), data, 0644) params := []string{ "chroot", c.Rootfs, "/.dockerinit", + "-driver", + d.String(), } - // need to mount proc params = append(params, c.Entrypoint) params = append(params, c.Arguments...) diff --git a/execdriver/driver.go b/execdriver/driver.go index 202d6ccdc7..04c52161d4 100644 --- a/execdriver/driver.go +++ b/execdriver/driver.go @@ -11,6 +11,7 @@ type Driver interface { Kill(c *Process, sig int) error Wait(id string, duration time.Duration) error // Wait on an out of process option - lxc ghosts Version() string + String() string } // Network settings of the container diff --git a/execdriver/lxc/driver.go b/execdriver/lxc/driver.go index 2265185899..7a4e754911 100644 --- a/execdriver/lxc/driver.go +++ b/execdriver/lxc/driver.go @@ -41,6 +41,10 @@ func NewDriver(root string, apparmor bool) (execdriver.Driver, error) { }, nil } +func (d *driver) String() string { + return "lxc" +} + func (d *driver) Start(c *execdriver.Process) error { params := []string{ startPath, @@ -48,6 +52,8 @@ func (d *driver) Start(c *execdriver.Process) error { "-f", c.ConfigPath, "--", c.InitPath, + "-driver", + d.String(), } if c.Network != nil { diff --git a/mount/mount.go b/mount/mount.go index b087293a9d..3860b975bd 100644 --- a/mount/mount.go +++ b/mount/mount.go @@ -25,27 +25,37 @@ func Mounted(mountpoint string) (bool, error) { return false, nil } -// Mount the specified options at the target path +// Mount the specified options at the target path only if +// the target is not mounted // Options must be specified as fstab style func Mount(device, target, mType, options string) error { if mounted, err := Mounted(target); err != nil || mounted { return err } + return ForceMount(device, target, mType, options) +} +// Mount the specified options at the target path +// reguardless if the target is mounted or not +// Options must be specified as fstab style +func ForceMount(device, target, mType, options string) error { flag, data := parseOptions(options) if err := mount(device, target, mType, uintptr(flag), data); err != nil { return err } return nil - } // Unmount the target only if it is mounted -func Unmount(target string) (err error) { +func Unmount(target string) error { if mounted, err := Mounted(target); err != nil || !mounted { return err } + return ForceUnmount(target) +} +// Unmount the target reguardless if it is mounted or not +func ForceUnmount(target string) (err error) { // Simple retry logic for unmount for i := 0; i < 10; i++ { if err = unmount(target, 0); err == nil { diff --git a/sysinit/sysinit.go b/sysinit/sysinit.go index 72f5a3ba83..73349379fb 100644 --- a/sysinit/sysinit.go +++ b/sysinit/sysinit.go @@ -4,6 +4,7 @@ import ( "encoding/json" "flag" "fmt" + "github.com/dotcloud/docker/mount" "github.com/dotcloud/docker/pkg/netlink" "github.com/dotcloud/docker/utils" "github.com/syndtr/gocapability/capability" @@ -26,6 +27,7 @@ type DockerInitArgs struct { env []string args []string mtu int + driver string } func setupHostname(args *DockerInitArgs) error { @@ -92,6 +94,10 @@ func setupWorkingDirectory(args *DockerInitArgs) error { return nil } +func setupMounts(args *DockerInitArgs) error { + return mount.ForceMount("proc", "proc", "proc", "") +} + // Takes care of dropping privileges to the desired user func changeUser(args *DockerInitArgs) error { if args.user == "" { @@ -182,7 +188,7 @@ func getEnv(args *DockerInitArgs, key string) string { func executeProgram(args *DockerInitArgs) error { setupEnv(args) - if false { + if args.driver == "lxc" { if err := setupHostname(args); err != nil { return err } @@ -201,6 +207,12 @@ func executeProgram(args *DockerInitArgs) error { if err := changeUser(args); err != nil { return err } + } else if args.driver == "chroot" { + // TODO: @crosbymichael @creack how do we unmount this after the + // process exists? + if err := setupMounts(args); err != nil { + return err + } } path, err := exec.LookPath(args.args[0]) @@ -233,6 +245,7 @@ func SysInit() { workDir := flag.String("w", "", "workdir") privileged := flag.Bool("privileged", false, "privileged mode") mtu := flag.Int("mtu", 1500, "interface mtu") + driver := flag.String("driver", "", "exec driver") flag.Parse() // Get env @@ -257,6 +270,7 @@ func SysInit() { env: env, args: flag.Args(), mtu: *mtu, + driver: *driver, } if err := executeProgram(args); err != nil {