diff --git a/execdriver/driver.go b/execdriver/driver.go index 8b5dd5ccc7..d64c08fa6c 100644 --- a/execdriver/driver.go +++ b/execdriver/driver.go @@ -53,6 +53,7 @@ type InitArgs struct { Driver string Console string Pipe int + Root string } // Driver specific information based on diff --git a/execdriver/native/driver.go b/execdriver/native/driver.go index 16e5ea1b49..6236950476 100644 --- a/execdriver/native/driver.go +++ b/execdriver/native/driver.go @@ -25,9 +25,9 @@ func init() { execdriver.RegisterInitFunc(DriverName, func(args *execdriver.InitArgs) error { var ( container *libcontainer.Container - ns = nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{}) + ns = nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{args.Root}) ) - f, err := os.Open("container.json") + f, err := os.Open(filepath.Join(args.Root, "container.json")) if err != nil { return err } @@ -57,6 +57,9 @@ type driver struct { } func NewDriver(root string) (*driver, error) { + if err := os.MkdirAll(root, 0655); err != nil { + return nil, err + } return &driver{ root: root, }, nil @@ -66,14 +69,18 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba var ( term nsinit.Terminal container = createContainer(c) - factory = &dockerCommandFactory{c} + factory = &dockerCommandFactory{c: c, driver: d} stateWriter = &dockerStateWriter{ callback: startCallback, c: c, - dsw: &nsinit.DefaultStateWriter{c.Rootfs}, + dsw: &nsinit.DefaultStateWriter{filepath.Join(d.root, c.ID)}, } - ns = nsinit.NewNsInit(factory, stateWriter) + ns = nsinit.NewNsInit(factory, stateWriter) + args = append([]string{c.Entrypoint}, c.Arguments...) ) + if err := d.createContainerRoot(c.ID); err != nil { + return -1, err + } if c.Tty { term = &dockerTtyTerm{ pipes: pipes, @@ -84,10 +91,9 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba } } c.Terminal = term - if err := writeContainerFile(container, c.Rootfs); err != nil { + if err := d.writeContainerFile(container, c.ID); err != nil { return -1, err } - args := append([]string{c.Entrypoint}, c.Arguments...) return ns.Exec(container, term, args) } @@ -98,9 +104,9 @@ func (d *driver) Kill(p *execdriver.Command, sig int) error { func (d *driver) Restore(c *execdriver.Command) error { var ( nspid int - p = filepath.Join(d.root, "containers", c.ID, "root", ".nspid") + path = filepath.Join(d.root, c.ID, "pid") ) - f, err := os.Open(p) + f, err := os.Open(path) if err != nil { return err } @@ -109,7 +115,7 @@ func (d *driver) Restore(c *execdriver.Command) error { return err } f.Close() - defer os.Remove(p) + defer os.Remove(path) proc, err := os.FindProcess(nspid) if err != nil { @@ -167,12 +173,16 @@ func (d *driver) GetPidsForContainer(id string) ([]int, error) { return pids, nil } -func writeContainerFile(container *libcontainer.Container, rootfs string) error { +func (d *driver) writeContainerFile(container *libcontainer.Container, id string) error { data, err := json.Marshal(container) if err != nil { return err } - return ioutil.WriteFile(filepath.Join(rootfs, "container.json"), data, 0755) + return ioutil.WriteFile(filepath.Join(d.root, id, "container.json"), data, 0655) +} + +func (d *driver) createContainerRoot(id string) error { + return os.MkdirAll(filepath.Join(d.root, id), 0655) } func getEnv(key string, env []string) string { @@ -186,7 +196,8 @@ func getEnv(key string, env []string) string { } type dockerCommandFactory struct { - c *execdriver.Command + c *execdriver.Command + driver *driver } // createCommand will return an exec.Cmd with the Cloneflags set to the proper namespaces @@ -202,6 +213,7 @@ func (d *dockerCommandFactory) Create(container *libcontainer.Container, console "-driver", DriverName, "-console", console, "-pipe", fmt.Sprint(syncFd), + "-root", filepath.Join(d.driver.root, d.c.ID), }, args...) d.c.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: uintptr(nsinit.GetNamespaceFlags(container.Namespaces)), diff --git a/execdriver/native/info.go b/execdriver/native/info.go index a2ab7f2a0a..5223feee83 100644 --- a/execdriver/native/info.go +++ b/execdriver/native/info.go @@ -14,8 +14,7 @@ type info struct { // .nspid file for a container. If the file exists then the // container is currently running func (i *info) IsRunning() bool { - p := filepath.Join(i.driver.root, "containers", i.ID, "root", ".nspid") - if _, err := os.Stat(p); err == nil { + if _, err := os.Stat(filepath.Join(i.driver.root, i.ID, "pid")); err == nil { return true } return false diff --git a/pkg/libcontainer/nsinit/execin.go b/pkg/libcontainer/nsinit/execin.go index 306250cf9b..253fbdcea4 100644 --- a/pkg/libcontainer/nsinit/execin.go +++ b/pkg/libcontainer/nsinit/execin.go @@ -42,7 +42,7 @@ func (ns *linuxNs) ExecIn(container *libcontainer.Container, nspid int, args []s // if the container has a new pid and mount namespace we need to // remount proc and sys to pick up the changes - if container.Namespaces.Contains("CLONE_NEWNS") && container.Namespaces.Contains("CLONE_NEWPID") { + if container.Namespaces.Contains("NEWNS") && container.Namespaces.Contains("NEWPID") { pid, err := system.Fork() if err != nil { return -1, err diff --git a/pkg/libcontainer/nsinit/nsinit/main.go b/pkg/libcontainer/nsinit/nsinit/main.go index e385e7fb70..e6b020b74b 100644 --- a/pkg/libcontainer/nsinit/nsinit/main.go +++ b/pkg/libcontainer/nsinit/nsinit/main.go @@ -9,12 +9,13 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "strconv" ) var ( - console string - pipeFd int + root, console string + pipeFd int ) var ( @@ -25,6 +26,7 @@ var ( func registerFlags() { flag.StringVar(&console, "console", "", "console (pty slave) path") flag.IntVar(&pipeFd, "pipe", 0, "sync pipe fd") + flag.StringVar(&root, "root", ".", "root for storing configuration data") flag.Parse() } @@ -84,7 +86,7 @@ func main() { } func loadContainer() (*libcontainer.Container, error) { - f, err := os.Open("container.json") + f, err := os.Open(filepath.Join(root, "container.json")) if err != nil { return nil, err } @@ -98,7 +100,7 @@ func loadContainer() (*libcontainer.Container, error) { } func readPid() (int, error) { - data, err := ioutil.ReadFile(".nspid") + data, err := ioutil.ReadFile(filepath.Join(root, "pid")) if err != nil { return -1, err } @@ -110,5 +112,5 @@ func readPid() (int, error) { } func newNsInit() (nsinit.NsInit, error) { - return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{}), nil + return nsinit.NewNsInit(&nsinit.DefaultCommandFactory{}, &nsinit.DefaultStateWriter{root}), nil } diff --git a/pkg/libcontainer/nsinit/state.go b/pkg/libcontainer/nsinit/state.go index 5c719e1c54..af38008c03 100644 --- a/pkg/libcontainer/nsinit/state.go +++ b/pkg/libcontainer/nsinit/state.go @@ -18,11 +18,11 @@ type DefaultStateWriter struct { Root string } -// writePidFile writes the namespaced processes pid to .nspid in the rootfs for the container +// writePidFile writes the namespaced processes pid to pid in the rootfs for the container func (d *DefaultStateWriter) WritePid(pid int) error { - return ioutil.WriteFile(filepath.Join(d.Root, ".nspid"), []byte(fmt.Sprint(pid)), 0655) + return ioutil.WriteFile(filepath.Join(d.Root, "pid"), []byte(fmt.Sprint(pid)), 0655) } func (d *DefaultStateWriter) DeletePid() error { - return os.Remove(filepath.Join(d.Root, ".nspid")) + return os.Remove(filepath.Join(d.Root, "pid")) } diff --git a/runtime.go b/runtime.go index 1a95ad6270..c062578a31 100644 --- a/runtime.go +++ b/runtime.go @@ -711,7 +711,7 @@ func NewRuntimeFromDirectory(config *DaemonConfig, eng *engine.Engine) (*Runtime case "lxc": ed, err = lxc.NewDriver(config.Root, sysInfo.AppArmor) case "native": - ed, err = native.NewDriver(config.Root) + ed, err = native.NewDriver(path.Join(config.Root, "native")) default: return nil, fmt.Errorf("unknown exec driver %s", config.ExecDriver) } diff --git a/sysinit/sysinit.go b/sysinit/sysinit.go index 3f2b0b6066..c84c05982c 100644 --- a/sysinit/sysinit.go +++ b/sysinit/sysinit.go @@ -55,6 +55,7 @@ func SysInit() { driver = flag.String("driver", "", "exec driver") pipe = flag.Int("pipe", 0, "sync pipe fd") console = flag.String("console", "", "console (pty slave) path") + root = flag.String("root", ".", "root path for configuration files") ) flag.Parse() @@ -82,6 +83,7 @@ func SysInit() { Driver: *driver, Console: *console, Pipe: *pipe, + Root: *root, } if err := executeProgram(args); err != nil {