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  }