From c12bbf549b4d52a5f5b4e6425a882f770cb903c3 Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Thu, 1 Feb 2024 15:37:09 -0500 Subject: [PATCH] libcontainerd/supervisor: fix data race The monitorDaemon() goroutine calls startContainerd() then blocks on <-daemonWaitCh to wait for it to exit. The startContainerd() function would (re)initialize the daemonWaitCh so a restarted containerd could be waited on. This implementation was race-free because startContainerd() would synchronously initialize the daemonWaitCh before returning. When the call to start the managed containerd process was moved into the waiter goroutine, the code to initialize the daemonWaitCh struct field was also moved into the goroutine. This introduced a race condition. Move the daemonWaitCh initialization to guarantee that it happens before the startContainerd() call returns. Signed-off-by: Cory Snider (cherry picked from commit dd20bf4862319485a9a9c66ac8907993a3142e3c) Signed-off-by: Sebastiaan van Stijn --- libcontainerd/supervisor/remote_daemon.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libcontainerd/supervisor/remote_daemon.go b/libcontainerd/supervisor/remote_daemon.go index 7138dc00a8..10a8a4fda7 100644 --- a/libcontainerd/supervisor/remote_daemon.go +++ b/libcontainerd/supervisor/remote_daemon.go @@ -190,12 +190,13 @@ func (r *remote) startContainerd() error { runtime.LockOSThread() defer runtime.UnlockOSThread() err := cmd.Start() - startedCh <- err if err != nil { + startedCh <- err return } - r.daemonWaitCh = make(chan struct{}) + startedCh <- nil + // Reap our child when needed if err := cmd.Wait(); err != nil { r.logger.WithError(err).Errorf("containerd did not exit successfully")