33package cgroups
44
55import (
6+ "bufio"
7+ "errors"
8+ "fmt"
9+ "os"
610 "path/filepath"
711 "strconv"
812 "strings"
@@ -22,56 +26,122 @@ func getBlkioHandler() *linuxBlkioHandler {
2226
2327// Apply set the specified constraints.
2428func (c * linuxBlkioHandler ) Apply (ctr * CgroupControl , res * cgroups.Resources ) error {
25- man , err := fs2 .NewManager (ctr .config , filepath .Join (cgroupRoot , ctr .config .Path ))
26- if err != nil {
27- return err
29+ if ctr .cgroup2 {
30+ man , err := fs2 .NewManager (ctr .config , filepath .Join (cgroupRoot , ctr .config .Path ))
31+ if err != nil {
32+ return err
33+ }
34+ return man .Set (res )
35+ }
36+ path := filepath .Join (cgroupRoot , Blkio , ctr .config .Path )
37+ return c .Blkio .Set (path , res )
38+ }
39+
40+ // Create the cgroup.
41+ func (c * linuxBlkioHandler ) Create (ctr * CgroupControl ) (bool , error ) {
42+ if ctr .cgroup2 {
43+ return false , nil
2844 }
29- return man .Set (res )
45+ return ctr .createCgroupDirectory (Blkio )
46+ }
47+
48+ // Destroy the cgroup.
49+ func (c * linuxBlkioHandler ) Destroy (ctr * CgroupControl ) error {
50+ return rmDirRecursively (ctr .getCgroupv1Path (Blkio ))
3051}
3152
3253// Stat fills a metrics structure with usage stats for the controller.
3354func (c * linuxBlkioHandler ) Stat (ctr * CgroupControl , m * cgroups.Stats ) error {
3455 var ioServiceBytesRecursive []cgroups.BlkioStatEntry
3556
36- // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html
37- values , err := readCgroup2MapFile (ctr , "io.stat" )
38- if err != nil {
39- return err
40- }
41- for k , v := range values {
42- d := strings .Split (k , ":" )
43- if len (d ) != 2 {
44- continue
45- }
46- minor , err := strconv .ParseUint (d [0 ], 10 , 0 )
57+ if ctr .cgroup2 {
58+ // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html
59+ values , err := readCgroup2MapFile (ctr , "io.stat" )
4760 if err != nil {
4861 return err
4962 }
50- major , err := strconv .ParseUint (d [1 ], 10 , 0 )
63+ for k , v := range values {
64+ d := strings .Split (k , ":" )
65+ if len (d ) != 2 {
66+ continue
67+ }
68+ minor , err := strconv .ParseUint (d [0 ], 10 , 0 )
69+ if err != nil {
70+ return err
71+ }
72+ major , err := strconv .ParseUint (d [1 ], 10 , 0 )
73+ if err != nil {
74+ return err
75+ }
76+
77+ for _ , item := range v {
78+ d := strings .Split (item , "=" )
79+ if len (d ) != 2 {
80+ continue
81+ }
82+ op := d [0 ]
83+
84+ // Accommodate the cgroup v1 naming
85+ switch op {
86+ case "rbytes" :
87+ op = "read"
88+ case "wbytes" :
89+ op = "write"
90+ }
91+
92+ value , err := strconv .ParseUint (d [1 ], 10 , 0 )
93+ if err != nil {
94+ return err
95+ }
96+
97+ entry := cgroups.BlkioStatEntry {
98+ Op : op ,
99+ Major : major ,
100+ Minor : minor ,
101+ Value : value ,
102+ }
103+ ioServiceBytesRecursive = append (ioServiceBytesRecursive , entry )
104+ }
105+ }
106+ } else {
107+ BlkioRoot := ctr .getCgroupv1Path (Blkio )
108+
109+ p := filepath .Join (BlkioRoot , "blkio.throttle.io_service_bytes_recursive" )
110+ f , err := os .Open (p )
51111 if err != nil {
52- return err
112+ if errors .Is (err , os .ErrNotExist ) {
113+ return nil
114+ }
115+ return fmt .Errorf ("open %s: %w" , p , err )
53116 }
117+ defer f .Close ()
54118
55- for _ , item := range v {
56- d := strings .Split (item , "=" )
119+ scanner := bufio .NewScanner (f )
120+ for scanner .Scan () {
121+ line := scanner .Text ()
122+ parts := strings .Fields (line )
123+ if len (parts ) < 3 {
124+ continue
125+ }
126+ d := strings .Split (parts [0 ], ":" )
57127 if len (d ) != 2 {
58128 continue
59129 }
60- op := d [0 ]
61-
62- // Accommodate the cgroup v1 naming
63- switch op {
64- case "rbytes" :
65- op = "read"
66- case "wbytes" :
67- op = "write"
130+ minor , err := strconv .ParseUint (d [0 ], 10 , 0 )
131+ if err != nil {
132+ return err
68133 }
69-
70- value , err := strconv .ParseUint (d [1 ], 10 , 0 )
134+ major , err := strconv .ParseUint (d [1 ], 10 , 0 )
71135 if err != nil {
72136 return err
73137 }
74138
139+ op := parts [1 ]
140+
141+ value , err := strconv .ParseUint (parts [2 ], 10 , 0 )
142+ if err != nil {
143+ return err
144+ }
75145 entry := cgroups.BlkioStatEntry {
76146 Op : op ,
77147 Major : major ,
@@ -80,6 +150,9 @@ func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error {
80150 }
81151 ioServiceBytesRecursive = append (ioServiceBytesRecursive , entry )
82152 }
153+ if err := scanner .Err (); err != nil {
154+ return fmt .Errorf ("parse %s: %w" , p , err )
155+ }
83156 }
84157 m .BlkioStats .IoServiceBytesRecursive = ioServiceBytesRecursive
85158 return nil
0 commit comments