Files
moby/pkg/sysinfo/cgroup2_linux.go
Sebastiaan van Stijn 18a1b61b49 pkg/sysinfo: remove // import comments
These comments were added to enforce using the correct import path for
our packages ("github.com/docker/docker", not "github.com/moby/moby").
However, when working in go module mode (not GOPATH / vendor), they have
no effect, so their impact is limited.

Remove these imports in preparation of migrating our code to become an
actual go module.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-30 15:59:18 +02:00

160 lines
3.5 KiB
Go

package sysinfo
import (
"context"
"os"
"path"
"strings"
"github.com/containerd/cgroups/v3"
cgroupsV2 "github.com/containerd/cgroups/v3/cgroup2"
"github.com/containerd/log"
"github.com/moby/sys/userns"
)
func newV2(options ...Opt) *SysInfo {
sysInfo := &SysInfo{
CgroupUnified: true,
cg2GroupPath: "/",
}
for _, o := range options {
o(sysInfo)
}
ops := []infoCollector{
applyNetworkingInfo,
applyAppArmorInfo,
applySeccompInfo,
applyCgroupNsInfo,
}
m, err := cgroupsV2.Load(sysInfo.cg2GroupPath)
if err != nil {
log.G(context.TODO()).Warn(err)
} else {
sysInfo.cg2Controllers = make(map[string]struct{})
controllers, err := m.Controllers()
if err != nil {
log.G(context.TODO()).Warn(err)
}
for _, c := range controllers {
sysInfo.cg2Controllers[c] = struct{}{}
}
ops = append(ops,
applyMemoryCgroupInfoV2,
applyCPUCgroupInfoV2,
applyIOCgroupInfoV2,
applyCPUSetCgroupInfoV2,
applyPIDSCgroupInfoV2,
applyDevicesCgroupInfoV2,
)
}
for _, o := range ops {
o(sysInfo)
}
return sysInfo
}
func getSwapLimitV2() bool {
_, g, err := cgroups.ParseCgroupFileUnified("/proc/self/cgroup")
if err != nil {
return false
}
if g == "" {
return false
}
cGroupPath := path.Join("/sys/fs/cgroup", g, "memory.swap.max")
if _, err = os.Stat(cGroupPath); os.IsNotExist(err) {
return false
}
return true
}
func applyMemoryCgroupInfoV2(info *SysInfo) {
if _, ok := info.cg2Controllers["memory"]; !ok {
info.Warnings = append(info.Warnings, "Unable to find memory controller")
return
}
info.MemoryLimit = true
info.SwapLimit = getSwapLimitV2()
info.MemoryReservation = true
info.OomKillDisable = false
info.MemorySwappiness = false
info.KernelMemory = false
info.KernelMemoryTCP = false
}
func applyCPUCgroupInfoV2(info *SysInfo) {
if _, ok := info.cg2Controllers["cpu"]; !ok {
info.Warnings = append(info.Warnings, "Unable to find cpu controller")
return
}
info.CPUShares = true
info.CPUCfs = true
info.CPURealtime = false
}
func applyIOCgroupInfoV2(info *SysInfo) {
if _, ok := info.cg2Controllers["io"]; !ok {
info.Warnings = append(info.Warnings, "Unable to find io controller")
return
}
info.BlkioWeight = true
info.BlkioWeightDevice = true
info.BlkioReadBpsDevice = true
info.BlkioWriteBpsDevice = true
info.BlkioReadIOpsDevice = true
info.BlkioWriteIOpsDevice = true
}
func applyCPUSetCgroupInfoV2(info *SysInfo) {
if _, ok := info.cg2Controllers["cpuset"]; !ok {
info.Warnings = append(info.Warnings, "Unable to find cpuset controller")
return
}
info.Cpuset = true
cpus, err := os.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.cpus.effective"))
if err != nil {
return
}
info.Cpus = strings.TrimSpace(string(cpus))
cpuSets, err := parseUintList(info.Cpus, 0)
if err != nil {
info.Warnings = append(info.Warnings, "Unable to parse cpuset cpus: "+err.Error())
return
}
info.CPUSets = cpuSets
mems, err := os.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.mems.effective"))
if err != nil {
return
}
info.Mems = strings.TrimSpace(string(mems))
memSets, err := parseUintList(info.Cpus, 0)
if err != nil {
info.Warnings = append(info.Warnings, "Unable to parse cpuset mems: "+err.Error())
return
}
info.MemSets = memSets
}
func applyPIDSCgroupInfoV2(info *SysInfo) {
if _, ok := info.cg2Controllers["pids"]; !ok {
info.Warnings = append(info.Warnings, "Unable to find pids controller")
return
}
info.PidsLimit = true
}
func applyDevicesCgroupInfoV2(info *SysInfo) {
info.CgroupDevicesEnabled = !userns.RunningInUserNS()
}