Skip to content

Commit 7b26da9

Browse files
committed
libcontainer: Prevent startup hang when CloseExecFrom errors
The previous logic caused runc to hang if CloseExecFrom returned an error, as the defer waiting on logsDone never finished as the parent process was never started (and it controls the closing of logsDone via it's logsPipe). This moves the defer to after we have started the parent, with means all the logic related to managing the logsPipe should also be running. Signed-off-by: Evan Phoenix <evan@phx.io>
1 parent a7d7645 commit 7b26da9

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

libcontainer/container_linux.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -324,16 +324,6 @@ func (c *Container) start(process *Process) (retErr error) {
324324
defer process.closeClonedExes()
325325

326326
logsDone := parent.forwardChildLogs()
327-
if logsDone != nil {
328-
defer func() {
329-
// Wait for log forwarder to finish. This depends on
330-
// runc init closing the _LIBCONTAINER_LOGPIPE log fd.
331-
err := <-logsDone
332-
if err != nil && retErr == nil {
333-
retErr = fmt.Errorf("unable to forward init logs: %w", err)
334-
}
335-
}()
336-
}
337327

338328
// Before starting "runc init", mark all non-stdio open files as O_CLOEXEC
339329
// to make sure we don't leak any files into "runc init". Any files to be
@@ -348,6 +338,17 @@ func (c *Container) start(process *Process) (retErr error) {
348338
return fmt.Errorf("unable to start container process: %w", err)
349339
}
350340

341+
if logsDone != nil {
342+
defer func() {
343+
// Wait for log forwarder to finish. This depends on
344+
// runc init closing the _LIBCONTAINER_LOGPIPE log fd.
345+
err := <-logsDone
346+
if err != nil && retErr == nil {
347+
retErr = fmt.Errorf("unable to forward init logs: %w", err)
348+
}
349+
}()
350+
}
351+
351352
if process.Init {
352353
c.fifo.Close()
353354
if c.config.HasHook(configs.Poststart) {

0 commit comments

Comments
 (0)