mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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
This commit is contained in:
committed by
Shentubot
parent
18e6e63503
commit
d28f71adcf
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+10
-26
@@ -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
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user