瀏覽代碼

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 <csnider@mirantis.com>
Cory Snider 1 年之前
父節點
當前提交
dd20bf4862
共有 1 個文件被更改,包括 3 次插入2 次删除
  1. 3 2
      libcontainerd/supervisor/remote_daemon.go

+ 3 - 2
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")