Update procfs library (#1640)

Bump procfs to latest release.

Fixes: https://github.com/prometheus/node_exporter/issues/1625
Fixes: https://github.com/prometheus/node_exporter/issues/1634

Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
Ben Kochie 2020-03-19 19:51:20 +01:00 committed by GitHub
parent e49a13d0cf
commit 47610d0d2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 345 additions and 64 deletions

2
go.mod
View file

@ -18,7 +18,7 @@ require (
github.com/prometheus/client_golang v1.4.1 github.com/prometheus/client_golang v1.4.1
github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model v0.2.0
github.com/prometheus/common v0.9.1 github.com/prometheus/common v0.9.1
github.com/prometheus/procfs v0.0.10 github.com/prometheus/procfs v0.0.11
github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745 github.com/siebenmann/go-kstat v0.0.0-20160321171754-d34789b79745
github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a
go.uber.org/atomic v1.5.1 // indirect go.uber.org/atomic v1.5.1 // indirect

5
go.sum
View file

@ -275,8 +275,8 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.0.10 h1:QJQN3jYQhkamO4mhfUWqdDH2asK7ONOI9MTWjyAxNKM= github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -405,6 +405,7 @@ golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU= golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw= golang.org/x/sys v0.0.0-20200217220822-9197077df867 h1:JoRuNIf+rpHl+VhScRQQvzbHed86tKkqwPMV34T8myw=

View file

@ -1,4 +1,4 @@
---
linters: linters:
enable: enable:
- staticcheck - golint
- govet

View file

@ -69,6 +69,15 @@ else
GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH) GO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)
endif endif
GOTEST := $(GO) test
GOTEST_DIR :=
ifneq ($(CIRCLE_JOB),)
ifneq ($(shell which gotestsum),)
GOTEST_DIR := test-results
GOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --
endif
endif
PROMU_VERSION ?= 0.5.0 PROMU_VERSION ?= 0.5.0
PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz
@ -142,14 +151,17 @@ else
endif endif
.PHONY: common-test-short .PHONY: common-test-short
common-test-short: common-test-short: $(GOTEST_DIR)
@echo ">> running short tests" @echo ">> running short tests"
GO111MODULE=$(GO111MODULE) $(GO) test -short $(GOOPTS) $(pkgs) GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs)
.PHONY: common-test .PHONY: common-test
common-test: common-test: $(GOTEST_DIR)
@echo ">> running all tests" @echo ">> running all tests"
GO111MODULE=$(GO111MODULE) $(GO) test $(test-flags) $(GOOPTS) $(pkgs) GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)
$(GOTEST_DIR):
@mkdir -p $@
.PHONY: common-format .PHONY: common-format
common-format: common-format:

View file

