1// +build linux
2
3package fs
4
5import (
6	"bufio"
7	"os"
8	"path/filepath"
9	"strconv"
10
11	"github.com/opencontainers/runc/libcontainer/cgroups"
12	"github.com/opencontainers/runc/libcontainer/configs"
13)
14
15type CpuGroup struct {
16}
17
18func (s *CpuGroup) Name() string {
19	return "cpu"
20}
21
22func (s *CpuGroup) Apply(d *cgroupData) error {
23	// We always want to join the cpu group, to allow fair cpu scheduling
24	// on a container basis
25	_, err := d.join("cpu")
26	if err != nil && !cgroups.IsNotFound(err) {
27		return err
28	}
29	return nil
30}
31
32func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
33	if cgroup.Resources.CpuShares != 0 {
34		if err := writeFile(path, "cpu.shares", strconv.FormatInt(cgroup.Resources.CpuShares, 10)); err != nil {
35			return err
36		}
37	}
38	if cgroup.Resources.CpuPeriod != 0 {
39		if err := writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(cgroup.Resources.CpuPeriod, 10)); err != nil {
40			return err
41		}
42	}
43	if cgroup.Resources.CpuQuota != 0 {
44		if err := writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(cgroup.Resources.CpuQuota, 10)); err != nil {
45			return err
46		}
47	}
48	if cgroup.Resources.CpuRtPeriod != 0 {
49		if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.Resources.CpuRtPeriod, 10)); err != nil {
50			return err
51		}
52	}
53	if cgroup.Resources.CpuRtRuntime != 0 {
54		if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil {
55			return err
56		}
57	}
58
59	return nil
60}
61
62func (s *CpuGroup) Remove(d *cgroupData) error {
63	return removePath(d.path("cpu"))
64}
65
66func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error {
67	f, err := os.Open(filepath.Join(path, "cpu.stat"))
68	if err != nil {
69		if os.IsNotExist(err) {
70			return nil
71		}
72		return err
73	}
74	defer f.Close()
75
76	sc := bufio.NewScanner(f)
77	for sc.Scan() {
78		t, v, err := getCgroupParamKeyValue(sc.Text())
79		if err != nil {
80			return err
81		}
82		switch t {
83		case "nr_periods":
84			stats.CpuStats.ThrottlingData.Periods = v
85
86		case "nr_throttled":
87			stats.CpuStats.ThrottlingData.ThrottledPeriods = v
88
89		case "throttled_time":
90			stats.CpuStats.ThrottlingData.ThrottledTime = v
91		}
92	}
93	return nil
94}
95