Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix container cgroup lookup #8422

Merged
merged 1 commit into from
Nov 20, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/cri-o/ocicni/pkg/ocicni"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

// CgroupfsDefaultCgroupParent is the cgroup parent for CGroupFS in libpod
Expand Down Expand Up @@ -920,19 +921,39 @@ func (c *Container) CGroupPath() (string, error) {
return "", errors.Wrapf(define.ErrNoCgroups, "this container is not creating cgroups")
}

// 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.
// Read /proc/[PID]/cgroup and find the *longest* cgroup entry. That's
// needed to account for hacks in cgroups v1, where each line in the
// file could potentially point to a cgroup. The longest one, however,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems pretty arbitrary, but if it fixes our Flake,

LGTM

// 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)
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)

var cgroupPath string
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
Expand Down