summaryrefslogtreecommitdiffhomepage
path: root/runsc/sandbox/sandbox.go
diff options
context:
space:
mode:
authorLantao Liu <lantaol@google.com>2018-09-13 16:36:53 -0700
committerShentubot <shentubot@google.com>2018-09-13 16:38:03 -0700
commitbde2a91433cfbac426577a691bf13817115b53be (patch)
tree1403a6e5ffca3345da142bf68535763b6f34e5a9 /runsc/sandbox/sandbox.go
parentadf8f339703922211886d3e5588160f65bc131b3 (diff)
runsc: Support container signal/wait.
This CL: 1) Fix `runsc wait`, it now also works after the container exits; 2) Generate correct container state in Load; 2) Make sure `Destory` cleanup everything before successfully return. PiperOrigin-RevId: 212900107 Change-Id: Ie129cbb9d74f8151a18364f1fc0b2603eac4109a
Diffstat (limited to 'runsc/sandbox/sandbox.go')
-rw-r--r--runsc/sandbox/sandbox.go38
1 files changed, 20 insertions, 18 deletions
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index 8e90dcc70..156b2f769 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -16,6 +16,7 @@
package sandbox
import (
+ "context"
"fmt"
"os"
"os/exec"
@@ -23,8 +24,8 @@ import (
"syscall"
"time"
+ "github.com/cenkalti/backoff"
specs "github.com/opencontainers/runtime-spec/specs-go"
- "golang.org/x/sys/unix"
"gvisor.googlesource.com/gvisor/pkg/control/client"
"gvisor.googlesource.com/gvisor/pkg/control/server"
"gvisor.googlesource.com/gvisor/pkg/log"
@@ -543,20 +544,18 @@ func (s *Sandbox) IsRootContainer(cid string) bool {
return s.ID == cid
}
-// Stop stops the container in the sandbox.
-func (s *Sandbox) Stop(cid string) error {
- // TODO: This should stop the container with the given ID
- // in the sandbox.
- return nil
-}
-
// Destroy frees all resources associated with the sandbox.
+// Destroy returns error if any step fails, and the function can be safely retried.
func (s *Sandbox) Destroy() error {
log.Debugf("Destroy sandbox %q", s.ID)
if s.Pid != 0 {
- // TODO: Too harsh?
log.Debugf("Killing sandbox %q", s.ID)
- signalProcess(s.Pid, unix.SIGKILL)
+ if err := syscall.Kill(s.Pid, syscall.SIGKILL); err != nil && err != syscall.ESRCH {
+ return fmt.Errorf("error killing sandbox %q PID %q: %v", s.ID, s.Pid, err)
+ }
+ if err := s.waitForStopped(); err != nil {
+ return fmt.Errorf("error waiting sandbox %q stop: %v", s.ID, err)
+ }
}
if s.Chroot != "" {
@@ -641,7 +640,7 @@ func (s *Sandbox) Resume(cid string) error {
func (s *Sandbox) IsRunning() bool {
if s.Pid != 0 {
// Send a signal 0 to the sandbox process.
- if err := signalProcess(s.Pid, 0); err == nil {
+ if err := syscall.Kill(s.Pid, 0); err == nil {
// Succeeded, process is running.
return true
}
@@ -665,14 +664,17 @@ func (s *Sandbox) Stacks() (string, error) {
return stacks, nil
}
-// signalProcess sends a signal to the host process (i.e. a sandbox or gofer
-// process). Sandbox.Signal should be used to send a signal to a process
-// running inside the sandbox.
-func signalProcess(pid int, sig syscall.Signal) error {
- if err := syscall.Kill(pid, sig); err != nil {
- return fmt.Errorf("error sending signal %d to pid %d: %v", sig, pid, err)
+func (s *Sandbox) waitForStopped() error {
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ b := backoff.WithContext(backoff.NewConstantBackOff(100*time.Millisecond), ctx)
+ op := func() error {
+ if s.IsRunning() {
+ return fmt.Errorf("sandbox is still running")
+ }
+ return nil
}
- return nil
+ return backoff.Retry(op, b)
}
// deviceFileForPlatform opens the device file for the given platform. If the