source: code/trunk/vendor/github.com/prometheus/procfs/proc_fdinfo.go@ 822

Last change on this file since 822 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 3.4 KB
Line 
1// Copyright 2019 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 procfs
15
16import (
17 "bufio"
18 "bytes"
19 "fmt"
20 "regexp"
21
22 "github.com/prometheus/procfs/internal/util"
23)
24
25var (
26 rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
27 rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
28 rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
29 rInotify = regexp.MustCompile(`^inotify`)
30 rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`)
31)
32
33// ProcFDInfo contains represents file descriptor information.
34type ProcFDInfo struct {
35 // File descriptor
36 FD string
37 // File offset
38 Pos string
39 // File access mode and status flags
40 Flags string
41 // Mount point ID
42 MntID string
43 // List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
44 InotifyInfos []InotifyInfo
45}
46
47// FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.
48func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
49 data, err := util.ReadFileNoStat(p.path("fdinfo", fd))
50 if err != nil {
51 return nil, err
52 }
53
54 var text, pos, flags, mntid string
55 var inotify []InotifyInfo
56
57 scanner := bufio.NewScanner(bytes.NewReader(data))
58 for scanner.Scan() {
59 text = scanner.Text()
60 if rPos.MatchString(text) {
61 pos = rPos.FindStringSubmatch(text)[1]
62 } else if rFlags.MatchString(text) {
63 flags = rFlags.FindStringSubmatch(text)[1]
64 } else if rMntID.MatchString(text) {
65 mntid = rMntID.FindStringSubmatch(text)[1]
66 } else if rInotify.MatchString(text) {
67 newInotify, err := parseInotifyInfo(text)
68 if err != nil {
69 return nil, err
70 }
71 inotify = append(inotify, *newInotify)
72 }
73 }
74
75 i := &ProcFDInfo{
76 FD: fd,
77 Pos: pos,
78 Flags: flags,
79 MntID: mntid,
80 InotifyInfos: inotify,
81 }
82
83 return i, nil
84}
85
86// InotifyInfo represents a single inotify line in the fdinfo file.
87type InotifyInfo struct {
88 // Watch descriptor number
89 WD string
90 // Inode number
91 Ino string
92 // Device ID
93 Sdev string
94 // Mask of events being monitored
95 Mask string
96}
97
98// InotifyInfo constructor. Only available on kernel 3.8+.
99func parseInotifyInfo(line string) (*InotifyInfo, error) {
100 m := rInotifyParts.FindStringSubmatch(line)
101 if len(m) >= 4 {
102 var mask string
103 if len(m) == 5 {
104 mask = m[4]
105 }
106 i := &InotifyInfo{
107 WD: m[1],
108 Ino: m[2],
109 Sdev: m[3],
110 Mask: mask,
111 }
112 return i, nil
113 }
114 return nil, fmt.Errorf("invalid inode entry: %q", line)
115}
116
117// ProcFDInfos represents a list of ProcFDInfo structs.
118type ProcFDInfos []ProcFDInfo
119
120func (p ProcFDInfos) Len() int { return len(p) }
121func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
122func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD }
123
124// InotifyWatchLen returns the total number of inotify watches.
125func (p ProcFDInfos) InotifyWatchLen() (int, error) {
126 length := 0
127 for _, f := range p {
128 length += len(f.InotifyInfos)
129 }
130
131 return length, nil
132}
Note: See TracBrowser for help on using the repository browser.