diff options
author | Justine Olshan <justineolshan@google.com> | 2018-06-15 16:08:20 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-06-15 16:09:09 -0700 |
commit | 0786707cd94b8feffaeb083077eccaf10873e682 (patch) | |
tree | 9dba432e5b695936e5f9907a92dae12bd5dc666a /runsc/container | |
parent | bd2d1aaa16474202b1a2c1edbf62e6782fa2dc36 (diff) |
Added code for a pause command for a container process.
Like runc, the pause command will pause the processes of the given container.
It will set that container's status to "paused."
A resume command will be be added to unpause and continue running the process.
PiperOrigin-RevId: 200789624
Change-Id: I72a5d7813d90ecfc4d01cc252d6018855016b1ea
Diffstat (limited to 'runsc/container')
-rw-r--r-- | runsc/container/container.go | 19 | ||||
-rw-r--r-- | runsc/container/container_test.go | 34 | ||||
-rw-r--r-- | runsc/container/status.go | 18 |
3 files changed, 64 insertions, 7 deletions
diff --git a/runsc/container/container.go b/runsc/container/container.go index 40c31ca7f..dc7fccdee 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -316,7 +316,7 @@ func (c *Container) Event() (*boot.Event, error) { // Pid returns the Pid of the sandbox the container is running in, or -1 if the // container is not running. func (c *Container) Pid() int { - if c.Status != Running && c.Status != Created { + if c.Status != Running && c.Status != Created && c.Status != Paused { return -1 } return c.Sandbox.Pid @@ -349,6 +349,23 @@ func (c *Container) Checkpoint(f *os.File) error { return c.Sandbox.Checkpoint(c.ID, f) } +// Pause suspends the container and its kernel. +// The call only succeeds if the container's status is created or running. +func (c *Container) Pause() error { + log.Debugf("Pausing container %q", c.ID) + switch c.Status { + case Created, Running: + if err := c.Sandbox.Pause(c.ID); err != nil { + return fmt.Errorf("error pausing container: %v", err) + } + c.Status = Paused + return c.save() + default: + log.Warningf("container %q not created or running, not pausing", c.ID) + return nil + } +} + // State returns the metadata of the container. func (c *Container) State() specs.State { return specs.State{ diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index b6d19bf33..5659abab3 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -459,6 +459,40 @@ func TestCheckpoint(t *testing.T) { } } +// TestPause tests that calling pause successfully pauses the container. +// It checks that no errors are returned and that the state of the container +// is in fact 'Paused.' +func TestPause(t *testing.T) { + spec := testutil.NewSpecWithArgs("sleep", "100") + + rootDir, bundleDir, conf, err := testutil.SetupContainer(spec) + if err != nil { + t.Fatalf("error setting up container: %v", err) + } + defer os.RemoveAll(rootDir) + defer os.RemoveAll(bundleDir) + + // Create and start the container. + cont, err := container.Create(testutil.UniqueContainerID(), spec, conf, bundleDir, "", "") + if err != nil { + t.Fatalf("error creating container: %v", err) + } + defer cont.Destroy() + if err := cont.Start(conf); err != nil { + t.Fatalf("error starting container: %v", err) + } + + // Pause the running container. + if err := cont.Pause(); err != nil { + t.Errorf("error pausing container: %v", err) + } + + // Confirm the status of the container is paused. + if got, want := cont.Status, container.Paused; got != want { + t.Errorf("container status got %v, want %v", got, want) + } +} + // TestCapabilities verifies that: // - Running exec as non-root UID and GID will result in an error (because the // executable file can't be read). diff --git a/runsc/container/status.go b/runsc/container/status.go index 8da1b4e89..bf177e78a 100644 --- a/runsc/container/status.go +++ b/runsc/container/status.go @@ -19,13 +19,17 @@ package container type Status int const ( - // Creating indicates "the container is being created". - Creating Status = iota - // Created indicates "the runtime has finished the create operation and // the container process has neither exited nor executed the // user-specified program". - Created + Created Status = iota + + // Creating indicates "the container is being created". + Creating + + // Paused indicates that the process within the container has been + // suspended. + Paused // Running indicates "the container process has executed the // user-specified program but has not exited". @@ -39,10 +43,12 @@ const ( // CLI spec and should not be changed. func (s Status) String() string { switch s { - case Creating: - return "creating" case Created: return "created" + case Creating: + return "creating" + case Paused: + return "paused" case Running: return "running" case Stopped: |