container: load initial process started before syscall
All checks were successful
Test / Create distribution (push) Successful in 27s
Test / Sandbox (push) Successful in 2m50s
Test / Sandbox (race detector) (push) Successful in 5m3s
Test / Hpkg (push) Successful in 5m21s
Test / Hakurei (push) Successful in 5m47s
Test / Hakurei (race detector) (push) Successful in 7m7s
Test / Flake checks (push) Successful in 1m39s

This avoids a race between returning from syscall and checking the state.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-12-09 08:12:22 +09:00
parent c538df7daa
commit a3fd05765e
Signed by: cat
SSH Key Fingerprint: SHA256:wr6yH7sDDbUFi81k/GsIGwpM3O2QrwqYlLF26CcJa4w

View File

@ -380,6 +380,9 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
err error err error
wpid = -2 wpid = -2
wstatus WaitStatus wstatus WaitStatus
// whether initial process has started
started bool
) )
// keep going until no child process is left // keep going until no child process is left
@ -406,6 +409,10 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
} }
} }
if !started {
started = initialProcessStarted.Load()
}
err = EINTR err = EINTR
for errors.Is(err, EINTR) { for errors.Is(err, EINTR) {
wpid, err = k.wait4(-1, &wstatus, 0, nil) wpid, err = k.wait4(-1, &wstatus, 0, nil)
@ -414,7 +421,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
if !errors.Is(err, ECHILD) { if !errors.Is(err, ECHILD) {
k.printf(msg, "unexpected wait4 response: %v", err) k.printf(msg, "unexpected wait4 response: %v", err)
} else if !initialProcessStarted.Load() { } else if !started {
// initial process has not yet been reached and all daemons // initial process has not yet been reached and all daemons
// terminated or none were started in the first place // terminated or none were started in the first place
time.Sleep(500 * time.Microsecond) time.Sleep(500 * time.Microsecond)