@ -29,7 +29,7 @@ type Stats struct {
} }
// BcacheStats contains statistics tied to a bcache ID. // BcacheStats contains statistics tied to a bcache ID.
type BcacheStats struct { type BcacheStats struct { // nolint:golint
AverageKeySize uint64 AverageKeySize uint64
BtreeCacheSize uint64 BtreeCacheSize uint64
CacheAvailablePercent uint64 CacheAvailablePercent uint64

View file

@ -51,8 +51,21 @@ func NewFS(mountPoint string) (FS, error) {
return FS{&fs}, nil return FS{&fs}, nil
} }
// Stats retrieves bcache runtime statistics for each bcache. // Stats is a wrapper around stats()
// It returns full available statistics
func (fs FS) Stats() ([]*Stats, error) { func (fs FS) Stats() ([]*Stats, error) {
return fs.stats(true)
}
// StatsWithoutPriority is a wrapper around stats().
// It ignores priority_stats file, because it is expensive to read.
func (fs FS) StatsWithoutPriority() ([]*Stats, error) {
return fs.stats(false)
}
// stats() retrieves bcache runtime statistics for each bcache.
// priorityStats flag controls if we need to read priority_stats.
func (fs FS) stats(priorityStats bool) ([]*Stats, error) {
matches, err := filepath.Glob(fs.sys.Path("fs/bcache/*-*")) matches, err := filepath.Glob(fs.sys.Path("fs/bcache/*-*"))
if err != nil { if err != nil {
return nil, err return nil, err
@ -64,7 +77,7 @@ func (fs FS) Stats() ([]*Stats, error) {
name := filepath.Base(uuidPath) name := filepath.Base(uuidPath)
// stats // stats
s, err := GetStats(uuidPath) s, err := GetStats(uuidPath, priorityStats)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -251,7 +264,7 @@ func (p *parser) getPriorityStats() PriorityStats {
} }
// GetStats collects from sysfs files data tied to one bcache ID. // GetStats collects from sysfs files data tied to one bcache ID.
func GetStats(uuidPath string) (*Stats, error) { func GetStats(uuidPath string, priorityStats bool) (*Stats, error) {
var bs Stats var bs Stats
par := parser{uuidPath: uuidPath} par := parser{uuidPath: uuidPath}
@ -370,8 +383,10 @@ func GetStats(uuidPath string) (*Stats, error) {
cs.MetadataWritten = par.readValue("metadata_written") cs.MetadataWritten = par.readValue("metadata_written")
cs.Written = par.readValue("written") cs.Written = par.readValue("written")
ps := par.getPriorityStats() if priorityStats {
cs.Priority = ps ps := par.getPriorityStats()
cs.Priority = ps
}
} }
if par.err != nil { if par.err != nil {

View file

@ -289,6 +289,19 @@ Max realtime priority 0 0
Max realtime timeout unlimited unlimited us Max realtime timeout unlimited unlimited us
Mode: 644 Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26232/maps
Lines: 9
55680ae1e000-55680ae20000 r--p 00000000 fd:01 47316994 /bin/cat
55680ae29000-55680ae2a000 rwxs 0000a000 fd:01 47316994 /bin/cat
55680bed6000-55680bef7000 rw-p 00000000 00:00 0 [heap]
7fdf964fc000-7fdf973f2000 r--p 00000000 fd:01 17432624 /usr/lib/locale/locale-archive
7fdf973f2000-7fdf97417000 r--p 00000000 fd:01 60571062 /lib/x86_64-linux-gnu/libc-2.29.so
7ffe9215c000-7ffe9217f000 rw-p 00000000 00:00 0 [stack]
7ffe921da000-7ffe921dd000 r--p 00000000 00:00 0 [vvar]
7ffe921dd000-7ffe921de000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26232/root Path: fixtures/proc/26232/root
SymlinkTo: /does/not/exist SymlinkTo: /does/not/exist
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -317,6 +330,17 @@ Lines: 8
|| || || ||
Mode: 644 Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/26234
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/26234/maps
Lines: 4
08048000-08089000 r-xp 00000000 03:01 104219 /bin/tcsh
08089000-0808c000 rw-p 00041000 03:01 104219 /bin/tcsh
0808c000-08146000 rwxp 00000000 00:00 0
40000000-40015000 r-xp 00000000 03:01 61874 /lib/ld-2.3.2.so
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/proc/584 Directory: fixtures/proc/584
Mode: 755 Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1527,11 +1551,6 @@ blocksize : 16
min keysize : 16 min keysize : 16
max keysize : 32 max keysize : 32
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/loadavg
Lines: 1
0.02 0.04 0.05 1/497 11947
Mode: 444 Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/diskstats Path: fixtures/proc/diskstats
@ -1620,6 +1639,11 @@ xpc 399724544 92823103 86219234
debug 0 debug 0
Mode: 644 Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/loadavg
Lines: 1
0.02 0.04 0.05 1/497 11947
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/mdstat Path: fixtures/proc/mdstat
Lines: 56 Lines: 56
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
@ -1827,8 +1851,14 @@ FRAG6: inuse 0 memory 0
Mode: 444 Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat Path: fixtures/proc/net/softnet_stat
Lines: 1 Lines: 2
00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00000000
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat.broken
Lines: 1
00015c73 00020e76 F0000769 00000000
Mode: 644 Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/udp Path: fixtures/proc/net/udp

View file

@ -5,4 +5,5 @@ go 1.12
require ( require (
github.com/google/go-cmp v0.3.1 github.com/google/go-cmp v0.3.1
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e
) )

View file

@ -2,3 +2,5 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e h1:LwyF2AFISC9nVbS6MgzsaQNSUsRXI49GS+YQ5KX/QH0=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View file

@ -29,10 +29,10 @@ import (
// is described in the following man page. // is described in the following man page.
// http://man7.org/linux/man-pages/man5/proc.5.html // http://man7.org/linux/man-pages/man5/proc.5.html
type MountInfo struct { type MountInfo struct {
// Unique Id for the mount // Unique ID for the mount
MountId int MountID int
// The Id of the parent mount // The ID of the parent mount
ParentId int ParentID int
// The value of `st_dev` for the files on this FS // The value of `st_dev` for the files on this FS
MajorMinorVer string MajorMinorVer string
// The pathname of the directory in the FS that forms // The pathname of the directory in the FS that forms
@ -96,11 +96,11 @@ func parseMountInfoString(mountString string) (*MountInfo, error) {
SuperOptions: mountOptionsParser(mountInfo[mountInfoLength-1]), SuperOptions: mountOptionsParser(mountInfo[mountInfoLength-1]),
} }
mount.MountId, err = strconv.Atoi(mountInfo[0]) mount.MountID, err = strconv.Atoi(mountInfo[0])
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse mount ID") return nil, fmt.Errorf("failed to parse mount ID")
} }
mount.ParentId, err = strconv.Atoi(mountInfo[1]) mount.ParentID, err = strconv.Atoi(mountInfo[1])
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse parent ID") return nil, fmt.Errorf("failed to parse parent ID")
} }

View file

@ -25,7 +25,9 @@ import (
) )
// For the proc file format details, // For the proc file format details,
// see https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 // See:
// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343
// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. // and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810.
// SoftnetStat contains a single row of data from /proc/net/softnet_stat // SoftnetStat contains a single row of data from /proc/net/softnet_stat
@ -38,9 +40,11 @@ type SoftnetStat struct {
TimeSqueezed uint32 TimeSqueezed uint32
} }
var softNetProcFile = "net/softnet_stat"
// NetSoftnetStat reads data from /proc/net/softnet_stat. // NetSoftnetStat reads data from /proc/net/softnet_stat.
func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) { func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {
b, err := util.ReadFileNoStat(fs.proc.Path("net/softnet_stat")) b, err := util.ReadFileNoStat(fs.proc.Path(softNetProcFile))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -54,7 +58,7 @@ func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {
} }
func parseSoftnet(r io.Reader) ([]SoftnetStat, error) { func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
const expectedColumns = 11 const minColumns = 9
s := bufio.NewScanner(r) s := bufio.NewScanner(r)
@ -63,8 +67,8 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
columns := strings.Fields(s.Text()) columns := strings.Fields(s.Text())
width := len(columns) width := len(columns)
if width != 11 { if width < minColumns {
return nil, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedColumns) return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns)
} }
// We only parse the first three columns at the moment. // We only parse the first three columns at the moment.

View file

@ -16,6 +16,7 @@ package procfs
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"errors"
"regexp" "regexp"
"github.com/prometheus/procfs/internal/util" "github.com/prometheus/procfs/internal/util"
@ -23,10 +24,11 @@ import (
// Regexp variables // Regexp variables
var ( var (
rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`) rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
rInotify = regexp.MustCompile(`^inotify`) rInotify = regexp.MustCompile(`^inotify`)
rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`)
) )
// ProcFDInfo contains represents file descriptor information. // ProcFDInfo contains represents file descriptor information.
@ -96,15 +98,21 @@ type InotifyInfo struct {
// InotifyInfo constructor. Only available on kernel 3.8+. // InotifyInfo constructor. Only available on kernel 3.8+.
func parseInotifyInfo(line string) (*InotifyInfo, error) { func parseInotifyInfo(line string) (*InotifyInfo, error) {
r := regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)\s+mask:([0-9a-f]+)`) m := rInotifyParts.FindStringSubmatch(line)
m := r.FindStringSubmatch(line) if len(m) >= 4 {
i := &InotifyInfo{ var mask string
WD: m[1], if len(m) == 5 {
Ino: m[2], mask = m[4]
Sdev: m[3], }
Mask: m[4], i := &InotifyInfo{
WD: m[1],
Ino: m[2],
Sdev: m[3],
Mask: mask,
}
return i, nil
} }
return i, nil return nil, errors.New("invalid inode entry: " + line)
} }
// ProcFDInfos represents a list of ProcFDInfo structs. // ProcFDInfos represents a list of ProcFDInfo structs.

208
vendor/github.com/prometheus/procfs/proc_maps.go generated vendored Normal file
View file

@ -0,0 +1,208 @@
// Copyright 2019 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !windows
package procfs
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"golang.org/x/sys/unix"
)
type ProcMapPermissions struct {
// mapping has the [R]ead flag set
Read bool
// mapping has the [W]rite flag set
Write bool
// mapping has the [X]ecutable flag set
Execute bool
// mapping has the [S]hared flag set
Shared bool
// mapping is marked as [P]rivate (copy on write)
Private bool
}
// ProcMap contains the process memory-mappings of the process,
// read from /proc/[pid]/maps
type ProcMap struct {
// The start address of current mapping.
StartAddr uintptr
// The end address of the current mapping
EndAddr uintptr
// The permissions for this mapping
Perms *ProcMapPermissions
// The current offset into the file/fd (e.g., shared libs)
Offset int64
// Device owner of this mapping (major:minor) in Mkdev format.
Dev uint64
// The inode of the device above
Inode uint64
// The file or psuedofile (or empty==anonymous)
Pathname string
}
// parseDevice parses the device token of a line and converts it to a dev_t
// (mkdev) like structure.
func parseDevice(s string) (uint64, error) {
toks := strings.Split(s, ":")
if len(toks) < 2 {
return 0, fmt.Errorf("unexpected number of fields")
}
major, err := strconv.ParseUint(toks[0], 16, 0)
if err != nil {
return 0, err
}
minor, err := strconv.ParseUint(toks[1], 16, 0)
if err != nil {
return 0, err
}
return unix.Mkdev(uint32(major), uint32(minor)), nil
}
// parseAddress just converts a hex-string to a uintptr
func parseAddress(s string) (uintptr, error) {
a, err := strconv.ParseUint(s, 16, 0)
if err != nil {
return 0, err
}
return uintptr(a), nil
}
// parseAddresses parses the start-end address
func parseAddresses(s string) (uintptr, uintptr, error) {
toks := strings.Split(s, "-")
if len(toks) < 2 {
return 0, 0, fmt.Errorf("invalid address")
}
saddr, err := parseAddress(toks[0])
if err != nil {
return 0, 0, err
}
eaddr, err := parseAddress(toks[1])
if err != nil {
return 0, 0, err
}
return saddr, eaddr, nil
}
// parsePermissions parses a token and returns any that are set.
func parsePermissions(s string) (*ProcMapPermissions, error) {
if len(s) < 4 {
return nil, fmt.Errorf("invalid permissions token")
}
perms := ProcMapPermissions{}
for _, ch := range s {
switch ch {
case 'r':
perms.Read = true
case 'w':
perms.Write = true
case 'x':
perms.Execute = true
case 'p':
perms.Private = true
case 's':
perms.Shared = true
}
}
return &perms, nil
}
// parseProcMap will attempt to parse a single line within a proc/[pid]/maps
// buffer.
func parseProcMap(text string) (*ProcMap, error) {
fields := strings.Fields(text)
if len(fields) < 5 {
return nil, fmt.Errorf("truncated procmap entry")
}
saddr, eaddr, err := parseAddresses(fields[0])
if err != nil {
return nil, err
}
perms, err := parsePermissions(fields[1])
if err != nil {
return nil, err
}
offset, err := strconv.ParseInt(fields[2], 16, 0)
if err != nil {
return nil, err
}
device, err := parseDevice(fields[3])
if err != nil {
return nil, err
}
inode, err := strconv.ParseUint(fields[4], 10, 0)
if err != nil {
return nil, err
}
pathname := ""
if len(fields) >= 5 {
pathname = strings.Join(fields[5:], " ")
}
return &ProcMap{
StartAddr: saddr,
EndAddr: eaddr,
Perms: perms,
Offset: offset,
Dev: device,
Inode: inode,
Pathname: pathname,
}, nil
}
// ProcMaps reads from /proc/[pid]/maps to get the memory-mappings of the
// process.
func (p Proc) ProcMaps() ([]*ProcMap, error) {
file, err := os.Open(p.path("maps"))
if err != nil {
return nil, err
}
defer file.Close()
maps := []*ProcMap{}
scan := bufio.NewScanner(file)
for scan.Scan() {
m, err := parseProcMap(scan.Text())
if err != nil {
return nil, err
}
maps = append(maps, m)
}
return maps, nil
}

View file

@ -33,37 +33,37 @@ type ProcStatus struct {
TGID int TGID int
// Peak virtual memory size. // Peak virtual memory size.
VmPeak uint64 VmPeak uint64 // nolint:golint
// Virtual memory size. // Virtual memory size.
VmSize uint64 VmSize uint64 // nolint:golint
// Locked memory size. // Locked memory size.
VmLck uint64 VmLck uint64 // nolint:golint
// Pinned memory size. // Pinned memory size.
VmPin uint64 VmPin uint64 // nolint:golint
// Peak resident set size. // Peak resident set size.
VmHWM uint64 VmHWM uint64 // nolint:golint
// Resident set size (sum of RssAnnon RssFile and RssShmem). // Resident set size (sum of RssAnnon RssFile and RssShmem).
VmRSS uint64 VmRSS uint64 // nolint:golint
// Size of resident anonymous memory. // Size of resident anonymous memory.
RssAnon uint64 RssAnon uint64 // nolint:golint
// Size of resident file mappings. // Size of resident file mappings.
RssFile uint64 RssFile uint64 // nolint:golint
// Size of resident shared memory. // Size of resident shared memory.
RssShmem uint64 RssShmem uint64 // nolint:golint
// Size of data segments. // Size of data segments.
VmData uint64 VmData uint64 // nolint:golint
// Size of stack segments. // Size of stack segments.
VmStk uint64 VmStk uint64 // nolint:golint
// Size of text segments. // Size of text segments.
VmExe uint64 VmExe uint64 // nolint:golint
// Shared library code size. // Shared library code size.
VmLib uint64 VmLib uint64 // nolint:golint
// Page table entries size. // Page table entries size.
VmPTE uint64 VmPTE uint64 // nolint:golint
// Size of second-level page tables. // Size of second-level page tables.
VmPMD uint64 VmPMD uint64 // nolint:golint
// Swapped-out virtual memory size by anonymous private. // Swapped-out virtual memory size by anonymous private.
VmSwap uint64 VmSwap uint64 // nolint:golint
// Size of hugetlb memory portions // Size of hugetlb memory portions
HugetlbPages uint64 HugetlbPages uint64

View file

@ -251,7 +251,7 @@ func parseInfiniBandCounters(portPath string) (*InfiniBandCounters, error) {
name := filepath.Join(path, f.Name()) name := filepath.Join(path, f.Name())
value, err := util.SysReadFile(name) value, err := util.SysReadFile(name)
if err != nil { if err != nil {
if os.IsNotExist(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" { if os.IsNotExist(err) || os.IsPermission(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" {
continue continue
} }
return nil, fmt.Errorf("failed to read file %q: %v", name, err) return nil, fmt.Errorf("failed to read file %q: %v", name, err)
@ -334,7 +334,7 @@ func parseInfiniBandCounters(portPath string) (*InfiniBandCounters, error) {
name := filepath.Join(path, f.Name()) name := filepath.Join(path, f.Name())
value, err := util.SysReadFile(name) value, err := util.SysReadFile(name)
if err != nil { if err != nil {
if os.IsNotExist(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" { if os.IsNotExist(err) || os.IsPermission(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" {
continue continue
} }
return nil, fmt.Errorf("failed to read file %q: %v", name, err) return nil, fmt.Errorf("failed to read file %q: %v", name, err)

View file

@ -119,7 +119,7 @@ func (nc NetClass) parseNetClassIface(devicePath string) (*NetClassIface, error)
name := filepath.Join(devicePath, f.Name()) name := filepath.Join(devicePath, f.Name())
value, err := util.SysReadFile(name) value, err := util.SysReadFile(name)
if err != nil { if err != nil {
if os.IsNotExist(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" { if os.IsNotExist(err) || os.IsPermission(err) || err.Error() == "operation not supported" || err.Error() == "invalid argument" {
continue continue
} }
return nil, fmt.Errorf("failed to read file %q: %v", name, err) return nil, fmt.Errorf("failed to read file %q: %v", name, err)

2
vendor/modules.txt vendored
View file

@ -59,7 +59,7 @@ github.com/prometheus/common/model
github.com/prometheus/common/promlog github.com/prometheus/common/promlog
github.com/prometheus/common/promlog/flag github.com/prometheus/common/promlog/flag
github.com/prometheus/common/version github.com/prometheus/common/version
# github.com/prometheus/procfs v0.0.10 # github.com/prometheus/procfs v0.0.11
github.com/prometheus/procfs github.com/prometheus/procfs
github.com/prometheus/procfs/bcache github.com/prometheus/procfs/bcache
github.com/prometheus/procfs/btrfs github.com/prometheus/procfs/btrfs