summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2018-10-03 10:31:01 -0700
committerShentubot <shentubot@google.com>2018-10-03 10:32:03 -0700
commite215b9970ad82915a8d544b81b3c49d7d84a0eb0 (patch)
treeca7fafed97a41307243ab7fc84d0a19e285dee53 /runsc/sandbox
parent77e43adeab4abcd301d76222e0304f551fbcf0cc (diff)
runsc: Pass root container's stdio via FD.
We were previously using the sandbox process's stdio as the root container's stdio. This makes it difficult/impossible to distinguish output application output from sandbox output, such as panics, which are always written to stderr. Also close the console socket when we are done with it. PiperOrigin-RevId: 215585180 Change-Id: I980b8c69bd61a8b8e0a496fd7bc90a06446764e0
Diffstat (limited to 'runsc/sandbox')
-rw-r--r--runsc/sandbox/sandbox.go50
1 files changed, 37 insertions, 13 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index e4853af69..1ed1ab61d 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -285,9 +285,6 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
// All flags after this must be for the boot command
cmd.Args = append(cmd.Args, "boot", "--bundle="+bundleDir)
- consoleEnabled := consoleSocket != ""
- cmd.Args = append(cmd.Args, "--console="+strconv.FormatBool(consoleEnabled))
-
// Create a socket for the control server and donate it to the sandbox.
addr := boot.ControlSocketAddr(s.ID)
sockFD, err := server.CreateSocket(addr)
@@ -332,27 +329,54 @@ func (s *Sandbox) createSandboxProcess(spec *specs.Spec, conf *boot.Config, bund
nextFD++
}
- // Sandbox stdio defaults to current process stdio.
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
-
// If the console control socket file is provided, then create a new
// pty master/slave pair and set the TTY on the sandbox process.
- if consoleEnabled {
- // console.NewWithSocket will send the master on the socket,
- // and return the slave.
+ if consoleSocket != "" {
+ cmd.Args = append(cmd.Args, "--console=true")
+
+ // console.NewWithSocket will send the master on the given
+ // socket, and return the slave.
tty, err := console.NewWithSocket(consoleSocket)
if err != nil {
return fmt.Errorf("error setting up console with socket %q: %v", consoleSocket, err)
}
defer tty.Close()
+ fd := int(tty.Fd())
+
+ // Set the TTY as a controlling TTY on the sandbox process.
+ cmd.SysProcAttr.Setctty = true
+ cmd.SysProcAttr.Ctty = fd
+ // Ideally we would set the sandbox stdin to this process'
+ // stdin, but for some reason Docker does not like that (it
+ // never calls `runsc start`). Instead we set stdio to the
+ // console TTY, but note that this is distinct from the
+ // container stdio, which is passed via the flags below.
cmd.Stdin = tty
cmd.Stdout = tty
cmd.Stderr = tty
- cmd.SysProcAttr.Setctty = true
- cmd.SysProcAttr.Ctty = int(tty.Fd())
+
+ // Pass the tty as all stdio fds to sandbox.
+ for i := 0; i < 3; i++ {
+ cmd.ExtraFiles = append(cmd.ExtraFiles, tty)
+ cmd.Args = append(cmd.Args, "--stdio-fds="+strconv.Itoa(nextFD))
+ nextFD++
+ }
+ } else {
+ // Connect the sandbox process to this process's stdios. Note
+ // that this is distinct from the container's stdio, which is
+ // passed by the flags below.
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+
+ // If not using a console, pass our current stdio as the
+ // container stdio via flags.
+ for _, f := range []*os.File{os.Stdin, os.Stdout, os.Stderr} {
+ cmd.ExtraFiles = append(cmd.ExtraFiles, f)
+ cmd.Args = append(cmd.Args, "--stdio-fds="+strconv.Itoa(nextFD))
+ nextFD++
+ }
}
// Detach from this session, otherwise cmd will get SIGHUP and SIGCONT