diff options
author | Kevin Krakauer <krakauer@google.com> | 2018-09-19 22:19:10 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-19 22:20:41 -0700 |
commit | ffb5fdd69021713e88ec965e77487b7fc28bc104 (patch) | |
tree | f063a16a1acb56efc62f3b501b9c905648705080 /runsc/boot/loader.go | |
parent | 915d76aa924c08b1fcb80a58e3caa24529a23d04 (diff) |
runsc: Fix stdin/stdout/stderr in multi-container mode.
The issue with the previous change was that the stdin/stdout/stderr passed to
the sentry were dup'd by host.ImportFile. This left a dangling FD that by never
closing caused containerd to timeout waiting on container stop.
PiperOrigin-RevId: 213753032
Change-Id: Ia5e4c0565c42c8610d3b59f65599a5643b0901e4
Diffstat (limited to 'runsc/boot/loader.go')
-rw-r--r-- | runsc/boot/loader.go | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index f906c9f95..e47eced18 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -78,8 +78,11 @@ type Loader struct { watchdog *watchdog.Watchdog - // ioFDs are the FDs that attach the sandbox to the gofers. - ioFDs []int + // stdioFDs contains stdin, stdout, and stderr. + stdioFDs []int + + // goferFDs are the FDs that attach the sandbox to the gofers. + goferFDs []int // spec is the base configuration for the root container. spec *specs.Spec @@ -139,7 +142,7 @@ func init() { // New initializes a new kernel loader configured by spec. // New also handles setting up a kernel for restoring a container. -func New(spec *specs.Spec, conf *Config, controllerFD, deviceFD int, ioFDs []int, console bool) (*Loader, error) { +func New(spec *specs.Spec, conf *Config, controllerFD, deviceFD int, goferFDs []int, console bool) (*Loader, error) { if err := usage.Init(); err != nil { return nil, fmt.Errorf("Error setting up memory usage: %v", err) } @@ -278,7 +281,8 @@ func New(spec *specs.Spec, conf *Config, controllerFD, deviceFD int, ioFDs []int conf: conf, console: console, watchdog: watchdog, - ioFDs: ioFDs, + stdioFDs: []int{syscall.Stdin, syscall.Stdout, syscall.Stderr}, + goferFDs: goferFDs, spec: spec, startSignalForwarding: startSignalForwarding, rootProcArgs: procArgs, @@ -390,7 +394,8 @@ func (l *Loader) run() error { &l.rootProcArgs, l.spec, l.conf, - l.ioFDs, + l.stdioFDs, + l.goferFDs, l.console, l.rootProcArgs.Credentials, l.rootProcArgs.Limits, @@ -474,11 +479,14 @@ func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config ioFDs = append(ioFDs, fd) } + stdioFDs := ioFDs[:3] + goferFDs := ioFDs[3:] if err := setFileSystemForProcess( &procArgs, spec, conf, - ioFDs, + stdioFDs, + goferFDs, false, creds, procArgs.Limits, @@ -487,6 +495,13 @@ func (l *Loader) startContainer(k *kernel.Kernel, spec *specs.Spec, conf *Config return fmt.Errorf("failed to create new process: %v", err) } + // setFileSystemForProcess dup'd stdioFDs, so we can close them. + for i, fd := range stdioFDs { + if err := syscall.Close(fd); err != nil { + return fmt.Errorf("failed to close stdioFD #%d: %v", i, fd) + } + } + ctx := procArgs.NewContext(l.k) mns := k.RootMountNamespace() if err := setExecutablePath(ctx, mns, &procArgs); err != nil { |