Skip to content

Commit

Permalink
StartWithLogFile: Fix d.cmd race
Browse files Browse the repository at this point in the history
Use `exec.Command` created by this function instead of obtaining it from
daemon struct. This prevents a race condition where `daemon.Kill` is
called before the goroutine has the chance to call `cmd.Wait`.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 88992de)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
  • Loading branch information
vvoland committed Mar 22, 2023
1 parent 7f49ca2 commit c6bf307
Showing 1 changed file with 10 additions and 10 deletions.
20 changes: 10 additions & 10 deletions testutil/daemon/daemon.go
Expand Up @@ -392,34 +392,34 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
}

d.args = append(d.args, providedArgs...)
d.cmd = exec.Command(dockerdBinary, d.args...)
d.cmd.Env = append(os.Environ(), "DOCKER_SERVICE_PREFER_OFFLINE_IMAGE=1")
d.cmd.Env = append(d.cmd.Env, d.extraEnv...)
d.cmd.Stdout = out
d.cmd.Stderr = out
cmd := exec.Command(dockerdBinary, d.args...)
cmd.Env = append(os.Environ(), "DOCKER_SERVICE_PREFER_OFFLINE_IMAGE=1")
cmd.Env = append(cmd.Env, d.extraEnv...)
cmd.Stdout = out
cmd.Stderr = out
d.logFile = out
if d.rootlessUser != nil {
// sudo requires this for propagating signals
setsid(d.cmd)
setsid(cmd)
}

if err := d.cmd.Start(); err != nil {
if err := cmd.Start(); err != nil {
return errors.Wrapf(err, "[%s] could not start daemon container", d.id)
}

wait := make(chan error, 1)
d.cmd = cmd
d.Wait = wait

go func() {
ret := d.cmd.Wait()
ret := cmd.Wait()
d.log.Logf("[%s] exiting daemon", d.id)
// If we send before logging, we might accidentally log _after_ the test is done.
// As of Go 1.12, this incurs a panic instead of silently being dropped.
wait <- ret
close(wait)
}()

d.Wait = wait

clientConfig, err := d.getClientConfig()
if err != nil {
return err
Expand Down

0 comments on commit c6bf307

Please sign in to comment.