daemon: close exec config streams with timeout

Closing streams of exec config can be blocked idefinitely when
writes of output streams are blocked - similarly to what may
happen to container's own output streams when there is a
non-reading attached client. This may block container shutdown,
preventing it from completing. Use context with timeout to limit
the time waiting for execConfig.CloseStreams to complete during
container shutdown.

Signed-off-by: Daniil Sigalov <asterite@seclab.cs.msu.ru>
This commit is contained in:
Daniil Sigalov 2021-06-10 13:24:44 +03:00
parent e9bfffa378
commit 695ebbafd8
3 changed files with 6 additions and 4 deletions

View file

@ -65,8 +65,8 @@ func (c *ExecConfig) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) {
}
// CloseStreams closes the stdio streams for the exec
func (c *ExecConfig) CloseStreams() error {
return c.StreamConfig.CloseStreams(context.Background())
func (c *ExecConfig) CloseStreams(ctx context.Context) error {
return c.StreamConfig.CloseStreams(ctx)
}
// SetExitCode sets the exec config's exit code

View file

@ -187,7 +187,7 @@ func (daemon *Daemon) ContainerExecStart(ctx context.Context, name string, optio
ec.Running = false
exitCode := 126
ec.ExitCode = &exitCode
if err := ec.CloseStreams(); err != nil {
if err := ec.CloseStreams(ctx); err != nil {
log.G(ctx).Errorf("failed to cleanup exec %s streams: %s", ec.Container.ID, err)
}
ec.Unlock()

View file

@ -191,9 +191,11 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerdtypes.EventType, ei
execConfig.StreamConfig.Wait(ctx)
cancel()
if err := execConfig.CloseStreams(); err != nil {
ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
if err := execConfig.CloseStreams(ctx); err != nil {
log.G(ctx).Errorf("failed to cleanup exec %s streams: %s", c.ID, err)
}
cancel()
exitCode = ec