Don't create pty slave in the daemon for native driver

Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@docker.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-07-15 18:31:46 -07:00
parent 9fc6058aa1
commit 1501c342d8
4 changed files with 22 additions and 86 deletions

View file

@ -95,6 +95,11 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
if err != nil {
return -1, err
}
if err := execdriver.SetTerminal(c, pipes); err != nil {
return -1, err
}
d.Lock()
d.activeContainers[c.ID] = &activeContainer{
container: container,
@ -106,6 +111,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 +121,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 +205,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
}
@ -266,18 +272,3 @@ 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,
}
}
c.Terminal = term
return term
}

View file

@ -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
}

View file

@ -1,11 +1,12 @@
package execdriver
import (
"github.com/dotcloud/docker/pkg/term"
"github.com/kr/pty"
"io"
"os"
"os/exec"
"github.com/dotcloud/docker/pkg/system"
"github.com/dotcloud/docker/pkg/term"
)
func SetTerminal(command *Command, pipes *Pipes) error {
@ -13,37 +14,42 @@ func SetTerminal(command *Command, pipes *Pipes) error {
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()
ptyMaster, console, err := system.CreateMasterAndConsole()
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()
command.Console = console
return tty, nil
}
@ -56,9 +62,6 @@ func (t *TtyConsole) Resize(h, w int) error {
}
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
@ -69,19 +72,16 @@ func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *Pipes) error {
}()
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()
}

View file

@ -1,13 +0,0 @@
// +build linux,cgo
package system
/*
#include <unistd.h>
int get_hz(void) { return sysconf(_SC_CLK_TCK); }
*/
import "C"
func GetClockTicks() int {
return int(C.get_hz())
}