cubefs
151 строка · 3.5 Кб
1// Copyright 2020 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package procfs15
16import (17"bufio"18"bytes"19"fmt"20"regexp"21"strconv"22"strings"23
24"github.com/prometheus/procfs/internal/util"25)
26
27var (28slabSpace = regexp.MustCompile(`\s+`)29slabVer = regexp.MustCompile(`slabinfo -`)30slabHeader = regexp.MustCompile(`# name`)31)
32
33// Slab represents a slab pool in the kernel.
34type Slab struct {35Name string36ObjActive int6437ObjNum int6438ObjSize int6439ObjPerSlab int6440PagesPerSlab int6441// tunables42Limit int6443Batch int6444SharedFactor int6445SlabActive int6446SlabNum int6447SharedAvail int6448}
49
50// SlabInfo represents info for all slabs.
51type SlabInfo struct {52Slabs []*Slab53}
54
55func shouldParseSlab(line string) bool {56if slabVer.MatchString(line) {57return false58}59if slabHeader.MatchString(line) {60return false61}62return true63}
64
65// parseV21SlabEntry is used to parse a line from /proc/slabinfo version 2.1.
66func parseV21SlabEntry(line string) (*Slab, error) {67// First cleanup whitespace.68l := slabSpace.ReplaceAllString(line, " ")69s := strings.Split(l, " ")70if len(s) != 16 {71return nil, fmt.Errorf("unable to parse: %q", line)72}73var err error74i := &Slab{Name: s[0]}75i.ObjActive, err = strconv.ParseInt(s[1], 10, 64)76if err != nil {77return nil, err78}79i.ObjNum, err = strconv.ParseInt(s[2], 10, 64)80if err != nil {81return nil, err82}83i.ObjSize, err = strconv.ParseInt(s[3], 10, 64)84if err != nil {85return nil, err86}87i.ObjPerSlab, err = strconv.ParseInt(s[4], 10, 64)88if err != nil {89return nil, err90}91i.PagesPerSlab, err = strconv.ParseInt(s[5], 10, 64)92if err != nil {93return nil, err94}95i.Limit, err = strconv.ParseInt(s[8], 10, 64)96if err != nil {97return nil, err98}99i.Batch, err = strconv.ParseInt(s[9], 10, 64)100if err != nil {101return nil, err102}103i.SharedFactor, err = strconv.ParseInt(s[10], 10, 64)104if err != nil {105return nil, err106}107i.SlabActive, err = strconv.ParseInt(s[13], 10, 64)108if err != nil {109return nil, err110}111i.SlabNum, err = strconv.ParseInt(s[14], 10, 64)112if err != nil {113return nil, err114}115i.SharedAvail, err = strconv.ParseInt(s[15], 10, 64)116if err != nil {117return nil, err118}119return i, nil120}
121
122// parseSlabInfo21 is used to parse a slabinfo 2.1 file.
123func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) {124scanner := bufio.NewScanner(r)125s := SlabInfo{Slabs: []*Slab{}}126for scanner.Scan() {127line := scanner.Text()128if !shouldParseSlab(line) {129continue130}131slab, err := parseV21SlabEntry(line)132if err != nil {133return s, err134}135s.Slabs = append(s.Slabs, slab)136}137return s, nil138}
139
140// SlabInfo reads data from `/proc/slabinfo`.
141func (fs FS) SlabInfo() (SlabInfo, error) {142// TODO: Consider passing options to allow for parsing different143// slabinfo versions. However, slabinfo 2.1 has been stable since144// kernel 2.6.10 and later.145data, err := util.ReadFileNoStat(fs.proc.Path("slabinfo"))146if err != nil {147return SlabInfo{}, err148}149
150return parseSlabInfo21(bytes.NewReader(data))151}
152