summaryrefslogtreecommitdiffhomepage
path: root/runsc/specutils/specutils.go
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-05-03 21:08:38 -0700
committerShentubot <shentubot@google.com>2018-05-03 21:09:31 -0700
commitc186ebb62a6005288d83feed0e43cca9f0577383 (patch)
treec36a976d6aaec2d09435f96fb0cbd4e0168d9bba /runsc/specutils/specutils.go
parent58235b1840db01aa2ede311efa782eac60767722 (diff)
Return error when child exits early
PiperOrigin-RevId: 195365050 Change-Id: I8754dc7a3fc2975d422cae453762a455478a8e6a
Diffstat (limited to 'runsc/specutils/specutils.go')
-rw-r--r--runsc/specutils/specutils.go32
1 files changed, 32 insertions, 0 deletions
diff --git a/runsc/specutils/specutils.go b/runsc/specutils/specutils.go
index bed0f75eb..04ecb6ae3 100644
--- a/runsc/specutils/specutils.go
+++ b/runsc/specutils/specutils.go
@@ -23,6 +23,8 @@ import (
"os"
"path/filepath"
"strings"
+ "syscall"
+ "time"
specs "github.com/opencontainers/runtime-spec/specs-go"
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
@@ -181,3 +183,33 @@ func BinPath() (string, error) {
}
return binPath, nil
}
+
+// WaitForReady waits for a process to become ready. The process is ready when
+// the 'ready' function returns true. It continues to wait if 'ready' returns
+// false. It returns error on timeout, if the process stops or if 'ready' fails.
+func WaitForReady(pid int, timeout time.Duration, ready func() (bool, error)) error {
+ backoff := 1 * time.Millisecond
+ for start := time.Now(); time.Now().Sub(start) < timeout; {
+ if ok, err := ready(); err != nil {
+ return err
+ } else if ok {
+ return nil
+ }
+
+ // Check if the process is still running.
+ var ws syscall.WaitStatus
+ var ru syscall.Rusage
+ child, err := syscall.Wait4(pid, &ws, syscall.WNOHANG, &ru)
+ if err != nil || child == pid {
+ return fmt.Errorf("process (%d) is not running, err: %v", pid, err)
+ }
+
+ // Process continues to run, backoff and retry.
+ time.Sleep(backoff)
+ backoff *= 2
+ if backoff > 1*time.Second {
+ backoff = 1 * time.Second
+ }
+ }
+ return fmt.Errorf("timed out waiting for process (%d)", pid)
+}