mirror of
https://github.com/containers/podman.git
synced 2025-07-01 00:01:02 +08:00
fix container cgroup lookup
When running on cgroups v1, `/proc/{PID}/cgroup` has multiple entries, each pointing potentially to a different cgroup. Some may be empty, some may point to parents. The one we really need is the libpod-specific one, which always is the longest path. So instead of looking at the first entry, look at all and select the longest one. Fixes: #8397 Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CgroupfsDefaultCgroupParent is the cgroup parent for CGroupFS in libpod
|
// CgroupfsDefaultCgroupParent is the cgroup parent for CGroupFS in libpod
|
||||||
@ -920,19 +921,39 @@ func (c *Container) CGroupPath() (string, error) {
|
|||||||
return "", errors.Wrapf(define.ErrNoCgroups, "this container is not creating cgroups")
|
return "", errors.Wrapf(define.ErrNoCgroups, "this container is not creating cgroups")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read /proc/[PID]/cgroup and look at the first line. cgroups(7)
|
// Read /proc/[PID]/cgroup and find the *longest* cgroup entry. That's
|
||||||
// nails it down to three fields with the 3rd pointing to the cgroup's
|
// needed to account for hacks in cgroups v1, where each line in the
|
||||||
// path which works both on v1 and v2.
|
// file could potentially point to a cgroup. The longest one, however,
|
||||||
|
// is the libpod-specific one we're looking for.
|
||||||
|
//
|
||||||
|
// See #8397 on the need for the longest-path look up.
|
||||||
procPath := fmt.Sprintf("/proc/%d/cgroup", c.state.PID)
|
procPath := fmt.Sprintf("/proc/%d/cgroup", c.state.PID)
|
||||||
lines, err := ioutil.ReadFile(procPath)
|
lines, err := ioutil.ReadFile(procPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
fields := bytes.Split(bytes.Split(lines, []byte("\n"))[0], []byte(":"))
|
|
||||||
if len(fields) != 3 {
|
var cgroupPath string
|
||||||
return "", errors.Errorf("expected 3 fields but got %d: %s", len(fields), procPath)
|
for _, line := range bytes.Split(lines, []byte("\n")) {
|
||||||
|
// cgroups(7) nails it down to three fields with the 3rd
|
||||||
|
// pointing to the cgroup's path which works both on v1 and v2.
|
||||||
|
fields := bytes.Split(line, []byte(":"))
|
||||||
|
if len(fields) != 3 {
|
||||||
|
logrus.Debugf("Error parsing cgroup: expected 3 fields but got %d: %s", len(fields), procPath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
path := string(fields[2])
|
||||||
|
if len(path) > len(cgroupPath) {
|
||||||
|
cgroupPath = path
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return string(fields[2]), nil
|
|
||||||
|
if len(cgroupPath) == 0 {
|
||||||
|
return "", errors.Errorf("could not find any cgroup in %q", procPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cgroupPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RootFsSize returns the root FS size of the container
|
// RootFsSize returns the root FS size of the container
|
||||||
|
Reference in New Issue
Block a user