...
1 package fs2
2
3 import (
4 "bufio"
5 "os"
6 "strconv"
7
8 "github.com/opencontainers/runc/libcontainer/cgroups"
9 "github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
10 "github.com/opencontainers/runc/libcontainer/configs"
11 )
12
13 func isCpuSet(r *configs.Resources) bool {
14 return r.CpuWeight != 0 || r.CpuQuota != 0 || r.CpuPeriod != 0
15 }
16
17 func setCpu(dirPath string, r *configs.Resources) error {
18 if !isCpuSet(r) {
19 return nil
20 }
21
22
23 if r.CpuWeight != 0 {
24 if err := cgroups.WriteFile(dirPath, "cpu.weight", strconv.FormatUint(r.CpuWeight, 10)); err != nil {
25 return err
26 }
27 }
28
29 if r.CpuQuota != 0 || r.CpuPeriod != 0 {
30 str := "max"
31 if r.CpuQuota > 0 {
32 str = strconv.FormatInt(r.CpuQuota, 10)
33 }
34 period := r.CpuPeriod
35 if period == 0 {
36
37
38 period = 100000
39 }
40 str += " " + strconv.FormatUint(period, 10)
41 if err := cgroups.WriteFile(dirPath, "cpu.max", str); err != nil {
42 return err
43 }
44 }
45
46 return nil
47 }
48
49 func statCpu(dirPath string, stats *cgroups.Stats) error {
50 const file = "cpu.stat"
51 f, err := cgroups.OpenFile(dirPath, file, os.O_RDONLY)
52 if err != nil {
53 return err
54 }
55 defer f.Close()
56
57 sc := bufio.NewScanner(f)
58 for sc.Scan() {
59 t, v, err := fscommon.ParseKeyValue(sc.Text())
60 if err != nil {
61 return &parseError{Path: dirPath, File: file, Err: err}
62 }
63 switch t {
64 case "usage_usec":
65 stats.CpuStats.CpuUsage.TotalUsage = v * 1000
66
67 case "user_usec":
68 stats.CpuStats.CpuUsage.UsageInUsermode = v * 1000
69
70 case "system_usec":
71 stats.CpuStats.CpuUsage.UsageInKernelmode = v * 1000
72
73 case "nr_periods":
74 stats.CpuStats.ThrottlingData.Periods = v
75
76 case "nr_throttled":
77 stats.CpuStats.ThrottlingData.ThrottledPeriods = v
78
79 case "throttled_usec":
80 stats.CpuStats.ThrottlingData.ThrottledTime = v * 1000
81 }
82 }
83 if err := sc.Err(); err != nil {
84 return &parseError{Path: dirPath, File: file, Err: err}
85 }
86 return nil
87 }
88
View as plain text