diff --git a/daemon/daemon.go b/daemon/daemon.go index 16510316b5..0a094e3087 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -949,25 +949,30 @@ func (daemon *Daemon) shutdownContainer(c *container.Container) error { return nil } -// ShutdownTimeout returns the shutdown timeout based on the max stopTimeout of the containers, -// and is limited by daemon's ShutdownTimeout. +// ShutdownTimeout returns the timeout (in seconds) before containers are forcibly +// killed during shutdown. The default timeout can be configured both on the daemon +// and per container, and the longest timeout will be used. A grace-period of +// 5 seconds is added to the configured timeout. +// +// A negative (-1) timeout means "indefinitely", which means that containers +// are not forcibly killed, and the daemon shuts down after all containers exit. func (daemon *Daemon) ShutdownTimeout() int { - // By default we use daemon's ShutdownTimeout. shutdownTimeout := daemon.configStore.ShutdownTimeout + if shutdownTimeout < 0 { + return -1 + } + if daemon.containers == nil { + return shutdownTimeout + } graceTimeout := 5 - if daemon.containers != nil { - for _, c := range daemon.containers.List() { - if shutdownTimeout >= 0 { - stopTimeout := c.StopTimeout() - if stopTimeout < 0 { - shutdownTimeout = -1 - } else { - if stopTimeout+graceTimeout > shutdownTimeout { - shutdownTimeout = stopTimeout + graceTimeout - } - } - } + for _, c := range daemon.containers.List() { + stopTimeout := c.StopTimeout() + if stopTimeout < 0 { + return -1 + } + if stopTimeout+graceTimeout > shutdownTimeout { + shutdownTimeout = stopTimeout + graceTimeout } } return shutdownTimeout