aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-10-10 14:45:56 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-10-10 14:53:29 -0400
commitb6a7d88397c95a9f3a462274a890b65faafd4d7a (patch)
tree416ad704a77831173316325672f932ef1246e9ce
parent6f630bc09b3e937fe3ddc4a829715bacd5b6c779 (diff)
downloadpodman-b6a7d88397c95a9f3a462274a890b65faafd4d7a.tar.gz
podman-b6a7d88397c95a9f3a462274a890b65faafd4d7a.tar.bz2
podman-b6a7d88397c95a9f3a462274a890b65faafd4d7a.zip
When restoring containers, reset cgroup path
Previously, `podman checkport restore` with exported containers, when told to create a new container based on the exported checkpoint, would create a new container, with a new container ID, but not reset CGroup path - which contained the ID of the original container. If this was done multiple times, the result was two containers with the same cgroup paths. Operations on these containers would this have a chance of crossing over to affect the other one; the most notable was `podman rm` once it was changed to use the --all flag when stopping the container; all processes in the cgroup, including the ones in the other container, would be stopped. Reset cgroups on restore to ensure that the path matches the ID of the container actually being run. Signed-off-by: Matthew Heon <matthew.heon@pm.me>
-rw-r--r--libpod/container_internal_linux.go47
-rw-r--r--libpod/container_internal_unsupported.go4
-rw-r--r--libpod/runtime_ctr.go8
3 files changed, 41 insertions, 18 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index a35daf71d..b7d353327 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -419,27 +419,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
g.AddProcessEnv("container", "libpod")
}
- unified, err := cgroups.IsCgroup2UnifiedMode()
+ cgroupPath, err := c.getOCICgroupPath()
if err != nil {
return nil, err
}
- if (rootless.IsRootless() && !unified) || c.config.NoCgroups {
- g.SetLinuxCgroupsPath("")
- } else if c.runtime.config.CgroupManager == SystemdCgroupsManager {
- // When runc is set to use Systemd as a cgroup manager, it
- // expects cgroups to be passed as follows:
- // slice:prefix:name
- systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
- logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups)
- g.SetLinuxCgroupsPath(systemdCgroups)
- } else {
- cgroupPath, err := c.CGroupPath()
- if err != nil {
- return nil, err
- }
- logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
- g.SetLinuxCgroupsPath(cgroupPath)
- }
+ g.SetLinuxCgroupsPath(cgroupPath)
// Mounts need to be sorted so paths will not cover other paths
mounts := sortMounts(g.Mounts())
@@ -1332,3 +1316,30 @@ func (c *Container) refreshCNI() error {
podNetwork := c.runtime.getPodNetwork(c.ID(), c.config.Name, "", c.config.Networks, c.config.PortMappings, c.config.StaticIP)
return c.runtime.netPlugin.TearDownPod(podNetwork)
}
+
+// Get cgroup path in a format suitable for the OCI spec
+func (c *Container) getOCICgroupPath() (string, error) {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return "", err
+ }
+ if (rootless.IsRootless() && !unified) || c.config.NoCgroups {
+ return "", nil
+ } else if c.runtime.config.CgroupManager == SystemdCgroupsManager {
+ // When runc is set to use Systemd as a cgroup manager, it
+ // expects cgroups to be passed as follows:
+ // slice:prefix:name
+ systemdCgroups := fmt.Sprintf("%s:libpod:%s", path.Base(c.config.CgroupParent), c.ID())
+ logrus.Debugf("Setting CGroups for container %s to %s", c.ID(), systemdCgroups)
+ return systemdCgroups, nil
+ } else if c.runtime.config.CgroupManager == CgroupfsCgroupsManager {
+ cgroupPath, err := c.CGroupPath()
+ if err != nil {
+ return "", err
+ }
+ logrus.Debugf("Setting CGroup path for container %s to %s", c.ID(), cgroupPath)
+ return cgroupPath, nil
+ } else {
+ return "", errors.Wrapf(define.ErrInvalidArg, "invalid cgroup manager %s requested", c.runtime.config.CgroupManager)
+ }
+}
diff --git a/libpod/container_internal_unsupported.go b/libpod/container_internal_unsupported.go
index 05a587c59..4abaa6362 100644
--- a/libpod/container_internal_unsupported.go
+++ b/libpod/container_internal_unsupported.go
@@ -44,3 +44,7 @@ func (c *Container) copyOwnerAndPerms(source, dest string) error {
func (c *Container) refreshCNI() error {
return define.ErrNotImplemented
}
+
+func (c *Container) getOCICgroupPath() (string, error) {
+ return "", define.ErrNotImplemented
+}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index c1d7571e2..411264d25 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -264,6 +264,14 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai
g.RemoveMount("/etc/hosts")
g.RemoveMount("/run/.containerenv")
g.RemoveMount("/run/secrets")
+
+ // Regenerate CGroup paths so they don't point to the old
+ // container ID.
+ cgroupPath, err := ctr.getOCICgroupPath()
+ if err != nil {
+ return nil, err
+ }
+ g.SetLinuxCgroupsPath(cgroupPath)
}
// Set up storage for the container