1
2
3
4
5
6
7
8
9
10
11
12
13
14 package procfs
15
16 import (
17 "bufio"
18 "bytes"
19 "fmt"
20 "regexp"
21 "strconv"
22 "strings"
23
24 "github.com/prometheus/procfs/internal/util"
25 )
26
27 var (
28 slabSpace = regexp.MustCompile(`\s+`)
29 slabVer = regexp.MustCompile(`slabinfo -`)
30 slabHeader = regexp.MustCompile(`# name`)
31 )
32
33
34 type Slab struct {
35 Name string
36 ObjActive int64
37 ObjNum int64
38 ObjSize int64
39 ObjPerSlab int64
40 PagesPerSlab int64
41
42 Limit int64
43 Batch int64
44 SharedFactor int64
45 SlabActive int64
46 SlabNum int64
47 SharedAvail int64
48 }
49
50
51 type SlabInfo struct {
52 Slabs []*Slab
53 }
54
55 func shouldParseSlab(line string) bool {
56 if slabVer.MatchString(line) {
57 return false
58 }
59 if slabHeader.MatchString(line) {
60 return false
61 }
62 return true
63 }
64
65
66 func parseV21SlabEntry(line string) (*Slab, error) {
67
68 l := slabSpace.ReplaceAllString(line, " ")
69 s := strings.Split(l, " ")
70 if len(s) != 16 {
71 return nil, fmt.Errorf("%w: unable to parse: %q", ErrFileParse, line)
72 }
73 var err error
74 i := &Slab{Name: s[0]}
75 i.ObjActive, err = strconv.ParseInt(s[1], 10, 64)
76 if err != nil {
77 return nil, err
78 }
79 i.ObjNum, err = strconv.ParseInt(s[2], 10, 64)
80 if err != nil {
81 return nil, err
82 }
83 i.ObjSize, err = strconv.ParseInt(s[3], 10, 64)
84 if err != nil {
85 return nil, err
86 }
87 i.ObjPerSlab, err = strconv.ParseInt(s[4], 10, 64)
88 if err != nil {
89 return nil, err
90 }
91 i.PagesPerSlab, err = strconv.ParseInt(s[5], 10, 64)
92 if err != nil {
93 return nil, err
94 }
95 i.Limit, err = strconv.ParseInt(s[8], 10, 64)
96 if err != nil {
97 return nil, err
98 }
99 i.Batch, err = strconv.ParseInt(s[9], 10, 64)
100 if err != nil {
101 return nil, err
102 }
103 i.SharedFactor, err = strconv.ParseInt(s[10], 10, 64)
104 if err != nil {
105 return nil, err
106 }
107 i.SlabActive, err = strconv.ParseInt(s[13], 10, 64)
108 if err != nil {
109 return nil, err
110 }
111 i.SlabNum, err = strconv.ParseInt(s[14], 10, 64)
112 if err != nil {
113 return nil, err
114 }
115 i.SharedAvail, err = strconv.ParseInt(s[15], 10, 64)
116 if err != nil {
117 return nil, err
118 }
119 return i, nil
120 }
121
122
123 func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) {
124 scanner := bufio.NewScanner(r)
125 s := SlabInfo{Slabs: []*Slab{}}
126 for scanner.Scan() {
127 line := scanner.Text()
128 if !shouldParseSlab(line) {
129 continue
130 }
131 slab, err := parseV21SlabEntry(line)
132 if err != nil {
133 return s, err
134 }
135 s.Slabs = append(s.Slabs, slab)
136 }
137 return s, nil
138 }
139
140
141 func (fs FS) SlabInfo() (SlabInfo, error) {
142
143
144
145 data, err := util.ReadFileNoStat(fs.proc.Path("slabinfo"))
146 if err != nil {
147 return SlabInfo{}, err
148 }
149
150 return parseSlabInfo21(bytes.NewReader(data))
151 }
152
View as plain text