123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // +build linux
- package cpu
- import (
- "bufio"
- "fmt"
- "io"
- "os"
- "path"
- "strconv"
- "strings"
- )
- const cgroupRootDir = "/sys/fs/cgroup"
- // cgroup Linux cgroup
- type cgroup struct {
- cgroupSet map[string]string
- }
- // CPUCFSQuotaUs cpu.cfs_quota_us
- func (c *cgroup) CPUCFSQuotaUs() (int64, error) {
- data, err := readFile(path.Join(c.cgroupSet["cpu"], "cpu.cfs_quota_us"))
- if err != nil {
- return 0, err
- }
- return strconv.ParseInt(data, 10, 64)
- }
- // CPUCFSPeriodUs cpu.cfs_period_us
- func (c *cgroup) CPUCFSPeriodUs() (uint64, error) {
- data, err := readFile(path.Join(c.cgroupSet["cpu"], "cpu.cfs_period_us"))
- if err != nil {
- return 0, err
- }
- return parseUint(data)
- }
- // CPUAcctUsage cpuacct.usage
- func (c *cgroup) CPUAcctUsage() (uint64, error) {
- data, err := readFile(path.Join(c.cgroupSet["cpuacct"], "cpuacct.usage"))
- if err != nil {
- return 0, err
- }
- return parseUint(data)
- }
- // CPUAcctUsagePerCPU cpuacct.usage_percpu
- func (c *cgroup) CPUAcctUsagePerCPU() ([]uint64, error) {
- data, err := readFile(path.Join(c.cgroupSet["cpuacct"], "cpuacct.usage_percpu"))
- if err != nil {
- return nil, err
- }
- var usage []uint64
- for _, v := range strings.Fields(string(data)) {
- var u uint64
- if u, err = parseUint(v); err != nil {
- return nil, err
- }
- usage = append(usage, u)
- }
- return usage, nil
- }
- // CPUSetCPUs cpuset.cpus
- func (c *cgroup) CPUSetCPUs() ([]uint64, error) {
- data, err := readFile(path.Join(c.cgroupSet["cpuset"], "cpuset.cpus"))
- if err != nil {
- return nil, err
- }
- cpus, err := ParseUintList(data)
- if err != nil {
- return nil, err
- }
- var sets []uint64
- for k := range cpus {
- sets = append(sets, uint64(k))
- }
- return sets, nil
- }
- // CurrentcGroup get current process cgroup
- func currentcGroup() (*cgroup, error) {
- pid := os.Getpid()
- cgroupFile := fmt.Sprintf("/proc/%d/cgroup", pid)
- cgroupSet := make(map[string]string)
- fp, err := os.Open(cgroupFile)
- if err != nil {
- return nil, err
- }
- defer fp.Close()
- buf := bufio.NewReader(fp)
- for {
- line, err := buf.ReadString('\n')
- if err != nil {
- if err == io.EOF {
- break
- }
- return nil, err
- }
- col := strings.Split(strings.TrimSpace(line), ":")
- if len(col) != 3 {
- return nil, fmt.Errorf("invalid cgroup format %s", line)
- }
- dir := col[2]
- // When dir is not equal to /, it must be in docker
- if dir != "/" {
- cgroupSet[col[1]] = path.Join(cgroupRootDir, col[1])
- if strings.Contains(col[1], ",") {
- for _, k := range strings.Split(col[1], ",") {
- cgroupSet[k] = path.Join(cgroupRootDir, k)
- }
- }
- } else {
- cgroupSet[col[1]] = path.Join(cgroupRootDir, col[1], col[2])
- if strings.Contains(col[1], ",") {
- for _, k := range strings.Split(col[1], ",") {
- cgroupSet[k] = path.Join(cgroupRootDir, k, col[2])
- }
- }
- }
- }
- return &cgroup{cgroupSet: cgroupSet}, nil
- }
|