summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2019-12-18 09:42:01 -0500
committerDaniel J Walsh <dwalsh@redhat.com>2019-12-19 13:33:17 -0500
commit123b8c627d53c6bd76ff4d9f6a74674341a987c0 (patch)
treee6bdf872b1264da1001a24145c4165b4b96e6527
parent6b956dfd1f1071ceb40b403a9604da387979105a (diff)
downloadpodman-123b8c627d53c6bd76ff4d9f6a74674341a987c0.tar.gz
podman-123b8c627d53c6bd76ff4d9f6a74674341a987c0.tar.bz2
podman-123b8c627d53c6bd76ff4d9f6a74674341a987c0.zip
if container is not in a pid namespace, stop all processes
When a container is in a PID namespace, it is enought to send the stop signal to the PID 1 of the namespace, only send signals to all processes in the container when the container is not in a pid namespace. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
-rw-r--r--libpod/container_api.go4
-rw-r--r--libpod/container_internal.go21
-rw-r--r--libpod/pod_api.go2
-rw-r--r--libpod/runtime_ctr.go2
4 files changed, 23 insertions, 6 deletions
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 5168dbc68..e36623529 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -183,7 +183,7 @@ func (c *Container) StopWithTimeout(timeout uint) error {
return errors.Wrapf(define.ErrCtrStateInvalid, "can only stop created or running containers. %s is in state %s", c.ID(), c.state.State.String())
}
- return c.stop(timeout, false)
+ return c.stop(timeout)
}
// Kill sends a signal to a container
@@ -715,7 +715,7 @@ func (c *Container) Refresh(ctx context.Context) error {
// Next, if the container is running, stop it
if c.state.State == define.ContainerStateRunning {
- if err := c.stop(c.config.StopTimeout, false); err != nil {
+ if err := c.stop(c.config.StopTimeout); err != nil {
return err
}
}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 37801162a..9d97ac5d6 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1129,9 +1129,14 @@ func (c *Container) start() error {
}
// Internal, non-locking function to stop container
-func (c *Container) stop(timeout uint, all bool) error {
+func (c *Container) stop(timeout uint) error {
logrus.Debugf("Stopping ctr %s (timeout %d)", c.ID(), timeout)
+ // If the container is running in a PID Namespace, then killing the
+ // primary pid is enough to kill the container. If it is not running in
+ // a pid namespace then the OCI Runtime needs to kill ALL processes in
+ // the containers cgroup in order to make sure the container is stopped.
+ all := !c.hasNamespace(spec.PIDNamespace)
// We can't use --all if CGroups aren't present.
// Rootless containers with CGroups v1 and NoCgroups are both cases
// where this can happen.
@@ -1225,7 +1230,7 @@ func (c *Container) restartWithTimeout(ctx context.Context, timeout uint) (err e
if c.state.State == define.ContainerStateRunning {
conmonPID := c.state.ConmonPID
- if err := c.stop(timeout, false); err != nil {
+ if err := c.stop(timeout); err != nil {
return err
}
// Old versions of conmon have a bug where they create the exit file before
@@ -1895,3 +1900,15 @@ func (c *Container) reapExecSessions() error {
}
return lastErr
}
+
+func (c *Container) hasNamespace(namespace spec.LinuxNamespaceType) bool {
+ if c.config.Spec == nil || c.config.Spec.Linux == nil {
+ return false
+ }
+ for _, n := range c.config.Spec.Linux.Namespaces {
+ if n.Type == namespace {
+ return true
+ }
+ }
+ return false
+}
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index b27257004..cb04f7411 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -123,7 +123,7 @@ func (p *Pod) StopWithTimeout(ctx context.Context, cleanup bool, timeout int) (m
if timeout > -1 {
stopTimeout = uint(timeout)
}
- if err := ctr.stop(stopTimeout, false); err != nil {
+ if err := ctr.stop(stopTimeout); err != nil {
ctr.lock.Unlock()
ctrErrors[ctr.ID()] = err
continue
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index ae401013c..6a10849ab 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -463,7 +463,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool,
// Check that the container's in a good state to be removed
if c.state.State == define.ContainerStateRunning {
- if err := c.stop(c.StopTimeout(), true); err != nil {
+ if err := c.stop(c.StopTimeout()); err != nil {
return errors.Wrapf(err, "cannot remove container %s as it could not be stopped", c.ID())
}
}