Selaa lähdekoodia

Merge pull request #7069 from crosbymichael/update-libcontainer-july3

Update libcontainer to be85764f109c3f0f62cd2a5c8be
unclejack 11 vuotta sitten
vanhempi
commit
1646e5d69a
39 muutettua tiedostoa jossa 606 lisäystä ja 397 poistoa
  1. 3 3
      daemon/daemon.go
  2. 86 2
      daemon/execdriver/lxc/driver.go
  3. 1 1
      daemon/execdriver/native/create.go
  4. 71 15
      daemon/execdriver/native/driver.go
  5. 13 0
      daemon/execdriver/native/driver_unsupported_nocgo.go
  6. 1 1
      daemon/execdriver/native/info.go
  7. 0 42
      daemon/execdriver/native/term.go
  8. 0 80
      daemon/execdriver/termconsole.go
  9. 13 0
      daemon/utils_linux.go
  10. 9 0
      daemon/utils_nolinux.go
  11. 1 1
      hack/vendor.sh
  12. 8 0
      vendor/src/github.com/docker/libcontainer/Dockerfile
  13. 1 1
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go
  14. 78 8
      vendor/src/github.com/docker/libcontainer/console/console.go
  15. 8 9
      vendor/src/github.com/docker/libcontainer/mount/init.go
  16. 5 4
      vendor/src/github.com/docker/libcontainer/mount/msmoveroot.go
  17. 3 4
      vendor/src/github.com/docker/libcontainer/mount/nodes/nodes.go
  18. 7 5
      vendor/src/github.com/docker/libcontainer/mount/pivotroot.go
  19. 5 1
      vendor/src/github.com/docker/libcontainer/mount/ptmx.go
  20. 1 2
      vendor/src/github.com/docker/libcontainer/mount/readonly.go
  21. 8 8
      vendor/src/github.com/docker/libcontainer/mount/remount.go
  22. 19 19
      vendor/src/github.com/docker/libcontainer/namespaces/exec.go
  23. 1 1
      vendor/src/github.com/docker/libcontainer/namespaces/execin.go
  24. 11 7
      vendor/src/github.com/docker/libcontainer/namespaces/init.go
  25. 0 49
      vendor/src/github.com/docker/libcontainer/namespaces/std_term.go
  26. 0 29
      vendor/src/github.com/docker/libcontainer/namespaces/term.go
  27. 0 56
      vendor/src/github.com/docker/libcontainer/namespaces/tty_term.go
  28. 0 28
      vendor/src/github.com/docker/libcontainer/namespaces/unsupported.go
  29. 1 3
      vendor/src/github.com/docker/libcontainer/network/loopback.go
  30. 4 1
      vendor/src/github.com/docker/libcontainer/network/netns.go
  31. 1 0
      vendor/src/github.com/docker/libcontainer/network/types.go
  32. 61 5
      vendor/src/github.com/docker/libcontainer/nsinit/exec.go
  33. 4 6
      vendor/src/github.com/docker/libcontainer/security/restrict/restrict.go
  34. 7 6
      vendor/src/github.com/docker/libcontainer/selinux/selinux.go
  35. 60 0
      vendor/src/github.com/docker/libcontainer/system/linux.go
  36. 27 0
      vendor/src/github.com/docker/libcontainer/system/proc.go
  37. 29 0
      vendor/src/github.com/docker/libcontainer/system/setns_linux.go
  38. 0 0
      vendor/src/github.com/docker/libcontainer/system/sysconfig.go
  39. 59 0
      vendor/src/github.com/docker/libcontainer/system/xattrs_linux.go

+ 3 - 3
daemon/daemon.go

