| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- package node
- import (
- "os"
- "path"
- "regexp"
- "strconv"
- "strings"
- "k8s.io/klog/v2"
- )
- var blockDevice = regexp.MustCompile(`^(dm-\d+|(s|h|xv|v)d[a-z]|md\d+|nvme\d+n\d+|rbd\d+)`)
- type DevStat struct {
- Name string
- MajorMinor string
- ReadOps float64
- WriteOps float64
- BytesRead float64
- BytesWritten float64
- ReadTimeSeconds float64
- WriteTimeSeconds float64
- IoTimeSeconds float64
- }
- type Disks struct {
- byMajorMinor map[string]DevStat
- }
- func (disks *Disks) BlockDevices() []DevStat {
- var res []DevStat
- for _, d := range disks.byMajorMinor {
- groups := blockDevice.FindStringSubmatch(d.Name)
- if len(groups) < 2 {
- continue
- }
- if groups[1] == d.Name {
- res = append(res, d)
- }
- }
- return res
- }
- func (disks *Disks) GetParentBlockDevice(majorMinor string) *DevStat {
- dev, ok := disks.byMajorMinor[majorMinor]
- if !ok {
- return nil
- }
- groups := blockDevice.FindStringSubmatch(dev.Name)
- if len(groups) < 2 {
- return nil
- }
- parentName := groups[1]
- for _, d := range disks.byMajorMinor {
- if d.Name == parentName {
- return &d
- }
- }
- return nil
- }
- func GetDisks() (*Disks, error) {
- data, err := os.ReadFile(path.Join(procRoot, "diskstats"))
- if err != nil {
- return nil, err
- }
- disks := &Disks{
- byMajorMinor: map[string]DevStat{},
- }
- for _, line := range strings.Split(string(data), "\n") {
- fields := strings.Fields(line)
- if len(fields) < 14 {
- continue
- }
- deviceName := fields[2]
- values, err := parseFloats(fields[3:])
- if err != nil {
- klog.Warningf(`invalid diskstats line "%s": %s`, line, err)
- continue
- }
- majorMinor := fields[0] + ":" + fields[1]
- disks.byMajorMinor[majorMinor] = DevStat{
- Name: deviceName,
- MajorMinor: majorMinor,
- ReadOps: values[0],
- BytesRead: values[2] * 512,
- ReadTimeSeconds: values[3] / 1000,
- WriteOps: values[4],
- BytesWritten: values[6] * 512,
- WriteTimeSeconds: values[7] / 1000,
- IoTimeSeconds: values[9] / 1000,
- }
- }
- return disks, nil
- }
- func parseFloats(input []string) ([]float64, error) {
- res := make([]float64, len(input))
- for i, strValue := range input {
- v, err := strconv.ParseFloat(strValue, 64)
- if err != nil {
- return nil, err
- }
- res[i] = v
- }
- return res, nil
- }
|