summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/boot')
-rw-r--r--runsc/boot/controller.go2
-rw-r--r--runsc/boot/loader.go10
-rw-r--r--runsc/boot/loader_test.go19
3 files changed, 28 insertions, 3 deletions
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index 4d4ef7256..60c42fc19 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -68,7 +68,7 @@ func newController(fd int, k *kernel.Kernel) (*controller, error) {
app := &application{
startChan: make(chan struct{}),
- startResultChan: make(chan error, 1),
+ startResultChan: make(chan error),
k: k,
}
srv.Register(app)
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go
index af577f571..34a25241f 100644
--- a/runsc/boot/loader.go
+++ b/runsc/boot/loader.go
@@ -287,7 +287,15 @@ func createPlatform(conf *Config) (platform.Platform, error) {
func (l *Loader) Run() error {
err := l.run()
l.ctrl.app.startResultChan <- err
- return err
+ if err != nil {
+ // Give the controller some time to send the error to the
+ // runtime. If we return too quickly here the process will exit
+ // and the control connection will be closed before the error
+ // is returned.
+ gtime.Sleep(2 * gtime.Second)
+ return err
+ }
+ return nil
}
func (l *Loader) run() error {
diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go
index 2fc16b241..c3d9887fa 100644
--- a/runsc/boot/loader_test.go
+++ b/runsc/boot/loader_test.go
@@ -16,6 +16,7 @@ package boot
import (
"os"
+ "sync"
"testing"
"time"
@@ -65,11 +66,27 @@ func TestRun(t *testing.T) {
}
defer s.Destroy()
+ // Start a goroutine to read the start chan result, otherwise Run will
+ // block forever.
+ var resultChanErr error
+ var wg sync.WaitGroup
+ wg.Add(1)
+ go func() {
+ resultChanErr = <-s.ctrl.app.startResultChan
+ wg.Done()
+ }()
+
// Run the application.
if err := s.Run(); err != nil {
t.Errorf("error running application: %v", err)
}
+ // We should have not gotten an error on the startResultChan.
+ wg.Wait()
+ if resultChanErr != nil {
+ t.Errorf("error on startResultChan: %v", resultChanErr)
+ }
+
// Wait for the application to exit. It should succeed.
if status := s.WaitExit(); status.Code != 0 || status.Signo != 0 {
t.Errorf("application exited with status %+v, want 0", status)
@@ -94,7 +111,7 @@ func TestStartSignal(t *testing.T) {
waitFinished := make(chan struct{})
go func() {
s.WaitForStartSignal()
- // Pretent that Run() executed and returned no error.
+ // Pretend that Run() executed and returned no error.
s.ctrl.app.startResultChan <- nil
waitFinished <- struct{}{}
}()