summaryrefslogtreecommitdiffhomepage
path: root/runsc/boot/controller.go
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2018-09-17 16:24:05 -0700
committerShentubot <shentubot@google.com>2018-09-17 16:25:24 -0700
commitbb88c187c5457df14fa78e5e6b6f48cbc90fb489 (patch)
treea92886651d7657480b7f696ebe7a5f774916a1cb /runsc/boot/controller.go
parentab6fa44588233fa48d1ae0bf7d9b0d9e984a6af0 (diff)
runsc: Enable waiting on exited processes.
This makes `runsc wait` behave more like waitpid()/wait4() in that: - Once a process has run to completion, you can wait on it and get its exit code. - Processes not waited on will consume memory (like a zombie process) PiperOrigin-RevId: 213358916 Change-Id: I5b5eca41ce71eea68e447380df8c38361a4d1558
Diffstat (limited to 'runsc/boot/controller.go')
-rw-r--r--runsc/boot/controller.go33
1 files changed, 8 insertions, 25 deletions
diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go
index 4d41dcd6c..dc9359092 100644
--- a/runsc/boot/controller.go
+++ b/runsc/boot/controller.go
@@ -242,32 +242,11 @@ type ExecArgs struct {
// returns the pid of the new process.
func (cm *containerManager) ExecuteAsync(args *ExecArgs, pid *int32) error {
log.Debugf("containerManager.ExecuteAsync: %+v", args)
-
- // Get the container Root Dirent from the Task, since we must run this
- // process with the same Root.
- cm.l.mu.Lock()
- tg, ok := cm.l.containerRootTGs[args.CID]
- cm.l.mu.Unlock()
- if !ok {
- return fmt.Errorf("cannot exec in container %q: no such container", args.CID)
- }
- tg.Leader().WithMuLocked(func(t *kernel.Task) {
- args.Root = t.FSContext().RootDirectory()
- })
- if args.Root != nil {
- defer args.Root.DecRef()
- }
-
- // Start the process.
- proc := control.Proc{Kernel: cm.l.k}
- newTG, err := control.ExecAsync(&proc, &args.ExecArgs)
+ tgid, err := cm.l.executeAsync(&args.ExecArgs, args.CID)
if err != nil {
- return fmt.Errorf("error executing: %+v: %v", args, err)
+ return err
}
-
- // Return the pid of the newly-created process.
- ts := cm.l.k.TaskSet()
- *pid = int32(ts.Root.IDOfThreadGroup(newTG))
+ *pid = int32(tgid)
return nil
}
@@ -409,12 +388,16 @@ 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, waitStatus)
+ return cm.l.waitPID(kernel.ThreadID(args.PID), args.CID, args.ClearStatus, waitStatus)
}
// SignalArgs are arguments to the Signal method.