Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / prometheus / procfs / buddyinfo.go
1 // Copyright 2017 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
14 package procfs
15
16 import (
17         "bufio"
18         "fmt"
19         "io"
20         "os"
21         "strconv"
22         "strings"
23 )
24
25 // A BuddyInfo is the details parsed from /proc/buddyinfo.
26 // The data is comprised of an array of free fragments of each size.
27 // The sizes are 2^n*PAGE_SIZE, where n is the array index.
28 type BuddyInfo struct {
29         Node  string
30         Zone  string
31         Sizes []float64
32 }
33
34 // NewBuddyInfo reads the buddyinfo statistics.
35 func NewBuddyInfo() ([]BuddyInfo, error) {
36         fs, err := NewFS(DefaultMountPoint)
37         if err != nil {
38                 return nil, err
39         }
40
41         return fs.NewBuddyInfo()
42 }
43
44 // NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
45 func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
46         file, err := os.Open(fs.Path("buddyinfo"))
47         if err != nil {
48                 return nil, err
49         }
50         defer file.Close()
51
52         return parseBuddyInfo(file)
53 }
54
55 func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
56         var (
57                 buddyInfo   = []BuddyInfo{}
58                 scanner     = bufio.NewScanner(r)
59                 bucketCount = -1
60         )
61
62         for scanner.Scan() {
63                 var err error
64                 line := scanner.Text()
65                 parts := strings.Fields(line)
66
67                 if len(parts) < 4 {
68                         return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
69                 }
70
71                 node := strings.TrimRight(parts[1], ",")
72                 zone := strings.TrimRight(parts[3], ",")
73                 arraySize := len(parts[4:])
74
75                 if bucketCount == -1 {
76                         bucketCount = arraySize
77                 } else {
78                         if bucketCount != arraySize {
79                                 return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize)
80                         }
81                 }
82
83                 sizes := make([]float64, arraySize)
84                 for i := 0; i < arraySize; i++ {
85                         sizes[i], err = strconv.ParseFloat(parts[i+4], 64)
86                         if err != nil {
87                                 return nil, fmt.Errorf("invalid value in buddyinfo: %s", err)
88                         }
89                 }
90
91                 buddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes})
92         }
93
94         return buddyInfo, scanner.Err()
95 }