summaryrefslogtreecommitdiffhomepage
path: root/runsc/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/cmd')
-rw-r--r--runsc/cmd/exec.go87
1 files changed, 45 insertions, 42 deletions
diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go
index 576031b5b..052e00316 100644
--- a/runsc/cmd/exec.go
+++ b/runsc/cmd/exec.go
@@ -123,48 +123,7 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
// write the child's PID to the pid file. So when the container returns, the
// child process will also return and signal containerd.
if ex.detach {
- binPath, err := specutils.BinPath()
- if err != nil {
- Fatalf("error getting bin path: %v", err)
- }
- var args []string
- for _, a := range os.Args[1:] {
- if !strings.Contains(a, "detach") {
- args = append(args, a)
- }
- }
- cmd := exec.Command(binPath, args...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Start(); err != nil {
- Fatalf("failure to start child exec process, err: %v", err)
- }
-
- log.Infof("Started child (PID: %d) to exec and wait: %s %s", cmd.Process.Pid, binPath, args)
-
- // Wait for PID file to ensure that child process has started. Otherwise,
- // '--process' file is deleted as soon as this process returns and the child
- // may fail to read it.
- sleepTime := 10 * time.Millisecond
- for start := time.Now(); time.Now().Sub(start) < 10*time.Second; {
- _, err := os.Stat(ex.pidFile)
- if err == nil {
- break
- }
- if pe, ok := err.(*os.PathError); !ok || pe.Err != syscall.ENOENT {
- Fatalf("unexpected error waiting for PID file, err: %v", err)
- }
-
- log.Infof("Waiting for PID file to be created...")
- time.Sleep(sleepTime)
- sleepTime *= sleepTime * 2
- if sleepTime > 1*time.Second {
- sleepTime = 1 * time.Second
- }
- }
- *waitStatus = 0
- return subcommands.ExitSuccess
+ return ex.execAndWait(waitStatus)
}
if ex.pidFile != "" {
@@ -191,6 +150,50 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
return subcommands.ExitSuccess
}
+func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStatus {
+ binPath, err := specutils.BinPath()
+ if err != nil {
+ Fatalf("error getting bin path: %v", err)
+ }
+ var args []string
+ for _, a := range os.Args[1:] {
+ if !strings.Contains(a, "detach") {
+ args = append(args, a)
+ }
+ }
+ cmd := exec.Command(binPath, args...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Start(); err != nil {
+ Fatalf("failure to start child exec process, err: %v", err)
+ }
+
+ log.Infof("Started child (PID: %d) to exec and wait: %s %s", cmd.Process.Pid, binPath, args)
+
+ // Wait for PID file to ensure that child process has started. Otherwise,
+ // '--process' file is deleted as soon as this process returns and the child
+ // may fail to read it.
+ ready := func() (bool, error) {
+ _, err := os.Stat(ex.pidFile)
+ if err == nil {
+ // File appeared, we're done!
+ return true, nil
+ }
+ if pe, ok := err.(*os.PathError); !ok || pe.Err != syscall.ENOENT {
+ return false, err
+ }
+ // No file yet, continue to wait...
+ return false, nil
+ }
+ if err := specutils.WaitForReady(cmd.Process.Pid, 10*time.Second, ready); err != nil {
+ Fatalf("unexpected error waiting for PID file, err: %v", err)
+ }
+
+ *waitStatus = 0
+ return subcommands.ExitSuccess
+}
+
// parseArgs parses exec information from the command line or a JSON file
// depending on whether the --process flag was used. Returns an ExecArgs and
// the ID of the sandbox to be used.