github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/pkg/sysinfo/cgroup2_linux.go (about) 1 package sysinfo // import "github.com/docker/docker/pkg/sysinfo" 2 3 import ( 4 "os" 5 "path" 6 "strings" 7 8 cgroupsV2 "github.com/containerd/cgroups/v2" 9 "github.com/containerd/containerd/pkg/userns" 10 "github.com/opencontainers/runc/libcontainer/cgroups" 11 "github.com/sirupsen/logrus" 12 ) 13 14 func newV2(options ...Opt) *SysInfo { 15 sysInfo := &SysInfo{ 16 CgroupUnified: true, 17 cg2GroupPath: "/", 18 } 19 for _, o := range options { 20 o(sysInfo) 21 } 22 23 ops := []infoCollector{ 24 applyNetworkingInfo, 25 applyAppArmorInfo, 26 applySeccompInfo, 27 applyCgroupNsInfo, 28 } 29 30 m, err := cgroupsV2.LoadManager("/sys/fs/cgroup", sysInfo.cg2GroupPath) 31 if err != nil { 32 logrus.Warn(err) 33 } else { 34 sysInfo.cg2Controllers = make(map[string]struct{}) 35 controllers, err := m.Controllers() 36 if err != nil { 37 logrus.Warn(err) 38 } 39 for _, c := range controllers { 40 sysInfo.cg2Controllers[c] = struct{}{} 41 } 42 ops = append(ops, 43 applyMemoryCgroupInfoV2, 44 applyCPUCgroupInfoV2, 45 applyIOCgroupInfoV2, 46 applyCPUSetCgroupInfoV2, 47 applyPIDSCgroupInfoV2, 48 applyDevicesCgroupInfoV2, 49 ) 50 } 51 52 for _, o := range ops { 53 o(sysInfo) 54 } 55 return sysInfo 56 } 57 58 func getSwapLimitV2() bool { 59 groups, err := cgroups.ParseCgroupFile("/proc/self/cgroup") 60 if err != nil { 61 return false 62 } 63 64 g := groups[""] 65 if g == "" { 66 return false 67 } 68 69 cGroupPath := path.Join("/sys/fs/cgroup", g, "memory.swap.max") 70 if _, err = os.Stat(cGroupPath); os.IsNotExist(err) { 71 return false 72 } 73 return true 74 } 75 76 func applyMemoryCgroupInfoV2(info *SysInfo) { 77 if _, ok := info.cg2Controllers["memory"]; !ok { 78 info.Warnings = append(info.Warnings, "Unable to find memory controller") 79 return 80 } 81 82 info.MemoryLimit = true 83 info.SwapLimit = getSwapLimitV2() 84 info.MemoryReservation = true 85 info.OomKillDisable = false 86 info.MemorySwappiness = false 87 info.KernelMemory = false 88 info.KernelMemoryTCP = false 89 } 90 91 func applyCPUCgroupInfoV2(info *SysInfo) { 92 if _, ok := info.cg2Controllers["cpu"]; !ok { 93 info.Warnings = append(info.Warnings, "Unable to find cpu controller") 94 return 95 } 96 info.CPUShares = true 97 info.CPUCfs = true 98 info.CPURealtime = false 99 } 100 101 func applyIOCgroupInfoV2(info *SysInfo) { 102 if _, ok := info.cg2Controllers["io"]; !ok { 103 info.Warnings = append(info.Warnings, "Unable to find io controller") 104 return 105 } 106 107 info.BlkioWeight = true 108 info.BlkioWeightDevice = true 109 info.BlkioReadBpsDevice = true 110 info.BlkioWriteBpsDevice = true 111 info.BlkioReadIOpsDevice = true 112 info.BlkioWriteIOpsDevice = true 113 } 114 115 func applyCPUSetCgroupInfoV2(info *SysInfo) { 116 if _, ok := info.cg2Controllers["cpuset"]; !ok { 117 info.Warnings = append(info.Warnings, "Unable to find cpuset controller") 118 return 119 } 120 info.Cpuset = true 121 122 cpus, err := os.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.cpus.effective")) 123 if err != nil { 124 return 125 } 126 info.Cpus = strings.TrimSpace(string(cpus)) 127 128 mems, err := os.ReadFile(path.Join("/sys/fs/cgroup", info.cg2GroupPath, "cpuset.mems.effective")) 129 if err != nil { 130 return 131 } 132 info.Mems = strings.TrimSpace(string(mems)) 133 } 134 135 func applyPIDSCgroupInfoV2(info *SysInfo) { 136 if _, ok := info.cg2Controllers["pids"]; !ok { 137 info.Warnings = append(info.Warnings, "Unable to find pids controller") 138 return 139 } 140 info.PidsLimit = true 141 } 142 143 func applyDevicesCgroupInfoV2(info *SysInfo) { 144 info.CgroupDevicesEnabled = !userns.RunningInUserNS() 145 }