...
1 package fs
2
3 import (
4 "errors"
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 type HugetlbGroup struct{}
14
15 func (s *HugetlbGroup) Name() string {
16 return "hugetlb"
17 }
18
19 func (s *HugetlbGroup) Apply(path string, _ *configs.Resources, pid int) error {
20 return apply(path, pid)
21 }
22
23 func (s *HugetlbGroup) Set(path string, r *configs.Resources) error {
24 const suffix = ".limit_in_bytes"
25 skipRsvd := false
26
27 for _, hugetlb := range r.HugetlbLimit {
28 prefix := "hugetlb." + hugetlb.Pagesize
29 val := strconv.FormatUint(hugetlb.Limit, 10)
30 if err := cgroups.WriteFile(path, prefix+suffix, val); err != nil {
31 return err
32 }
33 if skipRsvd {
34 continue
35 }
36 if err := cgroups.WriteFile(path, prefix+".rsvd"+suffix, val); err != nil {
37 if errors.Is(err, os.ErrNotExist) {
38 skipRsvd = true
39 continue
40 }
41 return err
42 }
43 }
44
45 return nil
46 }
47
48 func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error {
49 if !cgroups.PathExists(path) {
50 return nil
51 }
52 rsvd := ".rsvd"
53 hugetlbStats := cgroups.HugetlbStats{}
54 for _, pageSize := range cgroups.HugePageSizes() {
55 again:
56 prefix := "hugetlb." + pageSize + rsvd
57
58 value, err := fscommon.GetCgroupParamUint(path, prefix+".usage_in_bytes")
59 if err != nil {
60 if rsvd != "" && errors.Is(err, os.ErrNotExist) {
61 rsvd = ""
62 goto again
63 }
64 return err
65 }
66 hugetlbStats.Usage = value
67
68 value, err = fscommon.GetCgroupParamUint(path, prefix+".max_usage_in_bytes")
69 if err != nil {
70 return err
71 }
72 hugetlbStats.MaxUsage = value
73
74 value, err = fscommon.GetCgroupParamUint(path, prefix+".failcnt")
75 if err != nil {
76 return err
77 }
78 hugetlbStats.Failcnt = value
79
80 stats.HugetlbStats[pageSize] = hugetlbStats
81 }
82
83 return nil
84 }
85
View as plain text