diff options
Diffstat (limited to 'pkg/cgroups/blkio.go')
-rw-r--r-- | pkg/cgroups/blkio.go | 134 |
1 files changed, 91 insertions, 43 deletions
diff --git a/pkg/cgroups/blkio.go b/pkg/cgroups/blkio.go index 8eb54abec..ca9107d97 100644 --- a/pkg/cgroups/blkio.go +++ b/pkg/cgroups/blkio.go @@ -9,6 +9,7 @@ import ( "strings" spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/pkg/errors" ) type blkioHandler struct { @@ -29,7 +30,7 @@ func (c *blkioHandler) Apply(ctr *CgroupControl, res *spec.LinuxResources) error // Create the cgroup func (c *blkioHandler) Create(ctr *CgroupControl) (bool, error) { if ctr.cgroup2 { - return false, fmt.Errorf("function not implemented yet") + return false, fmt.Errorf("io create not implemented for cgroup v2") } return ctr.createCgroupDirectory(Blkio) } @@ -44,57 +45,104 @@ func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error { var ioServiceBytesRecursive []BlkIOEntry if ctr.cgroup2 { - return fmt.Errorf("function not implemented yet") - } - - BlkioRoot := ctr.getCgroupv1Path(Blkio) - - p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") - f, err := os.Open(p) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - if len(parts) < 3 { - continue - } - d := strings.Split(parts[0], ":") - if len(d) != 2 { - continue - } - minor, err := strconv.ParseUint(d[0], 10, 0) + // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html + values, err := readCgroup2MapFile(ctr, "io.stat") if err != nil { return err } - major, err := strconv.ParseUint(d[1], 10, 0) + for k, v := range values { + d := strings.Split(k, ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) + if err != nil { + return err + } + major, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } + + for _, item := range v { + d := strings.Split(item, "=") + if len(d) != 2 { + continue + } + op := d[0] + + // Accommodate the cgroup v1 naming + switch op { + case "rbytes": + op = "read" + case "wbytes": + op = "write" + } + + value, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } + + entry := BlkIOEntry{ + Op: op, + Major: major, + Minor: minor, + Value: value, + } + ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) + } + } + } else { + BlkioRoot := ctr.getCgroupv1Path(Blkio) + + p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") + f, err := os.Open(p) if err != nil { - return err + if os.IsNotExist(err) { + return nil + } + return errors.Wrapf(err, "open %s", p) } + defer f.Close() - op := parts[1] + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + parts := strings.Fields(line) + if len(parts) < 3 { + continue + } + d := strings.Split(parts[0], ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) + if err != nil { + return err + } + major, err := strconv.ParseUint(d[1], 10, 0) + if err != nil { + return err + } - value, err := strconv.ParseUint(parts[2], 10, 0) - if err != nil { - return err + op := parts[1] + + value, err := strconv.ParseUint(parts[2], 10, 0) + if err != nil { + return err + } + entry := BlkIOEntry{ + Op: op, + Major: major, + Minor: minor, + Value: value, + } + ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } - entry := BlkIOEntry{ - Op: op, - Major: major, - Minor: minor, - Value: value, + if err := scanner.Err(); err != nil { + return errors.Wrapf(err, "parse %s", p) } - ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) - } - if err := scanner.Err(); err != nil { - return err } m.Blkio = BlkioMetrics{IoServiceBytesRecursive: ioServiceBytesRecursive} return nil |