浏览代码

Improve chroot driver by mounting proc

Add -driver flag to dockerinit

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
Michael Crosby 11 年之前
父节点
当前提交
92e6db7beb
共有 5 个文件被更改,包括 41 次插入10 次删除
  1. 6 6
      execdriver/chroot/driver.go
  2. 1 0
      execdriver/driver.go
  3. 6 0
      execdriver/lxc/driver.go
  4. 13 3
      mount/mount.go
  5. 15 1
      sysinit/sysinit.go

+ 6 - 6
execdriver/chroot/driver.go

@@ -1,11 +1,8 @@
 package chroot
 package chroot
 
 
 import (
 import (
-	"fmt"
 	"github.com/dotcloud/docker/execdriver"
 	"github.com/dotcloud/docker/execdriver"
-	"io/ioutil"
 	"os/exec"
 	"os/exec"
-	"path"
 	"time"
 	"time"
 )
 )
 
 
@@ -16,15 +13,18 @@ func NewDriver() (execdriver.Driver, error) {
 	return &driver{}, nil
 	return &driver{}, nil
 }
 }
 
 
+func (d *driver) String() string {
+	return "chroot"
+}
+
 func (d *driver) Start(c *execdriver.Process) error {
 func (d *driver) Start(c *execdriver.Process) error {
-	data, _ := ioutil.ReadFile(c.SysInitPath)
-	ioutil.WriteFile(path.Join(c.Rootfs, ".dockerinit"), data, 0644)
 	params := []string{
 	params := []string{
 		"chroot",
 		"chroot",
 		c.Rootfs,
 		c.Rootfs,
 		"/.dockerinit",
 		"/.dockerinit",
+		"-driver",
+		d.String(),
 	}
 	}
-	// need to mount proc
 	params = append(params, c.Entrypoint)
 	params = append(params, c.Entrypoint)
 	params = append(params, c.Arguments...)
 	params = append(params, c.Arguments...)
 
 

+ 1 - 0
execdriver/driver.go

@@ -11,6 +11,7 @@ type Driver interface {
 	Kill(c *Process, sig int) error
 	Kill(c *Process, sig int) error
 	Wait(id string, duration time.Duration) error // Wait on an out of process option - lxc ghosts
 	Wait(id string, duration time.Duration) error // Wait on an out of process option - lxc ghosts
 	Version() string
 	Version() string
+	String() string
 }
 }
 
 
 // Network settings of the container
 // Network settings of the container

+ 6 - 0
execdriver/lxc/driver.go

@@ -41,6 +41,10 @@ func NewDriver(root string, apparmor bool) (execdriver.Driver, error) {
 	}, nil
 	}, nil
 }
 }
 
 
+func (d *driver) String() string {
+	return "lxc"
+}
+
 func (d *driver) Start(c *execdriver.Process) error {
 func (d *driver) Start(c *execdriver.Process) error {
 	params := []string{
 	params := []string{
 		startPath,
 		startPath,
@@ -48,6 +52,8 @@ func (d *driver) Start(c *execdriver.Process) error {
 		"-f", c.ConfigPath,
 		"-f", c.ConfigPath,
 		"--",
 		"--",
 		c.InitPath,
 		c.InitPath,
+		"-driver",
+		d.String(),
 	}
 	}
 
 
 	if c.Network != nil {
 	if c.Network != nil {

+ 13 - 3
mount/mount.go

@@ -25,27 +25,37 @@ func Mounted(mountpoint string) (bool, error) {
 	return false, nil
 	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
 // Options must be specified as fstab style
 func Mount(device, target, mType, options string) error {
 func Mount(device, target, mType, options string) error {
 	if mounted, err := Mounted(target); err != nil || mounted {
 	if mounted, err := Mounted(target); err != nil || mounted {
 		return err
 		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)
 	flag, data := parseOptions(options)
 	if err := mount(device, target, mType, uintptr(flag), data); err != nil {
 	if err := mount(device, target, mType, uintptr(flag), data); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
-
 }
 }
 
 
 // Unmount the target only if it is mounted
 // 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 {
 	if mounted, err := Mounted(target); err != nil || !mounted {
 		return err
 		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
 	// Simple retry logic for unmount
 	for i := 0; i < 10; i++ {
 	for i := 0; i < 10; i++ {
 		if err = unmount(target, 0); err == nil {
 		if err = unmount(target, 0); err == nil {

+ 15 - 1
sysinit/sysinit.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"encoding/json"
 	"flag"
 	"flag"
 	"fmt"
 	"fmt"
+	"github.com/dotcloud/docker/mount"
 	"github.com/dotcloud/docker/pkg/netlink"
 	"github.com/dotcloud/docker/pkg/netlink"
 	"github.com/dotcloud/docker/utils"
 	"github.com/dotcloud/docker/utils"
 	"github.com/syndtr/gocapability/capability"
 	"github.com/syndtr/gocapability/capability"
@@ -26,6 +27,7 @@ type DockerInitArgs struct {
 	env        []string
 	env        []string
 	args       []string
 	args       []string
 	mtu        int
 	mtu        int
+	driver     string
 }
 }
 
 
 func setupHostname(args *DockerInitArgs) error {
 func setupHostname(args *DockerInitArgs) error {
@@ -92,6 +94,10 @@ func setupWorkingDirectory(args *DockerInitArgs) error {
 	return nil
 	return nil
 }
 }
 
 
+func setupMounts(args *DockerInitArgs) error {
+	return mount.ForceMount("proc", "proc", "proc", "")
+}
+
 // Takes care of dropping privileges to the desired user
 // Takes care of dropping privileges to the desired user
 func changeUser(args *DockerInitArgs) error {
 func changeUser(args *DockerInitArgs) error {
 	if args.user == "" {
 	if args.user == "" {
@@ -182,7 +188,7 @@ func getEnv(args *DockerInitArgs, key string) string {
 func executeProgram(args *DockerInitArgs) error {
 func executeProgram(args *DockerInitArgs) error {
 	setupEnv(args)
 	setupEnv(args)
 
 
-	if false {
+	if args.driver == "lxc" {
 		if err := setupHostname(args); err != nil {
 		if err := setupHostname(args); err != nil {
 			return err
 			return err
 		}
 		}
@@ -201,6 +207,12 @@ func executeProgram(args *DockerInitArgs) error {
 		if err := changeUser(args); err != nil {
 		if err := changeUser(args); err != nil {
 			return err
 			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])
 	path, err := exec.LookPath(args.args[0])
@@ -233,6 +245,7 @@ func SysInit() {
 	workDir := flag.String("w", "", "workdir")
 	workDir := flag.String("w", "", "workdir")
 	privileged := flag.Bool("privileged", false, "privileged mode")
 	privileged := flag.Bool("privileged", false, "privileged mode")
 	mtu := flag.Int("mtu", 1500, "interface mtu")
 	mtu := flag.Int("mtu", 1500, "interface mtu")
+	driver := flag.String("driver", "", "exec driver")
 	flag.Parse()
 	flag.Parse()
 
 
 	// Get env
 	// Get env
@@ -257,6 +270,7 @@ func SysInit() {
 		env:        env,
 		env:        env,
 		args:       flag.Args(),
 		args:       flag.Args(),
 		mtu:        *mtu,
 		mtu:        *mtu,
+		driver:     *driver,
 	}
 	}
 
 
 	if err := executeProgram(args); err != nil {
 	if err := executeProgram(args); err != nil {