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