summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot/loader.go
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2018-09-19 22:19:10 -0700
committerShentubot <shentubot@google.com>2018-09-19 22:20:41 -0700
commitffb5fdd69021713e88ec965e77487b7fc28bc104 (patch)
treef063a16a1acb56efc62f3b501b9c905648705080 /runsc/boot/loader.go
parent915d76aa924c08b1fcb80a58e3caa24529a23d04 (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.go27
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 {