summaryrefslogtreecommitdiffhomepage
path: root/runsc/cmd/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'runsc/cmd/exec.go')
-rw-r--r--runsc/cmd/exec.go62
1 files changed, 26 insertions, 36 deletions
diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go
index 52fd7ac4b..0eeaaadba 100644
--- a/runsc/cmd/exec.go
+++ b/runsc/cmd/exec.go
@@ -40,8 +40,6 @@ import (
"gvisor.googlesource.com/gvisor/runsc/specutils"
)
-const privateClearStatusFlag = "private-clear-status"
-
// Exec implements subcommands.Command for the "exec" command.
type Exec struct {
cwd string
@@ -51,7 +49,6 @@ type Exec struct {
extraKGIDs stringSlice
caps stringSlice
detach bool
- clearStatus bool
processPath string
pidFile string
internalPidFile string
@@ -103,10 +100,6 @@ func (ex *Exec) SetFlags(f *flag.FlagSet) {
f.StringVar(&ex.pidFile, "pid-file", "", "filename that the container pid will be written to")
f.StringVar(&ex.internalPidFile, "internal-pid-file", "", "filename that the container-internal pid will be written to")
f.StringVar(&ex.consoleSocket, "console-socket", "", "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal")
-
- // This flag clears the status of the exec'd process upon completion. It is
- // only used when we fork due to --detach being set on the parent.
- f.BoolVar(&ex.clearStatus, privateClearStatusFlag, true, "private flag, do not use")
}
// Execute implements subcommands.Command.Execute. It starts a process in an
@@ -150,13 +143,16 @@ 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 {
- return ex.execAndWait(waitStatus)
+ return ex.execChildAndWait(waitStatus)
}
+ return ex.exec(c, e, waitStatus)
+}
+func (ex *Exec) exec(c *container.Container, e *control.ExecArgs, waitStatus *syscall.WaitStatus) subcommands.ExitStatus {
// Start the new process and get it pid.
pid, err := c.Execute(e)
if err != nil {
- Fatalf("getting processes for container: %v", err)
+ return Errorf("executing processes for container: %v", err)
}
if e.StdioIsPty {
@@ -170,33 +166,37 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{})
if ex.internalPidFile != "" {
pidStr := []byte(strconv.Itoa(int(pid)))
if err := ioutil.WriteFile(ex.internalPidFile, pidStr, 0644); err != nil {
- Fatalf("writing internal pid file %q: %v", ex.internalPidFile, err)
+ return Errorf("writing internal pid file %q: %v", ex.internalPidFile, err)
}
}
- // Generate the pid file after the internal pid file is generated, so that users
- // can safely assume that the internal pid file is ready after `runsc exec -d`
- // returns.
+ // Generate the pid file after the internal pid file is generated, so that
+ // users can safely assume that the internal pid file is ready after
+ // `runsc exec -d` returns.
if ex.pidFile != "" {
if err := ioutil.WriteFile(ex.pidFile, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil {
- Fatalf("writing pid file: %v", err)
+ return Errorf("writing pid file: %v", err)
}
}
// Wait for the process to exit.
- ws, err := c.WaitPID(pid, ex.clearStatus)
+ ws, err := c.WaitPID(pid)
if err != nil {
- Fatalf("waiting on pid %d: %v", pid, err)
+ return Errorf("waiting on pid %d: %v", pid, err)
}
*waitStatus = ws
return subcommands.ExitSuccess
}
-func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStatus {
- binPath := specutils.ExePath
+func (ex *Exec) execChildAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStatus {
var args []string
+ for _, a := range os.Args[1:] {
+ if !strings.Contains(a, "detach") {
+ args = append(args, a)
+ }
+ }
- // The command needs to write a pid file so that execAndWait can tell
+ // The command needs to write a pid file so that execChildAndWait can tell
// when it has started. If no pid-file was provided, we should use a
// filename in a temp directory.
pidFile := ex.pidFile
@@ -210,19 +210,7 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
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") {
- // Replace with the "private-clear-status" flag, which tells
- // the new process it's a detached child and shouldn't
- // clear the exit status of the sentry process.
- args = append(args, fmt.Sprintf("--%s=false", privateClearStatusFlag))
- } else {
- args = append(args, a)
- }
- }
-
- cmd := exec.Command(binPath, args...)
+ cmd := exec.Command(specutils.ExePath, args...)
cmd.Args[0] = "runsc-exec"
// Exec stdio defaults to current process stdio.
@@ -233,8 +221,7 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
// If the console control socket file is provided, then create a new
// pty master/slave pair and set the TTY on the sandbox process.
if ex.consoleSocket != "" {
- // Create a new TTY pair and send the master on the provided
- // socket.
+ // Create a new TTY pair and send the master on the provided socket.
tty, err := console.NewWithSocket(ex.consoleSocket)
if err != nil {
Fatalf("setting up console with socket %q: %v", ex.consoleSocket, err)
@@ -256,7 +243,7 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
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)
+ log.Infof("Started child (PID: %d) to exec and wait: %s %s", cmd.Process.Pid, specutils.ExePath, 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
@@ -278,7 +265,10 @@ func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStat
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)
+ // Don't log fatal error here, otherwise it will override the error logged
+ // by the child process that has failed to start.
+ log.Warningf("Unexpected error waiting for PID file, err: %v", err)
+ return subcommands.ExitFailure
}
*waitStatus = 0