diff --git a/daemon/container.go b/daemon/container.go index e0da3c144a..3cb7af99e3 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -1081,22 +1081,14 @@ func (container *Container) startLoggingToDisk() error { func (container *Container) waitForStart() error { container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy) - var ( - cErr = utils.Go(container.monitor.Start) - waitStart = make(chan struct{}) - ) - - go func() { - container.State.WaitRunning(-1 * time.Second) - close(waitStart) - }() - - // Start should not return until the process is actually running + // block until we either receive an error from the initial start of the container's + // process or until the process is running in the container select { - case <-waitStart: - case err := <-cErr: + case <-container.monitor.startSignal: + case err := <-utils.Go(container.monitor.Start): return err } + return nil } diff --git a/daemon/monitor.go b/daemon/monitor.go index 231b883a3a..801fe0e043 100644 --- a/daemon/monitor.go +++ b/daemon/monitor.go @@ -35,6 +35,10 @@ type containerMonitor struct { // either because docker or the user asked for the container to be stopped shouldStop bool + // startSignal signals with the initial process has launched after calling Start + // on the monitor + startSignal chan struct{} + // stopChan is used to signal to the monitor whenever there is a wait for the // next restart so that the timeIncrement is not honored and the user is not // left waiting for nothing to happen during this time @@ -48,12 +52,15 @@ type containerMonitor struct { lastStartTime time.Time } +// newContainerMonitor returns an initialized containerMonitor for the provided container +// honoring the provided restart policy func newContainerMonitor(container *Container, policy runconfig.RestartPolicy) *containerMonitor { return &containerMonitor{ container: container, restartPolicy: policy, timeIncrement: defaultTimeIncrement, stopChan: make(chan struct{}, 1), + startSignal: make(chan struct{}, 1), } } @@ -119,6 +126,14 @@ func (m *containerMonitor) Start() error { m.lastStartTime = time.Now() if exitStatus, err = m.container.daemon.Run(m.container, pipes, m.callback); err != nil { + // if we receive an internal error from the initial start of a container then lets + // return it instead of entering the restart loop + if m.container.RestartCount == 1 { + m.resetContainer() + + return err + } + utils.Errorf("Error running container: %s", err) } @@ -230,6 +245,9 @@ func (m *containerMonitor) callback(command *execdriver.Command) { m.container.State.SetRunning(command.Pid()) + // signal that the process has started + close(m.startSignal) + if err := m.container.ToDisk(); err != nil { utils.Debugf("%s", err) }