@@ -13,7 +13,6 @@ import (
 	"time"
 
 	"github.com/docker/libcontainer/label"
-	"github.com/docker/libcontainer/selinux"
 	"github.com/dotcloud/docker/archive"
 	"github.com/dotcloud/docker/daemon/execdriver"
 	"github.com/dotcloud/docker/daemon/execdriver/execdrivers"
@@ -300,7 +299,8 @@ func (daemon *Daemon) Destroy(container *Container) error {
 	if err := os.RemoveAll(container.root); err != nil {
 		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
 	}
-	selinux.FreeLxcContexts(container.ProcessLabel)
+
+	selinuxFreeLxcContexts(container.ProcessLabel)
 
 	return nil
 }
@@ -761,7 +761,7 @@ func NewDaemon(config *daemonconfig.Config, eng *engine.Engine) (*Daemon, error)
 
 func NewDaemonFromDirectory(config *daemonconfig.Config, eng *engine.Engine) (*Daemon, error) {
 	if !config.EnableSelinuxSupport {
-		selinux.SetDisabled()
+		selinuxSetDisabled()
 	}
 
 	// Create the root directory if it doesn't exists

+ 86 - 2
daemon/execdriver/lxc/driver.go

@@ -3,6 +3,7 @@ package lxc
 import (
 	"encoding/json"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"log"
 	"os"
@@ -19,7 +20,9 @@ import (
 	"github.com/docker/libcontainer/label"
 	"github.com/docker/libcontainer/mount/nodes"
 	"github.com/dotcloud/docker/daemon/execdriver"
+	"github.com/dotcloud/docker/pkg/term"
 	"github.com/dotcloud/docker/utils"
+	"github.com/kr/pty"
 )
 
 const DriverName = "lxc"
@@ -78,10 +81,20 @@ func (d *driver) Name() string {
 }
 
 func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
-	if err := execdriver.SetTerminal(c, pipes); err != nil {
-		return -1, err
+	var (
+		term execdriver.Terminal
+		err  error
+	)
+
+	if c.Tty {
+		term, err = NewTtyConsole(c, pipes)
+	} else {
+		term, err = execdriver.NewStdConsole(c, pipes)
 	}
+	c.Terminal = term
+
 	c.Mounts = append(c.Mounts, execdriver.Mount{d.initPath, c.InitPath, false, true})
+
 	if err := d.generateEnvConfig(c); err != nil {
 		return -1, err
 	}
@@ -462,3 +475,74 @@ func (d *driver) generateEnvConfig(c *execdriver.Command) error {
 
 	return ioutil.WriteFile(p, data, 0600)
 }
+
+type TtyConsole struct {
+	MasterPty *os.File
+	SlavePty  *os.File
+}
+
+func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyConsole, error) {
+	// lxc is special in that we cannot create the master outside of the container without
+	// opening the slave because we have nothing to provide to the cmd.  We have to open both then do
+	// the crazy setup on command right now instead of passing the console path to lxc and telling it
+	// to open up that console.  we save a couple of openfiles in the native driver because we can do
+	// this.
+	ptyMaster, ptySlave, err := pty.Open()
+	if err != nil {
+		return nil, err
+	}
+
+	tty := &TtyConsole{
+		MasterPty: ptyMaster,
+		SlavePty:  ptySlave,
+	}
+
+	if err := tty.AttachPipes(&command.Cmd, pipes); err != nil {
+		tty.Close()
+		return nil, err
+	}
+
+	command.Console = tty.SlavePty.Name()
+
+	return tty, nil
+}
+
+func (t *TtyConsole) Master() *os.File {
+	return t.MasterPty
+}
+
+func (t *TtyConsole) Resize(h, w int) error {
+	return term.SetWinsize(t.MasterPty.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
+}
+
+func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *execdriver.Pipes) error {
+	command.Stdout = t.SlavePty
+	command.Stderr = t.SlavePty
+
+	go func() {
+		if wb, ok := pipes.Stdout.(interface {
+			CloseWriters() error
+		}); ok {
+			defer wb.CloseWriters()
+		}
+
+		io.Copy(pipes.Stdout, t.MasterPty)
+	}()
+
+	if pipes.Stdin != nil {
+		command.Stdin = t.SlavePty
+		command.SysProcAttr.Setctty = true
+
+		go func() {
+			io.Copy(t.MasterPty, pipes.Stdin)
+
+			pipes.Stdin.Close()
+		}()
+	}
+	return nil
+}
+
+func (t *TtyConsole) Close() error {
+	t.SlavePty.Close()
+	return t.MasterPty.Close()
+}

+ 1 - 1
daemon/execdriver/native/create.go

@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,cgo
 
 package native
 

+ 71 - 15
daemon/execdriver/native/driver.go

@@ -1,10 +1,11 @@
-// +build linux
+// +build linux,cgo
 
 package native
 
 import (
 	"encoding/json"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -21,6 +22,7 @@ import (
 	"github.com/docker/libcontainer/syncpipe"
 	"github.com/dotcloud/docker/daemon/execdriver"
 	"github.com/dotcloud/docker/pkg/system"
+	"github.com/dotcloud/docker/pkg/term"
 )
 
 const (
@@ -95,6 +97,16 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 	if err != nil {
 		return -1, err
 	}
+
+	var term execdriver.Terminal
+
+	if c.Tty {
+		term, err = NewTtyConsole(c, pipes)
+	} else {
+		term, err = execdriver.NewStdConsole(c, pipes)
+	}
+	c.Terminal = term
+
 	d.Lock()
 	d.activeContainers[c.ID] = &activeContainer{
 		container: container,
@@ -106,6 +118,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		dataPath = filepath.Join(d.root, c.ID)
 		args     = append([]string{c.Entrypoint}, c.Arguments...)
 	)
+
 	if err := d.createContainerRoot(c.ID); err != nil {
 		return -1, err
 	}
@@ -115,9 +128,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		return -1, err
 	}
 
-	term := getTerminal(c, pipes)
-
-	return namespaces.Exec(container, term, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd {
+	return namespaces.Exec(container, c.Stdin, c.Stdout, c.Stderr, c.Console, c.Rootfs, dataPath, args, func(container *libcontainer.Config, console, rootfs, dataPath, init string, child *os.File, args []string) *exec.Cmd {
 		// we need to join the rootfs because namespaces will setup the rootfs and chroot
 		initPath := filepath.Join(c.Rootfs, c.InitPath)
 
@@ -201,11 +212,13 @@ func (d *driver) Terminate(p *execdriver.Command) error {
 	if err != nil {
 		return err
 	}
+
 	if state.InitStartTime == currentStartTime {
 		err = syscall.Kill(p.Process.Pid, 9)
 		syscall.Wait4(p.Process.Pid, nil, 0, nil)
 	}
 	d.removeContainerRoot(p.ID)
+
 	return err
 
 }
@@ -267,17 +280,60 @@ func getEnv(key string, env []string) string {
 	return ""
 }
 
-func getTerminal(c *execdriver.Command, pipes *execdriver.Pipes) namespaces.Terminal {
-	var term namespaces.Terminal
-	if c.Tty {
-		term = &dockerTtyTerm{
-			pipes: pipes,
-		}
-	} else {
-		term = &dockerStdTerm{
-			pipes: pipes,
+type TtyConsole struct {
+	MasterPty *os.File
+}
+
+func NewTtyConsole(command *execdriver.Command, pipes *execdriver.Pipes) (*TtyConsole, error) {
+	ptyMaster, console, err := system.CreateMasterAndConsole()
+	if err != nil {
+		return nil, err
+	}
+
+	tty := &TtyConsole{
+		MasterPty: ptyMaster,
+	}
+
+	if err := tty.AttachPipes(&command.Cmd, pipes); err != nil {
+		tty.Close()
+		return nil, err
+	}
+
+	command.Console = console
+
+	return tty, nil
+}
+
+func (t *TtyConsole) Master() *os.File {
+	return t.MasterPty
+}
+
+func (t *TtyConsole) Resize(h, w int) error {
+	return term.SetWinsize(t.MasterPty.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
+}
+
+func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *execdriver.Pipes) error {
+	go func() {
+		if wb, ok := pipes.Stdout.(interface {
+			CloseWriters() error
+		}); ok {
+			defer wb.CloseWriters()
 		}
+
+		io.Copy(pipes.Stdout, t.MasterPty)
+	}()
+
+	if pipes.Stdin != nil {
+		go func() {
+			io.Copy(t.MasterPty, pipes.Stdin)
+
+			pipes.Stdin.Close()
+		}()
 	}
-	c.Terminal = term
-	return term
+
+	return nil
+}
+
+func (t *TtyConsole) Close() error {
+	return t.MasterPty.Close()
 }

+ 13 - 0
daemon/execdriver/native/driver_unsupported_nocgo.go

@@ -0,0 +1,13 @@
+// +build linux,!cgo
+
+package native
+
+import (
+	"fmt"
+
+	"github.com/dotcloud/docker/daemon/execdriver"
+)
+
+func NewDriver(root, initPath string) (execdriver.Driver, error) {
+	return nil, fmt.Errorf("native driver not supported on non-linux")
+}

+ 1 - 1
daemon/execdriver/native/info.go

@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,cgo
 
 package native
 

+ 0 - 42
daemon/execdriver/native/term.go

@@ -1,42 +0,0 @@
-/*
-   These types are wrappers around the libcontainer Terminal interface so that
-   we can resuse the docker implementations where possible.
-*/
-package native
-
-import (
-	"github.com/dotcloud/docker/daemon/execdriver"
-	"io"
-	"os"
-	"os/exec"
-)
-
-type dockerStdTerm struct {
-	execdriver.StdConsole
-	pipes *execdriver.Pipes
-}
-
-func (d *dockerStdTerm) Attach(cmd *exec.Cmd) error {
-	return d.AttachPipes(cmd, d.pipes)
-}
-
-func (d *dockerStdTerm) SetMaster(master *os.File) {
-	// do nothing
-}
-
-type dockerTtyTerm struct {
-	execdriver.TtyConsole
-	pipes *execdriver.Pipes
-}
-
-func (t *dockerTtyTerm) Attach(cmd *exec.Cmd) error {
-	go io.Copy(t.pipes.Stdout, t.MasterPty)
-	if t.pipes.Stdin != nil {
-		go io.Copy(t.MasterPty, t.pipes.Stdin)
-	}
-	return nil
-}
-
-func (t *dockerTtyTerm) SetMaster(master *os.File) {
-	t.MasterPty = master
-}

+ 0 - 80
daemon/execdriver/termconsole.go

@@ -1,90 +1,10 @@
 package execdriver
 
 import (
-	"github.com/dotcloud/docker/pkg/term"
-	"github.com/kr/pty"
 	"io"
-	"os"
 	"os/exec"
 )
 
-func SetTerminal(command *Command, pipes *Pipes) error {
-	var (
-		term Terminal
-		err  error
-	)
-	if command.Tty {
-		term, err = NewTtyConsole(command, pipes)
-	} else {
-		term, err = NewStdConsole(command, pipes)
-	}
-	if err != nil {
-		return err
-	}
-	command.Terminal = term
-	return nil
-}
-
-type TtyConsole struct {
-	MasterPty *os.File
-	SlavePty  *os.File
-}
-
-func NewTtyConsole(command *Command, pipes *Pipes) (*TtyConsole, error) {
-	ptyMaster, ptySlave, err := pty.Open()
-	if err != nil {
-		return nil, err
-	}
-	tty := &TtyConsole{
-		MasterPty: ptyMaster,
-		SlavePty:  ptySlave,
-	}
-	if err := tty.AttachPipes(&command.Cmd, pipes); err != nil {
-		tty.Close()
-		return nil, err
-	}
-	command.Console = tty.SlavePty.Name()
-	return tty, nil
-}
-
-func (t *TtyConsole) Master() *os.File {
-	return t.MasterPty
-}
-
-func (t *TtyConsole) Resize(h, w int) error {
-	return term.SetWinsize(t.MasterPty.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
-}
-
-func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *Pipes) error {
-	command.Stdout = t.SlavePty
-	command.Stderr = t.SlavePty
-
-	go func() {
-		if wb, ok := pipes.Stdout.(interface {
-			CloseWriters() error
-		}); ok {
-			defer wb.CloseWriters()
-		}
-		io.Copy(pipes.Stdout, t.MasterPty)
-	}()
-
-	if pipes.Stdin != nil {
-		command.Stdin = t.SlavePty
-		command.SysProcAttr.Setctty = true
-
-		go func() {
-			defer pipes.Stdin.Close()
-			io.Copy(t.MasterPty, pipes.Stdin)
-		}()
-	}
-	return nil
-}
-
-func (t *TtyConsole) Close() error {
-	t.SlavePty.Close()
-	return t.MasterPty.Close()
-}
-
 type StdConsole struct {
 }
 

+ 13 - 0
daemon/utils_linux.go

@@ -0,0 +1,13 @@
+// +build linux
+
+package daemon
+
+import "github.com/docker/libcontainer/selinux"
+
+func selinuxSetDisabled() {
+	selinux.SetDisabled()
+}
+
+func selinuxFreeLxcContexts(label string) {
+	selinux.FreeLxcContexts(label)
+}

+ 9 - 0
daemon/utils_nolinux.go

@@ -0,0 +1,9 @@
+// +build !linux
+
+package daemon
+
+func selinuxSetDisabled() {
+}
+
+func selinuxFreeLxcContexts(label string) {
+}

+ 1 - 1
hack/vendor.sh

@@ -63,4 +63,4 @@ mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
 
 clone git github.com/godbus/dbus v1
 clone git github.com/coreos/go-systemd v2
-clone git github.com/docker/libcontainer fb67bb80b4205bece36ff7096ee745ab0cee7e06
+clone git github.com/docker/libcontainer be85764f109c3f0f62cd2a5c8be9af7a599798cf

+ 8 - 0
vendor/src/github.com/docker/libcontainer/Dockerfile

@@ -0,0 +1,8 @@
+FROM crosbymichael/golang
+
+RUN apt-get update && apt-get install -y gcc
+
+ADD . /go/src/github.com/docker/libcontainer
+RUN cd /go/src/github.com/docker/libcontainer && go get -d ./... && go install ./...
+
+CMD ["nsinit"]

+ 1 - 1
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go

@@ -12,7 +12,7 @@ import (
 	"time"
 
 	"github.com/docker/libcontainer/cgroups"
-	"github.com/dotcloud/docker/pkg/system"
+	"github.com/docker/libcontainer/system"
 )
 
 var (

+ 78 - 8
vendor/src/github.com/docker/libcontainer/console/console.go

@@ -7,22 +7,24 @@ import (
 	"os"
 	"path/filepath"
 	"syscall"
+	"unsafe"
 
 	"github.com/docker/libcontainer/label"
-	"github.com/dotcloud/docker/pkg/system"
 )
 
 // Setup initializes the proper /dev/console inside the rootfs path
 func Setup(rootfs, consolePath, mountLabel string) error {
-	oldMask := system.Umask(0000)
-	defer system.Umask(oldMask)
+	oldMask := syscall.Umask(0000)
+	defer syscall.Umask(oldMask)
 
 	if err := os.Chmod(consolePath, 0600); err != nil {
 		return err
 	}
+
 	if err := os.Chown(consolePath, 0, 0); err != nil {
 		return err
 	}
+
 	if err := label.SetFileLabel(consolePath, mountLabel); err != nil {
 		return fmt.Errorf("set file label %s %s", consolePath, err)
 	}
@@ -33,26 +35,94 @@ func Setup(rootfs, consolePath, mountLabel string) error {
 	if err != nil && !os.IsExist(err) {
 		return fmt.Errorf("create %s %s", dest, err)
 	}
+
 	if f != nil {
 		f.Close()
 	}
 
-	if err := system.Mount(consolePath, dest, "bind", syscall.MS_BIND, ""); err != nil {
+	if err := syscall.Mount(consolePath, dest, "bind", syscall.MS_BIND, ""); err != nil {
 		return fmt.Errorf("bind %s to %s %s", consolePath, dest, err)
 	}
+
 	return nil
 }
 
 func OpenAndDup(consolePath string) error {
-	slave, err := system.OpenTerminal(consolePath, syscall.O_RDWR)
+	slave, err := OpenTerminal(consolePath, syscall.O_RDWR)
 	if err != nil {
 		return fmt.Errorf("open terminal %s", err)
 	}
-	if err := system.Dup2(slave.Fd(), 0); err != nil {
+
+	if err := syscall.Dup2(int(slave.Fd()), 0); err != nil {
 		return err
 	}
-	if err := system.Dup2(slave.Fd(), 1); err != nil {
+
+	if err := syscall.Dup2(int(slave.Fd()), 1); err != nil {
+		return err
+	}
+
+	return syscall.Dup2(int(slave.Fd()), 2)
+}
+
+// Unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
+// Unlockpt should be called before opening the slave side of a pseudoterminal.
+func Unlockpt(f *os.File) error {
+	var u int
+
+	return Ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
+}
+
+// Ptsname retrieves the name of the first available pts for the given master.
+func Ptsname(f *os.File) (string, error) {
+	var n int
+
+	if err := Ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
+		return "", err
+	}
+
+	return fmt.Sprintf("/dev/pts/%d", n), nil
+}
+
+// CreateMasterAndConsole will open /dev/ptmx on the host and retreive the
+// pts name for use as the pty slave inside the container
+func CreateMasterAndConsole() (*os.File, string, error) {
+	master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
+	if err != nil {
+		return nil, "", err
+	}
+
+	console, err := Ptsname(master)
+	if err != nil {
+		return nil, "", err
+	}
+
+	if err := Unlockpt(master); err != nil {
+		return nil, "", err
+	}
+
+	return master, console, nil
+}
+
+// OpenPtmx opens /dev/ptmx, i.e. the PTY master.
+func OpenPtmx() (*os.File, error) {
+	// O_NOCTTY and O_CLOEXEC are not present in os package so we use the syscall's one for all.
+	return os.OpenFile("/dev/ptmx", syscall.O_RDONLY|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
+}
+
+// OpenTerminal is a clone of os.OpenFile without the O_CLOEXEC
+// used to open the pty slave inside the container namespace
+func OpenTerminal(name string, flag int) (*os.File, error) {
+	r, e := syscall.Open(name, flag, 0)
+	if e != nil {
+		return nil, &os.PathError{"open", name, e}
+	}
+	return os.NewFile(uintptr(r), name), nil
+}
+
+func Ioctl(fd uintptr, flag, data uintptr) error {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
 		return err
 	}
-	return system.Dup2(slave.Fd(), 2)
+
+	return nil
 }

+ 8 - 9
vendor/src/github.com/docker/libcontainer/mount/init.go

@@ -11,7 +11,6 @@ import (
 	"github.com/docker/libcontainer/label"
 	"github.com/docker/libcontainer/mount/nodes"
 	"github.com/dotcloud/docker/pkg/symlink"
-	"github.com/dotcloud/docker/pkg/system"
 )
 
 // default mount point flags
@@ -35,10 +34,10 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig)
 	if mountConfig.NoPivotRoot {
 		flag = syscall.MS_SLAVE
 	}
-	if err := system.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
+	if err := syscall.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
 		return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err)
 	}
-	if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
+	if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
 		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
 	}
 	if err := mountSystem(rootfs, mountConfig); err != nil {
@@ -56,7 +55,7 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig)
 	if err := setupDevSymlinks(rootfs); err != nil {
 		return fmt.Errorf("dev symlinks %s", err)
 	}
-	if err := system.Chdir(rootfs); err != nil {
+	if err := syscall.Chdir(rootfs); err != nil {
 		return fmt.Errorf("chdir into %s %s", rootfs, err)
 	}
 
@@ -75,7 +74,7 @@ func InitializeMountNamespace(rootfs, console string, mountConfig *MountConfig)
 		}
 	}
 
-	system.Umask(0022)
+	syscall.Umask(0022)
 
 	return nil
 }
@@ -87,7 +86,7 @@ func mountSystem(rootfs string, mountConfig *MountConfig) error {
 		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
 			return fmt.Errorf("mkdirall %s %s", m.path, err)
 		}
-		if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
+		if err := syscall.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
 			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
 		}
 	}
@@ -169,11 +168,11 @@ func setupBindmounts(rootfs string, mountConfig *MountConfig) error {
 			return fmt.Errorf("Creating new bind-mount target, %s", err)
 		}
 
-		if err := system.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
+		if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags), ""); err != nil {
 			return fmt.Errorf("mounting %s into %s %s", m.Source, dest, err)
 		}
 		if !m.Writable {
-			if err := system.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
+			if err := syscall.Mount(m.Source, dest, "bind", uintptr(flags|syscall.MS_REMOUNT), ""); err != nil {
 				return fmt.Errorf("remounting %s into %s %s", m.Source, dest, err)
 			}
 		}
@@ -183,7 +182,7 @@ func setupBindmounts(rootfs string, mountConfig *MountConfig) error {
 			}
 		}
 		if m.Private {
-			if err := system.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
+			if err := syscall.Mount("", dest, "none", uintptr(syscall.MS_PRIVATE), ""); err != nil {
 				return fmt.Errorf("mounting %s private %s", dest, err)
 			}
 		}

+ 5 - 4
vendor/src/github.com/docker/libcontainer/mount/msmoveroot.go

@@ -4,16 +4,17 @@ package mount
 
 import (
 	"fmt"
-	"github.com/dotcloud/docker/pkg/system"
 	"syscall"
 )
 
 func MsMoveRoot(rootfs string) error {
-	if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
+	if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
 		return fmt.Errorf("mount move %s into / %s", rootfs, err)
 	}
-	if err := system.Chroot("."); err != nil {
+
+	if err := syscall.Chroot("."); err != nil {
 		return fmt.Errorf("chroot . %s", err)
 	}
-	return system.Chdir("/")
+
+	return syscall.Chdir("/")
 }

+ 3 - 4
vendor/src/github.com/docker/libcontainer/mount/nodes/nodes.go

@@ -9,13 +9,12 @@ import (
 	"syscall"
 
 	"github.com/docker/libcontainer/devices"
-	"github.com/dotcloud/docker/pkg/system"
 )
 
 // Create the device nodes in the container.
 func CreateDeviceNodes(rootfs string, nodesToCreate []*devices.Device) error {
-	oldMask := system.Umask(0000)
-	defer system.Umask(oldMask)
+	oldMask := syscall.Umask(0000)
+	defer syscall.Umask(oldMask)
 
 	for _, node := range nodesToCreate {
 		if err := CreateDeviceNode(rootfs, node); err != nil {
@@ -46,7 +45,7 @@ func CreateDeviceNode(rootfs string, node *devices.Device) error {
 		return fmt.Errorf("%c is not a valid device type for device %s", node.Type, node.Path)
 	}
 
-	if err := system.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) {
+	if err := syscall.Mknod(dest, uint32(fileMode), devices.Mkdev(node.MajorNumber, node.MinorNumber)); err != nil && !os.IsExist(err) {
 		return fmt.Errorf("mknod %s %s", node.Path, err)
 	}
 	return nil

+ 7 - 5
vendor/src/github.com/docker/libcontainer/mount/pivotroot.go

@@ -8,8 +8,6 @@ import (
 	"os"
 	"path/filepath"
 	"syscall"
-
-	"github.com/dotcloud/docker/pkg/system"
 )
 
 func PivotRoot(rootfs string) error {
@@ -17,16 +15,20 @@ func PivotRoot(rootfs string) error {
 	if err != nil {
 		return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
 	}
-	if err := system.Pivotroot(rootfs, pivotDir); err != nil {
+
+	if err := syscall.PivotRoot(rootfs, pivotDir); err != nil {
 		return fmt.Errorf("pivot_root %s", err)
 	}
-	if err := system.Chdir("/"); err != nil {
+
+	if err := syscall.Chdir("/"); err != nil {
 		return fmt.Errorf("chdir / %s", err)
 	}
+
 	// path to pivot dir now changed, update
 	pivotDir = filepath.Join("/", filepath.Base(pivotDir))
-	if err := system.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
+	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
 		return fmt.Errorf("unmount pivot_root dir %s", err)
 	}
+
 	return os.Remove(pivotDir)
 }

+ 5 - 1
vendor/src/github.com/docker/libcontainer/mount/ptmx.go

@@ -4,9 +4,10 @@ package mount
 
 import (
 	"fmt"
-	"github.com/docker/libcontainer/console"
 	"os"
 	"path/filepath"
+
+	"github.com/docker/libcontainer/console"
 )
 
 func SetupPtmx(rootfs, consolePath, mountLabel string) error {
@@ -14,13 +15,16 @@ func SetupPtmx(rootfs, consolePath, mountLabel string) error {
 	if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) {
 		return err
 	}
+
 	if err := os.Symlink("pts/ptmx", ptmx); err != nil {
 		return fmt.Errorf("symlink dev ptmx %s", err)
 	}
+
 	if consolePath != "" {
 		if err := console.Setup(rootfs, consolePath, mountLabel); err != nil {
 			return err
 		}
 	}
+
 	return nil
 }

+ 1 - 2
vendor/src/github.com/docker/libcontainer/mount/readonly.go

@@ -3,10 +3,9 @@
 package mount
 
 import (
-	"github.com/dotcloud/docker/pkg/system"
 	"syscall"
 )
 
 func SetReadonly() error {
-	return system.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
+	return syscall.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "")
 }

+ 8 - 8
vendor/src/github.com/docker/libcontainer/mount/remount.go

@@ -2,30 +2,30 @@
 
 package mount
 
-import (
-	"github.com/dotcloud/docker/pkg/system"
-	"syscall"
-)
+import "syscall"
 
 func RemountProc() error {
-	if err := system.Unmount("/proc", syscall.MNT_DETACH); err != nil {
+	if err := syscall.Unmount("/proc", syscall.MNT_DETACH); err != nil {
 		return err
 	}
-	if err := system.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), ""); err != nil {
+
+	if err := syscall.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), ""); err != nil {
 		return err
 	}
+
 	return nil
 }
 
 func RemountSys() error {
-	if err := system.Unmount("/sys", syscall.MNT_DETACH); err != nil {
+	if err := syscall.Unmount("/sys", syscall.MNT_DETACH); err != nil {
 		if err != syscall.EINVAL {
 			return err
 		}
 	} else {
-		if err := system.Mount("sysfs", "/sys", "sysfs", uintptr(defaultMountFlags), ""); err != nil {
+		if err := syscall.Mount("sysfs", "/sys", "sysfs", uintptr(defaultMountFlags), ""); err != nil {
 			return err
 		}
 	}
+
 	return nil
 }

+ 19 - 19
vendor/src/github.com/docker/libcontainer/namespaces/exec.go

@@ -3,6 +3,7 @@
 package namespaces
 
 import (
+	"io"
 	"os"
 	"os/exec"
 	"syscall"
@@ -13,18 +14,16 @@ import (
 	"github.com/docker/libcontainer/cgroups/systemd"
 	"github.com/docker/libcontainer/network"
 	"github.com/docker/libcontainer/syncpipe"
-	"github.com/dotcloud/docker/pkg/system"
+	"github.com/docker/libcontainer/system"
 )
 
 // TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work.
 // Move this to libcontainer package.
 // Exec performs setup outside of a namespace so that a container can be
 // executed.  Exec is a high level function for working with container namespaces.
-func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
+func Exec(container *libcontainer.Config, stdin io.Reader, stdout, stderr io.Writer, console string, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
 	var (
-		master  *os.File
-		console string
-		err     error
+		err error
 	)
 
 	// create a pipe so that we can syncronize with the namespaced process and
@@ -35,20 +34,13 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
 	}
 	defer syncPipe.Close()
 
-	if container.Tty {
-		master, console, err = system.CreateMasterAndConsole()
-		if err != nil {
-			return -1, err
-		}
-		term.SetMaster(master)
-	}
-
 	command := createCommand(container, console, rootfs, dataPath, os.Args[0], syncPipe.Child(), args)
-
-	if err := term.Attach(command); err != nil {
-		return -1, err
-	}
-	defer term.Close()
+	// Note: these are only used in non-tty mode
+	// if there is a tty for the container it will be opened within the namespace and the
+	// fds will be duped to stdin, stdiout, and stderr
+	command.Stdin = stdin
+	command.Stdout = stdout
+	command.Stderr = stderr
 
 	if err := command.Start(); err != nil {
 		return -1, err
@@ -110,6 +102,7 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string
 			return -1, err
 		}
 	}
+
 	return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil
 }
 
@@ -145,7 +138,11 @@ func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataP
 	command.Dir = rootfs
 	command.Env = append(os.Environ(), env...)
 
-	system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
+	if command.SysProcAttr == nil {
+		command.SysProcAttr = &syscall.SysProcAttr{}
+	}
+	command.SysProcAttr.Cloneflags = uintptr(GetNamespaceFlags(container.Namespaces))
+
 	command.SysProcAttr.Pdeathsig = syscall.SIGKILL
 	command.ExtraFiles = []*os.File{pipe}
 
@@ -157,11 +154,14 @@ func DefaultCreateCommand(container *libcontainer.Config, console, rootfs, dataP
 func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgroup, error) {
 	if container.Cgroups != nil {
 		c := container.Cgroups
+
 		if systemd.UseSystemd() {
 			return systemd.Apply(c, nspid)
 		}
+
 		return fs.Apply(c, nspid)
 	}
+
 	return nil, nil
 }
 

+ 1 - 1
vendor/src/github.com/docker/libcontainer/namespaces/execin.go

@@ -9,7 +9,7 @@ import (
 
 	"github.com/docker/libcontainer"
 	"github.com/docker/libcontainer/label"
-	"github.com/dotcloud/docker/pkg/system"
+	"github.com/docker/libcontainer/system"
 )
 
 // ExecIn uses an existing pid and joins the pid's namespaces with the new command.

+ 11 - 7
vendor/src/github.com/docker/libcontainer/namespaces/init.go

@@ -19,8 +19,8 @@ import (
 	"github.com/docker/libcontainer/security/capabilities"
 	"github.com/docker/libcontainer/security/restrict"
 	"github.com/docker/libcontainer/syncpipe"
+	"github.com/docker/libcontainer/system"
 	"github.com/docker/libcontainer/utils"
-	"github.com/dotcloud/docker/pkg/system"
 	"github.com/dotcloud/docker/pkg/user"
 )
 
@@ -57,7 +57,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
 			return err
 		}
 	}
-	if _, err := system.Setsid(); err != nil {
+	if _, err := syscall.Setsid(); err != nil {
 		return fmt.Errorf("setsid %s", err)
 	}
 	if consolePath != "" {
@@ -81,7 +81,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn
 	}
 
 	if container.Hostname != "" {
-		if err := system.Sethostname(container.Hostname); err != nil {
+		if err := syscall.Sethostname([]byte(container.Hostname)); err != nil {
 			return fmt.Errorf("sethostname %s", err)
 		}
 	}
@@ -155,15 +155,19 @@ func SetupUser(u string) error {
 	if err != nil {
 		return fmt.Errorf("get supplementary groups %s", err)
 	}
-	if err := system.Setgroups(suppGids); err != nil {
+
+	if err := syscall.Setgroups(suppGids); err != nil {
 		return fmt.Errorf("setgroups %s", err)
 	}
-	if err := system.Setgid(gid); err != nil {
+
+	if err := syscall.Setgid(gid); err != nil {
 		return fmt.Errorf("setgid %s", err)
 	}
-	if err := system.Setuid(uid); err != nil {
+
+	if err := syscall.Setuid(uid); err != nil {
 		return fmt.Errorf("setuid %s", err)
 	}
+
 	return nil
 }
 
@@ -229,7 +233,7 @@ func FinalizeNamespace(container *libcontainer.Config) error {
 	}
 
 	if container.WorkingDir != "" {
-		if err := system.Chdir(container.WorkingDir); err != nil {
+		if err := syscall.Chdir(container.WorkingDir); err != nil {
 			return fmt.Errorf("chdir to %s %s", container.WorkingDir, err)
 		}
 	}

+ 0 - 49
vendor/src/github.com/docker/libcontainer/namespaces/std_term.go

@@ -1,49 +0,0 @@
-package namespaces
-
-import (
-	"io"
-	"os"
-	"os/exec"
-)
-
-type StdTerminal struct {
-	stdin          io.Reader
-	stdout, stderr io.Writer
-}
-
-func (s *StdTerminal) SetMaster(*os.File) {
-	// no need to set master on non tty
-}
-
-func (s *StdTerminal) Close() error {
-	return nil
-}
-
-func (s *StdTerminal) Resize(h, w int) error {
-	return nil
-}
-
-func (s *StdTerminal) Attach(command *exec.Cmd) error {
-	inPipe, err := command.StdinPipe()
-	if err != nil {
-		return err
-	}
-	outPipe, err := command.StdoutPipe()
-	if err != nil {
-		return err
-	}
-	errPipe, err := command.StderrPipe()
-	if err != nil {
-		return err
-	}
-
-	go func() {
-		defer inPipe.Close()
-		io.Copy(inPipe, s.stdin)
-	}()
-
-	go io.Copy(s.stdout, outPipe)
-	go io.Copy(s.stderr, errPipe)
-
-	return nil
-}

+ 0 - 29
vendor/src/github.com/docker/libcontainer/namespaces/term.go

@@ -1,29 +0,0 @@
-package namespaces
-
-import (
-	"io"
-	"os"
-	"os/exec"
-)
-
-type Terminal interface {
-	io.Closer
-	SetMaster(*os.File)
-	Attach(*exec.Cmd) error
-	Resize(h, w int) error
-}
-
-func NewTerminal(stdin io.Reader, stdout, stderr io.Writer, tty bool) Terminal {
-	if tty {
-		return &TtyTerminal{
-			stdin:  stdin,
-			stdout: stdout,
-			stderr: stderr,
-		}
-	}
-	return &StdTerminal{
-		stdin:  stdin,
-		stdout: stdout,
-		stderr: stderr,
-	}
-}

+ 0 - 56
vendor/src/github.com/docker/libcontainer/namespaces/tty_term.go

@@ -1,56 +0,0 @@
-package namespaces
-
-import (
-	"io"
-	"os"
-	"os/exec"
-
-	"github.com/dotcloud/docker/pkg/term"
-)
-
-type TtyTerminal struct {
-	stdin          io.Reader
-	stdout, stderr io.Writer
-	master         *os.File
-	state          *term.State
-}
-
-func (t *TtyTerminal) Resize(h, w int) error {
-	return term.SetWinsize(t.master.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
-}
-
-func (t *TtyTerminal) SetMaster(master *os.File) {
-	t.master = master
-}
-
-func (t *TtyTerminal) Attach(command *exec.Cmd) error {
-	go io.Copy(t.stdout, t.master)
-	go io.Copy(t.master, t.stdin)
-
-	state, err := t.setupWindow(t.master, os.Stdin)
-
-	if err != nil {
-		return err
-	}
-
-	t.state = state
-	return err
-}
-
-// SetupWindow gets the parent window size and sets the master
-// pty to the current size and set the parents mode to RAW
-func (t *TtyTerminal) setupWindow(master, parent *os.File) (*term.State, error) {
-	ws, err := term.GetWinsize(parent.Fd())
-	if err != nil {
-		return nil, err
-	}
-	if err := term.SetWinsize(master.Fd(), ws); err != nil {
-		return nil, err
-	}
-	return term.SetRawTerminal(parent.Fd())
-}
-
-func (t *TtyTerminal) Close() error {
-	term.RestoreTerminal(os.Stdin.Fd(), t.state)
-	return t.master.Close()
-}

+ 0 - 28
vendor/src/github.com/docker/libcontainer/namespaces/unsupported.go

@@ -1,28 +0,0 @@
-// +build !linux
-
-package namespaces
-
-import (
-	"github.com/docker/libcontainer"
-	"github.com/docker/libcontainer/cgroups"
-)
-
-func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string, args []string, createCommand CreateCommand, startCallback func()) (int, error) {
-	return -1, ErrUnsupported
-}
-
-func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *SyncPipe, args []string) error {
-	return ErrUnsupported
-}
-
-func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe) error {
-	return ErrUnsupported
-}
-
-func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgroup, error) {
-	return nil, ErrUnsupported
-}
-
-func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
-	return 0
-}

+ 1 - 3
vendor/src/github.com/docker/libcontainer/network/loopback.go

@@ -15,9 +15,7 @@ func (l *Loopback) Create(n *Network, nspid int, networkState *NetworkState) err
 }
 
 func (l *Loopback) Initialize(config *Network, networkState *NetworkState) error {
-	if err := SetMtu("lo", config.Mtu); err != nil {
-		return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
-	}
+	// Do not set the MTU on the loopback interface - use the default.
 	if err := InterfaceUp("lo"); err != nil {
 		return fmt.Errorf("lo up %s", err)
 	}

+ 4 - 1
vendor/src/github.com/docker/libcontainer/network/netns.go

@@ -7,7 +7,7 @@ import (
 	"os"
 	"syscall"
 
-	"github.com/dotcloud/docker/pkg/system"
+	"github.com/docker/libcontainer/system"
 )
 
 //  crosbymichael: could make a network strategy that instead of returning veth pair names it returns a pid to an existing network namespace
@@ -23,12 +23,15 @@ func (v *NetNS) Initialize(config *Network, networkState *NetworkState) error {
 	if networkState.NsPath == "" {
 		return fmt.Errorf("nspath does is not specified in NetworkState")
 	}
+
 	f, err := os.OpenFile(networkState.NsPath, os.O_RDONLY, 0)
 	if err != nil {
 		return fmt.Errorf("failed get network namespace fd: %v", err)
 	}
+
 	if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil {
 		return fmt.Errorf("failed to setns current network namespace: %v", err)
 	}
+
 	return nil
 }

+ 1 - 0
vendor/src/github.com/docker/libcontainer/network/types.go

@@ -25,6 +25,7 @@ type Network struct {
 
 	// Mtu sets the mtu value for the interface and will be mirrored on both the host and
 	// container's interfaces if a pair is created, specifically in the case of type veth
+	// Note: This does not apply to loopback interfaces.
 	Mtu int `json:"mtu,omitempty"`
 }
 

+ 61 - 5
vendor/src/github.com/docker/libcontainer/nsinit/exec.go

@@ -2,14 +2,18 @@ package nsinit
 
 import (
 	"fmt"
+	"io"
 	"log"
 	"os"
 	"os/exec"
 	"os/signal"
+	"syscall"
 
 	"github.com/codegangsta/cli"
 	"github.com/docker/libcontainer"
+	consolepkg "github.com/docker/libcontainer/console"
 	"github.com/docker/libcontainer/namespaces"
+	"github.com/dotcloud/docker/pkg/term"
 )
 
 var execCommand = cli.Command{
@@ -34,8 +38,7 @@ func execAction(context *cli.Context) {
 	if state != nil {
 		err = namespaces.ExecIn(container, state, []string(context.Args()))
 	} else {
-		term := namespaces.NewTerminal(os.Stdin, os.Stdout, os.Stderr, container.Tty)
-		exitCode, err = startContainer(container, term, dataPath, []string(context.Args()))
+		exitCode, err = startContainer(container, dataPath, []string(context.Args()))
 	}
 
 	if err != nil {
@@ -49,7 +52,7 @@ func execAction(context *cli.Context) {
 // error.
 //
 // Signals sent to the current process will be forwarded to container.
-func startContainer(container *libcontainer.Config, term namespaces.Terminal, dataPath string, args []string) (int, error) {
+func startContainer(container *libcontainer.Config, dataPath string, args []string) (int, error) {
 	var (
 		cmd  *exec.Cmd
 		sigc = make(chan os.Signal, 10)
@@ -65,13 +68,66 @@ func startContainer(container *libcontainer.Config, term namespaces.Terminal, da
 		return cmd
 	}
 
+	var (
+		master  *os.File
+		console string
+		err     error
+
+		stdin  = os.Stdin
+		stdout = os.Stdout
+		stderr = os.Stderr
+	)
+
+	if container.Tty {
+		stdin = nil
+		stdout = nil
+		stderr = nil
+
+		master, console, err = consolepkg.CreateMasterAndConsole()
+		if err != nil {
+			return -1, err
+		}
+
+		go io.Copy(master, os.Stdin)
+		go io.Copy(os.Stdout, master)
+
+		state, err := term.SetRawTerminal(os.Stdin.Fd())
+		if err != nil {
+			return -1, err
+		}
+
+		defer term.RestoreTerminal(os.Stdin.Fd(), state)
+	}
+
 	startCallback := func() {
 		go func() {
+			resizeTty(master)
+
 			for sig := range sigc {
-				cmd.Process.Signal(sig)
+				switch sig {
+				case syscall.SIGWINCH:
+					resizeTty(master)
+				default:
+					cmd.Process.Signal(sig)
+				}
 			}
 		}()
 	}
 
-	return namespaces.Exec(container, term, "", dataPath, args, createCommand, startCallback)
+	return namespaces.Exec(container, stdin, stdout, stderr, console, "", dataPath, args, createCommand, startCallback)
+}
+
+func resizeTty(master *os.File) {
+	if master == nil {
+		return
+	}
+
+	ws, err := term.GetWinsize(os.Stdin.Fd())
+	if err != nil {
+		return
+	}
+
+	if err := term.SetWinsize(master.Fd(), ws); err != nil {
+		return
+	}
 }

+ 4 - 6
vendor/src/github.com/docker/libcontainer/security/restrict/restrict.go

@@ -7,23 +7,21 @@ import (
 	"os"
 	"syscall"
 	"time"
-
-	"github.com/dotcloud/docker/pkg/system"
 )
 
 const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
 
 func mountReadonly(path string) error {
 	for i := 0; i < 5; i++ {
-		if err := system.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) {
+		if err := syscall.Mount("", path, "", syscall.MS_REMOUNT|syscall.MS_RDONLY, ""); err != nil && !os.IsNotExist(err) {
 			switch err {
 			case syscall.EINVAL:
 				// Probably not a mountpoint, use bind-mount
-				if err := system.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
+				if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil {
 					return err
 				}
 
-				return system.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "")
+				return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC|defaultMountFlags, "")
 			case syscall.EBUSY:
 				time.Sleep(100 * time.Millisecond)
 				continue
@@ -47,7 +45,7 @@ func Restrict(mounts ...string) error {
 		}
 	}
 
-	if err := system.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
+	if err := syscall.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) {
 		return fmt.Errorf("unable to bind-mount /dev/null over /proc/kcore: %s", err)
 	}
 

+ 7 - 6
vendor/src/github.com/docker/libcontainer/selinux/selinux.go

@@ -5,8 +5,6 @@ import (
 	"crypto/rand"
 	"encoding/binary"
 	"fmt"
-	"github.com/dotcloud/docker/pkg/mount"
-	"github.com/dotcloud/docker/pkg/system"
 	"io"
 	"os"
 	"path/filepath"
@@ -14,6 +12,9 @@ import (
 	"strconv"
 	"strings"
 	"syscall"
+
+	"github.com/docker/libcontainer/system"
+	"github.com/dotcloud/docker/pkg/mount"
 )
 
 const (
@@ -153,16 +154,16 @@ func Getfilecon(path string) (string, error) {
 }
 
 func Setfscreatecon(scon string) error {
-	return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", system.Gettid()), scon)
+	return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), scon)
 }
 
 func Getfscreatecon() (string, error) {
-	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", system.Gettid()))
+	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()))
 }
 
 // Return the SELinux label of the current process thread.
 func Getcon() (string, error) {
-	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", system.Gettid()))
+	return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()))
 }
 
 func Getpidcon(pid int) (string, error) {
@@ -192,7 +193,7 @@ func writeCon(name string, val string) error {
 }
 
 func Setexeccon(scon string) error {
-	return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", system.Gettid()), scon)
+	return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), scon)
 }
 
 func (c SELinuxContext) Get() string {

+ 60 - 0
vendor/src/github.com/docker/libcontainer/system/linux.go

@@ -0,0 +1,60 @@
+// +build linux
+
+package system
+
+import (
+	"os/exec"
+	"syscall"
+	"unsafe"
+)
+
+func Execv(cmd string, args []string, env []string) error {
+	name, err := exec.LookPath(cmd)
+	if err != nil {
+		return err
+	}
+
+	return syscall.Exec(name, args, env)
+}
+
+func ParentDeathSignal(sig uintptr) error {
+	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 {
+		return err
+	}
+	return nil
+}
+
+func GetParentDeathSignal() (int, error) {
+	var sig int
+
+	_, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0)
+
+	if err != 0 {
+		return -1, err
+	}
+
+	return sig, nil
+}
+
+func SetKeepCaps() error {
+	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 {
+		return err
+	}
+
+	return nil
+}
+
+func ClearKeepCaps() error {
+	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 {
+		return err
+	}
+
+	return nil
+}
+
+func Setctty() error {
+	if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 {
+		return err
+	}
+	return nil
+}

+ 27 - 0
vendor/src/github.com/docker/libcontainer/system/proc.go

@@ -0,0 +1,27 @@
+package system
+
+import (
+	"io/ioutil"
+	"path/filepath"
+	"strconv"
+	"strings"
+)
+
+// look in /proc to find the process start time so that we can verify
+// that this pid has started after ourself
+func GetProcessStartTime(pid int) (string, error) {
+	data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
+	if err != nil {
+		return "", err
+	}
+
+	parts := strings.Split(string(data), " ")
+	// the starttime is located at pos 22
+	// from the man page
+	//
+	// starttime %llu (was %lu before Linux 2.6)
+	// (22)  The  time the process started after system boot.  In kernels before Linux 2.6, this
+	// value was expressed in jiffies.  Since Linux 2.6, the value is expressed in  clock  ticks
+	// (divide by sysconf(_SC_CLK_TCK)).
+	return parts[22-1], nil // starts at 1
+}

+ 29 - 0
vendor/src/github.com/docker/libcontainer/system/setns_linux.go

@@ -0,0 +1,29 @@
+package system
+
+import (
+	"fmt"
+	"runtime"
+	"syscall"
+)
+
+// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092
+//
+// We need different setns values for the different platforms and arch
+// We are declaring the macro here because the SETNS syscall does not exist in th stdlib
+var setNsMap = map[string]uintptr{
+	"linux/amd64": 308,
+}
+
+func Setns(fd uintptr, flags uintptr) error {
+	ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
+	if !exists {
+		return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+
+	_, _, err := syscall.RawSyscall(ns, fd, flags, 0)
+	if err != 0 {
+		return err
+	}
+
+	return nil
+}

+ 0 - 0
pkg/system/sysconfig.go → vendor/src/github.com/docker/libcontainer/system/sysconfig.go


+ 59 - 0
vendor/src/github.com/docker/libcontainer/system/xattrs_linux.go

@@ -0,0 +1,59 @@
+package system
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// Returns a nil slice and nil error if the xattr is not set
+func Lgetxattr(path string, attr string) ([]byte, error) {
+	pathBytes, err := syscall.BytePtrFromString(path)
+	if err != nil {
+		return nil, err
+	}
+	attrBytes, err := syscall.BytePtrFromString(attr)
+	if err != nil {
+		return nil, err
+	}
+
+	dest := make([]byte, 128)
+	destBytes := unsafe.Pointer(&dest[0])
+	sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
+	if errno == syscall.ENODATA {
+		return nil, nil
+	}
+	if errno == syscall.ERANGE {
+		dest = make([]byte, sz)
+		destBytes := unsafe.Pointer(&dest[0])
+		sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
+	}
+	if errno != 0 {
+		return nil, errno
+	}
+
+	return dest[:sz], nil
+}
+
+var _zero uintptr
+
+func Lsetxattr(path string, attr string, data []byte, flags int) error {
+	pathBytes, err := syscall.BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+	attrBytes, err := syscall.BytePtrFromString(attr)
+	if err != nil {
+		return err
+	}
+	var dataBytes unsafe.Pointer
+	if len(data) > 0 {
+		dataBytes = unsafe.Pointer(&data[0])
+	} else {
+		dataBytes = unsafe.Pointer(&_zero)
+	}
+	_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}