aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <mheon@redhat.com>2018-01-29 11:59:33 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-01-30 05:02:12 +0000
commitc60d8a0671b48ffdeda68895e0b7d97b252d66d9 (patch)
tree6be6b971913ae7763b79d7eef68dc71284a841c5
parentdd133a1ad25f75e5ddd53ed6cf59eedfb6838f54 (diff)
downloadpodman-c60d8a0671b48ffdeda68895e0b7d97b252d66d9.tar.gz
podman-c60d8a0671b48ffdeda68895e0b7d97b252d66d9.tar.bz2
podman-c60d8a0671b48ffdeda68895e0b7d97b252d66d9.zip
Add StopWithTimeout API function for containers
Normal Stop should not need a timeout, and should use the default Add a function that does accept a timeout aside it Signed-off-by: Matthew Heon <mheon@redhat.com> Closes: #272 Approved by: rhatdan
-rw-r--r--cmd/podman/stop.go2
-rw-r--r--libpod/container_api.go36
-rw-r--r--libpod/container_internal.go22
-rw-r--r--libpod/runtime.go2
4 files changed, 42 insertions, 20 deletions
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index d18a05bd4..9a0f28994 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -101,7 +101,7 @@ func stopCmd(c *cli.Context) error {
} else {
stopTimeout = ctr.StopTimeout()
}
- if err := ctr.Stop(stopTimeout); err != nil {
+ if err := ctr.StopWithTimeout(stopTimeout); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 2b3c83eb2..cd3485880 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -326,10 +326,11 @@ func (c *Container) Start() error {
}
// Stop uses the container's stop signal (or SIGTERM if no signal was specified)
-// to stop the container, and if it has not stopped after the given timeout (in
-// seconds), uses SIGKILL to attempt to forcibly stop the container.
-// If timeout is 0, SIGKILL will be used immediately
-func (c *Container) Stop(timeout uint) error {
+// to stop the container, and if it has not stopped after container's stop
+// timeout, SIGKILL is used to attempt to forcibly stop the container
+// Default stop timeout is 10 seconds, but can be overridden when the container
+// is created
+func (c *Container) Stop() error {
if !c.locked {
c.lock.Lock()
defer c.lock.Unlock()
@@ -339,24 +340,23 @@ func (c *Container) Stop(timeout uint) error {
}
}
- logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
-
- if c.state.State == ContainerStateConfigured ||
- c.state.State == ContainerStateUnknown ||
- c.state.State == ContainerStatePaused {
- return errors.Wrapf(ErrCtrStateInvalid, "can only stop created, running, or stopped containers")
- }
+ return c.stop(c.config.StopTimeout)
+}
- if err := c.runtime.ociRuntime.stopContainer(c, timeout); err != nil {
- return err
- }
+// StopWithTimeout is a version of Stop that allows a timeout to be specified
+// manually. If timeout is 0, SIGKILL will be used immediately to kill the
+// container.
+func (c *Container) StopWithTimeout(timeout uint) error {
+ if !c.locked {
+ c.lock.Lock()
+ defer c.lock.Unlock()
- // Sync the container's state to pick up return code
- if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil {
- return err
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
}
- return c.cleanupStorage()
+ return c.stop(timeout)
}
// Kill sends a signal to a container
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 9b785bfa5..fd8e826ba 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -302,6 +302,28 @@ func (c *Container) save() error {
return nil
}
+// Internal, non-locking function to stop container
+func (c *Container) stop(timeout uint) error {
+ logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
+
+ if c.state.State == ContainerStateConfigured ||
+ c.state.State == ContainerStateUnknown ||
+ c.state.State == ContainerStatePaused {
+ return errors.Wrapf(ErrCtrStateInvalid, "can only stop created, running, or stopped containers")
+ }
+
+ if err := c.runtime.ociRuntime.stopContainer(c, timeout); err != nil {
+ return err
+ }
+
+ // Sync the container's state to pick up return code
+ if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil {
+ return err
+ }
+
+ return c.cleanupStorage()
+}
+
// mountStorage sets up the container's root filesystem
// It mounts the image and any other requested mounts
// TODO: Add ability to override mount label so we can use this for Mount() too
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 804f69c9e..20ae2c6fe 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -299,7 +299,7 @@ func (r *Runtime) Shutdown(force bool) error {
logrus.Errorf("Error retrieving containers from database: %v", err)
} else {
for _, ctr := range ctrs {
- if err := ctr.Stop(CtrRemoveTimeout); err != nil {
+ if err := ctr.StopWithTimeout(CtrRemoveTimeout); err != nil {
logrus.Errorf("Error stopping container %s: %v", ctr.ID(), err)
}
}