diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2018-11-15 15:34:38 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-15 15:35:41 -0800 |
commit | adf8138e069a99aa7f3fe190a9a7c17a4e88b99a (patch) | |
tree | 349dd842162121546b957702aa8abebdfc82cc7b /runsc/sandbox/sandbox.go | |
parent | f7aa9371247a3e7d8c490ac0fd4c4f3ff6de2017 (diff) |
Allow sandbox.Wait to be called after the sandbox has exited.
sandbox.Wait is racey, as the sandbox may have exited before it is called, or
even during.
We already had code to handle the case that the sandbox exits during the Wait
call, but we were not properly handling the case where the sandbox has exited
before the call.
The best we can do in such cases is return the sandbox exit code as the
application exit code.
PiperOrigin-RevId: 221702517
Change-Id: I290d0333cc094c7c1c3b4ce0f17f61a3e908d787
Diffstat (limited to 'runsc/sandbox/sandbox.go')
-rw-r--r-- | runsc/sandbox/sandbox.go | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 084d79d06..3f00eba94 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -612,17 +612,23 @@ func (s *Sandbox) waitForCreated(timeout time.Duration) error { func (s *Sandbox) Wait(cid string) (syscall.WaitStatus, error) { log.Debugf("Waiting for container %q in sandbox %q", cid, s.ID) var ws syscall.WaitStatus - conn, err := s.sandboxConnect() - if err != nil { - return ws, err - } - defer conn.Close() - // First try the Wait RPC to the sandbox. - if err := conn.Call(boot.ContainerWait, &cid, &ws); err == nil { - return ws, nil + if conn, err := s.sandboxConnect(); err != nil { + // The sandbox may have exited while before we had a chance to + // wait on it. + log.Warningf("Wait on container %q failed: %v. Will try waiting on the sandbox process instead.", cid, err) + } else { + defer conn.Close() + // Try the Wait RPC to the sandbox. + err = conn.Call(boot.ContainerWait, &cid, &ws) + if err == nil { + // It worked! + return ws, nil + } + // The sandbox may have exited after we connected, but before + // or during the Wait RPC. + log.Warningf("Wait RPC to container %q failed: %v. Will try waiting on the sandbox process instead.", cid, err) } - log.Warningf("Wait RPC to container %q failed: %v. Will try waiting on the sandbox process instead.", cid, err) // The sandbox may have already exited, or exited while handling the // Wait RPC. The best we can do is ask Linux what the sandbox exit |