summaryrefslogtreecommitdiff
path: root/libpod/container.go
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2020-11-10 13:31:19 +0100
committerValentin Rothberg <rothberg@redhat.com>2020-11-17 12:29:50 +0100
commit39bf07694c5716cce3cb7e25c6d01b441b6b4e01 (patch)
tree4afffd1c244936ba54bff308e6df1373dea896d4 /libpod/container.go
parent3502860e1cfe1042aca7a8de8446360662a5a2fd (diff)
downloadpodman-39bf07694c5716cce3cb7e25c6d01b441b6b4e01.tar.gz
podman-39bf07694c5716cce3cb7e25c6d01b441b6b4e01.tar.bz2
podman-39bf07694c5716cce3cb7e25c6d01b441b6b4e01.zip
use container cgroups path
When looking up a container's cgroup path, parse /proc/[PID]/cgroup. This will work across all cgroup managers and configurations and is supported on cgroups v1 and v2. Fixes: #8265 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'libpod/container.go')
-rw-r--r--libpod/container.go55
1 files changed, 15 insertions, 40 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 580fa7b3d..333e1d848 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -1,22 +1,18 @@
package libpod
import (
+ "bytes"
"fmt"
"io/ioutil"
"net"
"os"
- "path/filepath"
- "strings"
"time"
"github.com/containernetworking/cni/pkg/types"
cnitypes "github.com/containernetworking/cni/pkg/types/current"
- "github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/lock"
- "github.com/containers/podman/v2/pkg/rootless"
- "github.com/containers/podman/v2/utils"
"github.com/containers/storage"
"github.com/cri-o/ocicni/pkg/ocicni"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -912,44 +908,23 @@ func (c *Container) CgroupManager() string {
// CGroupPath returns a cgroups "path" for a given container.
func (c *Container) CGroupPath() (string, error) {
- cgroupManager := c.CgroupManager()
-
- switch {
- case c.config.NoCgroups || c.config.CgroupsMode == "disabled":
+ if c.config.NoCgroups || c.config.CgroupsMode == "disabled" {
return "", errors.Wrapf(define.ErrNoCgroups, "this container is not creating cgroups")
- case c.config.CgroupsMode == cgroupSplit:
- if c.config.CgroupParent != "" {
- return "", errors.Errorf("cannot specify cgroup-parent with cgroup-mode %q", cgroupSplit)
- }
- cg, err := utils.GetCgroupProcess(c.state.ConmonPID)
- if err != nil {
- return "", err
- }
- // Use the conmon cgroup for two reasons: we validate the container
- // delegation was correct, and the conmon cgroup doesn't change at runtime
- // while we are not sure about the container that can create sub cgroups.
- if !strings.HasSuffix(cg, "supervisor") {
- return "", errors.Errorf("invalid cgroup for conmon %q", cg)
- }
- return strings.TrimSuffix(cg, "/supervisor") + "/container", nil
- case cgroupManager == config.CgroupfsCgroupsManager:
- return filepath.Join(c.config.CgroupParent, fmt.Sprintf("libpod-%s", c.ID())), nil
- case cgroupManager == config.SystemdCgroupsManager:
- if rootless.IsRootless() {
- uid := rootless.GetRootlessUID()
- parts := strings.SplitN(c.config.CgroupParent, "/", 2)
-
- dir := ""
- if len(parts) > 1 {
- dir = parts[1]
- }
+ }
- return filepath.Join(parts[0], fmt.Sprintf("user-%d.slice/user@%d.service/user.slice/%s", uid, uid, dir), createUnitName("libpod", c.ID())), nil
- }
- return filepath.Join(c.config.CgroupParent, createUnitName("libpod", c.ID())), nil
- default:
- return "", errors.Wrapf(define.ErrInvalidArg, "unsupported CGroup manager %s in use", cgroupManager)
+ // Read /proc/[PID]/cgroup and look at the first line. cgroups(7)
+ // nails it down to three fields with the 3rd pointing to the cgroup's
+ // path which works both on v1 and v2.
+ procPath := fmt.Sprintf("/proc/%d/cgroup", c.state.PID)
+ lines, err := ioutil.ReadFile(procPath)
+ if err != nil {
+ return "", err
+ }
+ fields := bytes.Split(bytes.Split(lines, []byte("\n"))[0], []byte(":"))
+ if len(fields) != 3 {
+ return "", errors.Errorf("expected 3 fields but got %d: %s", len(fields), procPath)
}
+ return string(fields[2]), nil
}
// RootFsSize returns the root FS size of the container