diff options
-rw-r--r-- | cmd/podman/stop.go | 2 | ||||
-rw-r--r-- | libpod/container_api.go | 36 | ||||
-rw-r--r-- | libpod/container_internal.go | 22 | ||||
-rw-r--r-- | libpod/runtime.go | 2 |
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) } } |