aboutsummaryrefslogtreecommitdiffhomepage
path: root/container
diff options
context:
space:
mode:
Diffstat (limited to 'container')
-rw-r--r--container/init.go20
-rw-r--r--container/init_test.go12
2 files changed, 25 insertions, 7 deletions
diff --git a/container/init.go b/container/init.go
index ff72c403..e38127fd 100644
--- a/container/init.go
+++ b/container/init.go
@@ -353,10 +353,14 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
wpid int
wstatus WaitStatus
}
+
+ // info is closed as the wait4 thread terminates
+ // when there are no longer any processes left to reap
info := make(chan winfo, 1)
- done := make(chan struct{})
k.new(func(k syscallDispatcher) {
+ k.lockOSThread()
+
var (
err error
wpid = -2
@@ -382,7 +386,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
k.printf(msg, "unexpected wait4 response: %v", err)
}
- close(done)
+ close(info)
})
// handle signals to dump withheld messages
@@ -411,7 +415,13 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
msg.BeforeExit()
k.exit(0)
- case w := <-info:
+ case w, ok := <-info:
+ if !ok {
+ msg.BeforeExit()
+ k.exit(r)
+ continue // unreachable
+ }
+
if w.wpid == cmd.Process.Pid {
// initial process exited, output is most likely available again
msg.Resume()
@@ -433,10 +443,6 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
go func() { time.Sleep(params.AdoptWaitDelay); close(timeout) }()
}
- case <-done:
- msg.BeforeExit()
- k.exit(r)
-
case <-timeout:
k.printf(msg, "timeout exceeded waiting for lingering processes")
msg.BeforeExit()
diff --git a/container/init_test.go b/container/init_test.go
index 49739726..c3f21979 100644
--- a/container/init_test.go
+++ b/container/init_test.go
@@ -2081,6 +2081,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
// magicWait4Signal as args[4] causes this to block until simulated signal is delivered
call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil, magicWait4Signal}, 0xbad, nil),
// this terminates the goroutine at the call, preventing it from leaking while preserving behaviour
@@ -2174,6 +2176,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
// this terminates the goroutine at the call, preventing it from leaking while preserving behaviour
call("wait4", stub.ExpectArgs{-1, nil, 0, nil, stub.PanicExit}, 0, syscall.ECHILD),
}}},
@@ -2266,6 +2270,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil),
// this terminates the goroutine at the call, preventing it from leaking while preserving behaviour
call("wait4", stub.ExpectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD),
@@ -2358,6 +2364,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil),
@@ -2494,6 +2502,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil),
@@ -2634,6 +2644,8 @@ func TestInitEntrypoint(t *testing.T) {
/* wait4 */
Tracks: []stub.Expect{{Calls: []stub.Call{
+ call("lockOSThread", stub.ExpectArgs{}, nil, nil),
+
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR),
call("wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil),