diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-10-03 10:31:01 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-10-03 10:32:03 -0700 |
commit | e215b9970ad82915a8d544b81b3c49d7d84a0eb0 (patch) | |
tree | ca7fafed97a41307243ab7fc84d0a19e285dee53 /runsc/sandbox | |
parent | 77e43adeab4abcd301d76222e0304f551fbcf0cc (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.go | 50 |
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 |