123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package cgroups
- import (
- "bufio"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- specs "github.com/opencontainers/runtime-spec/specs-go"
- )
- func NewCpu(root string) *cpuController {
- return &cpuController{
- root: filepath.Join(root, string(Cpu)),
- }
- }
- type cpuController struct {
- root string
- }
- func (c *cpuController) Name() Name {
- return Cpu
- }
- func (c *cpuController) Path(path string) string {
- return filepath.Join(c.root, path)
- }
- func (c *cpuController) Create(path string, resources *specs.LinuxResources) error {
- if err := os.MkdirAll(c.Path(path), defaultDirPerm); err != nil {
- return err
- }
- if cpu := resources.CPU; cpu != nil {
- for _, t := range []struct {
- name string
- ivalue *int64
- uvalue *uint64
- }{
- {
- name: "rt_period_us",
- uvalue: cpu.RealtimePeriod,
- },
- {
- name: "rt_runtime_us",
- ivalue: cpu.RealtimeRuntime,
- },
- {
- name: "shares",
- uvalue: cpu.Shares,
- },
- {
- name: "cfs_period_us",
- uvalue: cpu.Period,
- },
- {
- name: "cfs_quota_us",
- ivalue: cpu.Quota,
- },
- } {
- var value []byte
- if t.uvalue != nil {
- value = []byte(strconv.FormatUint(*t.uvalue, 10))
- } else if t.ivalue != nil {
- value = []byte(strconv.FormatInt(*t.ivalue, 10))
- }
- if value != nil {
- if err := ioutil.WriteFile(
- filepath.Join(c.Path(path), fmt.Sprintf("cpu.%s", t.name)),
- value,
- defaultFilePerm,
- ); err != nil {
- return err
- }
- }
- }
- }
- return nil
- }
- func (c *cpuController) Update(path string, resources *specs.LinuxResources) error {
- return c.Create(path, resources)
- }
- func (c *cpuController) Stat(path string, stats *Metrics) error {
- f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat"))
- if err != nil {
- return err
- }
- defer f.Close()
- // get or create the cpu field because cpuacct can also set values on this struct
- sc := bufio.NewScanner(f)
- for sc.Scan() {
- if err := sc.Err(); err != nil {
- return err
- }
- key, v, err := parseKV(sc.Text())
- if err != nil {
- return err
- }
- switch key {
- case "nr_periods":
- stats.CPU.Throttling.Periods = v
- case "nr_throttled":
- stats.CPU.Throttling.ThrottledPeriods = v
- case "throttled_time":
- stats.CPU.Throttling.ThrottledTime = v
- }
- }
- return nil
- }
|