cubefs
132 строки · 3.4 Кб
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 procfs15
16import (17"bufio"18"bytes"19"fmt"20"regexp"21
22"github.com/prometheus/procfs/internal/util"23)
24
25var (26rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)27rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)28rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)29rInotify = regexp.MustCompile(`^inotify`)30rInotifyParts = 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 descriptor36FD string37// File offset38Pos string39// File access mode and status flags40Flags string41// Mount point ID42MntID string43// List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)44InotifyInfos []InotifyInfo45}
46
47// FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.
48func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {49data, err := util.ReadFileNoStat(p.path("fdinfo", fd))50if err != nil {51return nil, err52}53
54var text, pos, flags, mntid string55var inotify []InotifyInfo56
57scanner := bufio.NewScanner(bytes.NewReader(data))58for scanner.Scan() {59text = scanner.Text()60if rPos.MatchString(text) {61pos = rPos.FindStringSubmatch(text)[1]62} else if rFlags.MatchString(text) {63flags = rFlags.FindStringSubmatch(text)[1]64} else if rMntID.MatchString(text) {65mntid = rMntID.FindStringSubmatch(text)[1]66} else if rInotify.MatchString(text) {67newInotify, err := parseInotifyInfo(text)68if err != nil {69return nil, err70}71inotify = append(inotify, *newInotify)72}73}74
75i := &ProcFDInfo{76FD: fd,77Pos: pos,78Flags: flags,79MntID: mntid,80InotifyInfos: inotify,81}82
83return i, nil84}
85
86// InotifyInfo represents a single inotify line in the fdinfo file.
87type InotifyInfo struct {88// Watch descriptor number89WD string90// Inode number91Ino string92// Device ID93Sdev string94// Mask of events being monitored95Mask string96}
97
98// InotifyInfo constructor. Only available on kernel 3.8+.
99func parseInotifyInfo(line string) (*InotifyInfo, error) {100m := rInotifyParts.FindStringSubmatch(line)101if len(m) >= 4 {102var mask string103if len(m) == 5 {104mask = m[4]105}106i := &InotifyInfo{107WD: m[1],108Ino: m[2],109Sdev: m[3],110Mask: mask,111}112return i, nil113}114return nil, fmt.Errorf("invalid inode entry: %q", line)115}
116
117// ProcFDInfos represents a list of ProcFDInfo structs.
118type ProcFDInfos []ProcFDInfo119
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) {126length := 0127for _, f := range p {128length += len(f.InotifyInfos)129}130
131return length, nil132}
133