runsc: Fix "exec" command when called without --pid-file.

When "exec" command is called without the "--detach" flag, we spawn a second
"exec" command and wait for that one to start. We use the pid file passed in
--pid-file to detect when this second command has started running.

However if "exec" is called with no --pid-file flag, this system breaks down,
as we don't have a pid file to wait for.

This CL ensures that the second instance of the "exec" command always writes a
pid-file, so the wait is successful.

PiperOrigin-RevId: 206002403
Change-Id: If9f2be31eb6e831734b1b833f25054ec71ab94a6
This commit is contained in:
Nicolas Lacasse
2018-07-25 09:11:45 -07:00
committed by Shentubot
parent 32aa0f5465
commit 1129b35c92
+19 -1
View File
@@ -20,6 +20,7 @@ import (
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"syscall"
@@ -156,11 +157,28 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
Fatalf("error getting bin path: %v", err)
}
var args []string
// The command needs to write a pid file so that execAndWait can tell
// when it has started. If no pid-file was provided, we should use a
// filename in a temp directory.
pidFile := ex.pidFile
if pidFile == "" {
tmpDir, err := ioutil.TempDir("", "exec-pid-")
if err != nil {
Fatalf("error creating TempDir: %v", err)
}
defer os.RemoveAll(tmpDir)
pidFile = filepath.Join(tmpDir, "pid")
args = append(args, "--pid-file="+pidFile)
}
// Add the rest of the args, excluding the "detach" flag.
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
@@ -175,7 +193,7 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
// '--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)
_, err := os.Stat(pidFile)
if err == nil {
// File appeared, we're done!
return true, nil