diff options
author | Fabricio Voznika <fvoznika@google.com> | 2019-06-03 18:14:52 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-06-03 18:16:09 -0700 |
commit | d28f71adcf60793a81490f3b4d25da36901e769e (patch) | |
tree | caef4a63a63fb4779be35ffc422825055b641826 | |
parent | 18e6e63503251cdc0b9432765b6eaa9ffa002824 (diff) |
Remove 'clearStatus' option from container.Wait*PID()
clearStatus was added to allow detached execution to wait
on the exec'd process and retrieve its exit status. However,
it's not currently used. Both docker and gvisor-containerd-shim
wait on the "shim" process and retrieve the exit status from
there. We could change gvisor-containerd-shim to use waits, but
it will end up also consuming a process for the wait, which is
similar to having the shim process.
Closes #234
PiperOrigin-RevId: 251349490
-rw-r--r-- | runsc/boot/controller.go | 6 | ||||
-rw-r--r-- | runsc/boot/loader.go | 13 | ||||
-rw-r--r-- | runsc/cmd/exec.go | 36 | ||||
-rw-r--r-- | runsc/cmd/wait.go | 4 | ||||
-rw-r--r-- | runsc/container/console_test.go | 2 | ||||
-rw-r--r-- | runsc/container/container.go | 8 | ||||
-rw-r--r-- | runsc/container/container_test.go | 2 | ||||
-rw-r--r-- | runsc/container/multi_container_test.go | 8 | ||||
-rw-r--r-- | runsc/sandbox/sandbox.go | 7 |
9 files changed, 31 insertions, 55 deletions
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index 72ab9ef86..419cb79d3 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -420,16 +420,12 @@ type WaitPIDArgs struct { // CID is the container ID. CID string - - // ClearStatus determines whether the exit status of the process should - // be cleared when WaitPID returns. - ClearStatus bool } // WaitPID waits for the process with PID 'pid' in the sandbox. func (cm *containerManager) WaitPID(args *WaitPIDArgs, waitStatus *uint32) error { log.Debugf("containerManager.Wait") - return cm.l.waitPID(kernel.ThreadID(args.PID), args.CID, args.ClearStatus, waitStatus) + return cm.l.waitPID(kernel.ThreadID(args.PID), args.CID, waitStatus) } // SignalDeliveryMode enumerates different signal delivery modes. diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index b29cb334f..52dccc994 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -724,7 +724,7 @@ func (l *Loader) waitContainer(cid string, waitStatus *uint32) error { return nil } -func (l *Loader) waitPID(tgid kernel.ThreadID, cid string, clearStatus bool, waitStatus *uint32) error { +func (l *Loader) waitPID(tgid kernel.ThreadID, cid string, waitStatus *uint32) error { if tgid <= 0 { return fmt.Errorf("PID (%d) must be positive", tgid) } @@ -736,13 +736,10 @@ func (l *Loader) waitPID(tgid kernel.ThreadID, cid string, clearStatus bool, wai ws := l.wait(execTG) *waitStatus = ws - // Remove tg from the cache if caller requested it. - if clearStatus { - l.mu.Lock() - delete(l.processes, eid) - log.Debugf("updated processes (removal): %v", l.processes) - l.mu.Unlock() - } + l.mu.Lock() + delete(l.processes, eid) + log.Debugf("updated processes (removal): %v", l.processes) + l.mu.Unlock() return nil } diff --git a/runsc/cmd/exec.go b/runsc/cmd/exec.go index 52fd7ac4b..8cd070e61 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 @@ -156,7 +149,7 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Start the new process and get it pid. pid, err := c.Execute(e) if err != nil { - Fatalf("getting processes for container: %v", err) + Fatalf("executing processes for container: %v", err) } if e.StdioIsPty { @@ -184,7 +177,7 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } // 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) } @@ -193,8 +186,12 @@ func (ex *Exec) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) } func (ex *Exec) execAndWait(waitStatus *syscall.WaitStatus) subcommands.ExitStatus { - binPath := specutils.ExePath 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 // when it has started. If no pid-file was provided, we should use a @@ -210,19 +207,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 +218,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 +240,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 diff --git a/runsc/cmd/wait.go b/runsc/cmd/wait.go index a55a682f3..58fd01974 100644 --- a/runsc/cmd/wait.go +++ b/runsc/cmd/wait.go @@ -88,14 +88,14 @@ func (wt *Wait) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) waitStatus = ws // Wait on a PID in the root PID namespace. case wt.rootPID != unsetPID: - ws, err := c.WaitRootPID(int32(wt.rootPID), true /* clearStatus */) + ws, err := c.WaitRootPID(int32(wt.rootPID)) if err != nil { Fatalf("waiting on PID in root PID namespace %d in container %q: %v", wt.rootPID, c.ID, err) } waitStatus = ws // Wait on a PID in the container's PID namespace. case wt.pid != unsetPID: - ws, err := c.WaitPID(int32(wt.pid), true /* clearStatus */) + ws, err := c.WaitPID(int32(wt.pid)) if err != nil { Fatalf("waiting on PID %d in container %q: %v", wt.pid, c.ID, err) } diff --git a/runsc/container/console_test.go b/runsc/container/console_test.go index b8af27c15..d016533e6 100644 --- a/runsc/container/console_test.go +++ b/runsc/container/console_test.go @@ -258,7 +258,7 @@ func TestJobControlSignalExec(t *testing.T) { } // Make sure the process indicates it was killed by a SIGKILL. - ws, err := c.WaitPID(pid, true) + ws, err := c.WaitPID(pid) if err != nil { t.Errorf("waiting on container failed: %v", err) } diff --git a/runsc/container/container.go b/runsc/container/container.go index 513085836..04b611b56 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -530,22 +530,22 @@ func (c *Container) Wait() (syscall.WaitStatus, error) { // WaitRootPID waits for process 'pid' in the sandbox's PID namespace and // returns its WaitStatus. -func (c *Container) WaitRootPID(pid int32, clearStatus bool) (syscall.WaitStatus, error) { +func (c *Container) WaitRootPID(pid int32) (syscall.WaitStatus, error) { log.Debugf("Wait on PID %d in sandbox %q", pid, c.Sandbox.ID) if !c.isSandboxRunning() { return 0, fmt.Errorf("sandbox is not running") } - return c.Sandbox.WaitPID(c.Sandbox.ID, pid, clearStatus) + return c.Sandbox.WaitPID(c.Sandbox.ID, pid) } // WaitPID waits for process 'pid' in the container's PID namespace and returns // its WaitStatus. -func (c *Container) WaitPID(pid int32, clearStatus bool) (syscall.WaitStatus, error) { +func (c *Container) WaitPID(pid int32) (syscall.WaitStatus, error) { log.Debugf("Wait on PID %d in container %q", pid, c.ID) if !c.isSandboxRunning() { return 0, fmt.Errorf("sandbox is not running") } - return c.Sandbox.WaitPID(c.ID, pid, clearStatus) + return c.Sandbox.WaitPID(c.ID, pid) } // SignalContainer sends the signal to the container. If all is true and signal diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index dcd9910a0..72c5ecbb0 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -1841,7 +1841,7 @@ func (cont *Container) executeSync(args *control.ExecArgs) (syscall.WaitStatus, if err != nil { return 0, fmt.Errorf("error executing: %v", err) } - ws, err := cont.WaitPID(pid, true /* clearStatus */) + ws, err := cont.WaitPID(pid) if err != nil { return 0, fmt.Errorf("error waiting: %v", err) } diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index 39c4dc03d..4ea3c74ac 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -175,12 +175,12 @@ func TestMultiContainerWait(t *testing.T) { go func(c *Container) { defer wg.Done() const pid = 2 - if ws, err := c.WaitPID(pid, true /* clearStatus */); err != nil { + if ws, err := c.WaitPID(pid); err != nil { t.Errorf("failed to wait for PID %d: %v", pid, err) } else if es := ws.ExitStatus(); es != 0 { t.Errorf("PID %d exited with non-zero status %d", pid, es) } - if _, err := c.WaitPID(pid, true /* clearStatus */); err == nil { + if _, err := c.WaitPID(pid); err == nil { t.Errorf("wait for stopped PID %d should fail", pid) } }(containers[1]) @@ -263,12 +263,12 @@ func TestExecWait(t *testing.T) { } // Get the exit status from the exec'd process. - if ws, err := containers[0].WaitPID(pid, true /* clearStatus */); err != nil { + if ws, err := containers[0].WaitPID(pid); err != nil { t.Fatalf("failed to wait for process %+v with pid %d: %v", args, pid, err) } else if es := ws.ExitStatus(); es != 0 { t.Fatalf("process %+v exited with non-zero status %d", args, es) } - if _, err := containers[0].WaitPID(pid, true /* clearStatus */); err == nil { + if _, err := containers[0].WaitPID(pid); err == nil { t.Fatalf("wait for stopped process %+v should fail", args) } } diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 47a66afb2..032190636 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -649,7 +649,7 @@ func (s *Sandbox) Wait(cid string) (syscall.WaitStatus, error) { // WaitPID waits for process 'pid' in the container's sandbox and returns its // WaitStatus. -func (s *Sandbox) WaitPID(cid string, pid int32, clearStatus bool) (syscall.WaitStatus, error) { +func (s *Sandbox) WaitPID(cid string, pid int32) (syscall.WaitStatus, error) { log.Debugf("Waiting for PID %d in sandbox %q", pid, s.ID) var ws syscall.WaitStatus conn, err := s.sandboxConnect() @@ -659,9 +659,8 @@ func (s *Sandbox) WaitPID(cid string, pid int32, clearStatus bool) (syscall.Wait defer conn.Close() args := &boot.WaitPIDArgs{ - PID: pid, - CID: cid, - ClearStatus: clearStatus, + PID: pid, + CID: cid, } if err := conn.Call(boot.ContainerWaitPID, args, &ws); err != nil { return ws, fmt.Errorf("waiting on PID %d in sandbox %q: %v", pid, s.ID, err) |