Sfoglia il codice sorgente

Rebased changes to return on first start's error

Signed-off-by: Michael Crosby <michael@docker.com>
Michael Crosby 11 anni fa
parent
commit
2ec1b697c1
2 ha cambiato i file con 23 aggiunte e 13 eliminazioni
  1. 5 13
      daemon/container.go
  2. 18 0
      daemon/monitor.go

+ 5 - 13
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
 }
 

+ 18 - 0
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)
 	}