package fs2 import ( "bufio" "os" "path/filepath" "strings" "linkfog.com/public/lib/cgroup/fscommon" "linkfog.com/public/lib/l" ) func GetCPULimit(cgroupDir string, defaultLimit float64) float64 { contents, err := fscommon.GetCgroupParamString(filepath.Join(cgroupDir, "cpu.max")) if err != nil { l.Errorf("read cpu.max file error:%v, use default value", err) return defaultLimit } fields := strings.Split(contents, " ") if len(fields) != 2 { l.Errorf("parse cpu.max file error, contents:%s, use default value", contents) return defaultLimit } // parse quota if fields[0] == "max" { l.Warn("cpu.max quota is max, use default value") return defaultLimit } cpuQuota, err := fscommon.ParseUint(fields[0], 10, 64) if err != nil { l.Errorf("parse cpu.max quota error:%v, contents:%s, use default value", err, fields[0]) return defaultLimit } if cpuQuota == 0 { l.Warn("cpu.max quota is 0, use default value") return defaultLimit } // parse period cpuPeriod, err := fscommon.ParseUint(fields[1], 10, 64) if err != nil { l.Errorf("parse cpu.max period error:%v, contents:%s, use default value", err, fields[1]) return defaultLimit } if cpuPeriod == 0 { l.Warn("cpu.max period is 0, use default value") return defaultLimit } return float64(cpuQuota) / float64(cpuPeriod) } func GetCPUUsage(cgroupDir string) (totalUsage uint64, err error) { return statCPU(cgroupDir) } // Copied from: https://github.com/opencontainers/runc/blob/main/libcontainer/cgroups/fs2/cpu.go func statCPU(dirPath string) (cpuUsage uint64, err error) { f, err := os.Open(filepath.Join(dirPath, "cpu.stat")) if err != nil { return cpuUsage, err } defer f.Close() sc := bufio.NewScanner(f) for sc.Scan() { t, v, err := fscommon.ParseKeyValue(sc.Text()) if err != nil { return cpuUsage, err } switch t { case "usage_usec": return v * 1000, nil } } if err := sc.Err(); err != nil { return cpuUsage, err } return cpuUsage, nil }