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
pkg/sysinfo: remove libcontainer dependency #43347
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,22 +5,62 @@ import ( | |
"os" | ||
"path" | ||
"strings" | ||
"sync" | ||
|
||
cdcgroups "github.com/containerd/cgroups" | ||
cdseccomp "github.com/containerd/containerd/pkg/seccomp" | ||
"github.com/opencontainers/runc/libcontainer/cgroups" | ||
"github.com/containerd/cgroups" | ||
"github.com/containerd/containerd/pkg/seccomp" | ||
"github.com/moby/sys/mountinfo" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
func findCgroupMountpoints() (map[string]string, error) { | ||
cgMounts, err := cgroups.GetCgroupMounts(false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FTR; the function in runc also deals with V2, but (see rest of this PR) we're not using that, so 👍 https://github.com/opencontainers/runc/blob/eddf35e5462e2a9f24d8279874a84cfc8b8453c2/libcontainer/cgroups/utils.go#L76-L88 |
||
var ( | ||
readMountinfoOnce sync.Once | ||
readMountinfoErr error | ||
cgroupMountinfo []*mountinfo.Info | ||
) | ||
|
||
// readCgroupMountinfo returns a list of cgroup v1 mounts (i.e. the ones | ||
// with fstype of "cgroup") for the current running process. | ||
// | ||
// The results are cached (to avoid re-reading mountinfo which is relatively | ||
// expensive), so it is assumed that cgroup mounts are not being changed. | ||
func readCgroupMountinfo() ([]*mountinfo.Info, error) { | ||
readMountinfoOnce.Do(func() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, it looks like Anyway, ok for a follow up (if that would work) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I took the conservative route of retaining the existing behavior as I am not familiar enough with the finer points of cgroups to know whether /proc/self/cgroups is as safe to cache as the cgroupfs mounts in /proc/self/mountinfo. I agree that it would make a lot of sense to parse /proc/self/cgroups only once if we know it is safe to cache. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heh; I was looking along the same lines; initially thought "cache it!" then noticed (hence the "for a follow up" 😂) |
||
cgroupMountinfo, readMountinfoErr = mountinfo.GetMounts( | ||
mountinfo.FSTypeFilter("cgroup"), | ||
) | ||
}) | ||
|
||
return cgroupMountinfo, readMountinfoErr | ||
} | ||
|
||
func findCgroupV1Mountpoints() (map[string]string, error) { | ||
mounts, err := readCgroupMountinfo() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
allSubsystems, err := cgroups.ParseCgroupFile("/proc/self/cgroup") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just recalled there was a subtle difference between the "runc" variant and the "containerd" variant that I noticed when I exported this (containerd/cgroups#197); the same where the containerd variant ignored empty subsystems, but the runc variant didn't; for _, subs := range strings.Split(parts[1], ",") {
if subs != "" {
cgroups[subs] = parts[2]
}
} for _, subs := range strings.Split(parts[1], ",") {
cgroups[subs] = parts[2]
} But re-reading the comment in runc opencontainers/runc#3001 (comment), it looks to be only for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for rambling 😂 - had to double check if it was fine here (had that on my list of todo's 🤗) |
||
if err != nil { | ||
return nil, fmt.Errorf("Failed to parse cgroup information: %v", err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (not for this PR) we should fix this error to not start with a capital, and use pkg/errors for this (not sure if we should |
||
} | ||
|
||
allMap := make(map[string]bool) | ||
for s := range allSubsystems { | ||
allMap[s] = false | ||
} | ||
|
||
mps := make(map[string]string) | ||
for _, m := range cgMounts { | ||
for _, ss := range m.Subsystems { | ||
mps[ss] = m.Mountpoint | ||
for _, mi := range mounts { | ||
for _, opt := range strings.Split(mi.VFSOptions, ",") { | ||
seen, known := allMap[opt] | ||
if known && !seen { | ||
allMap[opt] = true | ||
mps[strings.TrimPrefix(opt, "name=")] = mi.Mountpoint | ||
} | ||
} | ||
if len(mps) >= len(allMap) { | ||
break | ||
} | ||
} | ||
return mps, nil | ||
|
@@ -45,7 +85,7 @@ func WithCgroup2GroupPath(g string) Opt { | |
// New returns a new SysInfo, using the filesystem to detect which features | ||
// the kernel supports. | ||
func New(options ...Opt) *SysInfo { | ||
if cdcgroups.Mode() == cdcgroups.Unified { | ||
if cgroups.Mode() == cgroups.Unified { | ||
return newV2(options...) | ||
} | ||
return newV1() | ||
|
@@ -64,7 +104,7 @@ func newV1() *SysInfo { | |
applyCgroupNsInfo, | ||
} | ||
|
||
sysInfo.cgMounts, err = findCgroupMountpoints() | ||
sysInfo.cgMounts, err = findCgroupV1Mountpoints() | ||
if err != nil { | ||
logrus.Warn(err) | ||
} else { | ||
|
@@ -246,7 +286,7 @@ func applyCgroupNsInfo(info *SysInfo) { | |
|
||
// applySeccompInfo checks if Seccomp is supported, via CONFIG_SECCOMP. | ||
func applySeccompInfo(info *SysInfo) { | ||
info.Seccomp = cdseccomp.IsEnabled() | ||
info.Seccomp = seccomp.IsEnabled() | ||
} | ||
|
||
func cgroupEnabled(mountPoint, name string) bool { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused a regression:
docker info
always showsWARNING: No swap limit support
on cgroup v2 hosts #43646Because
containerd/cgroups.ParseCgroupFile
(purposely) does not support the unified hierarchy:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, dang that's what I initially was afraid of #43347 (comment)