From 2a76a6cf2cb90332521ca3e41b28df1efa9f7d98 Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Fri, 26 Feb 2021 07:50:49 -0500 Subject: [PATCH 01/31] Exclude freebsd from class_thermal Signed-off-by: Robert Fratto --- sysfs/class_thermal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysfs/class_thermal.go b/sysfs/class_thermal.go index 493a53129..71144d4c7 100644 --- a/sysfs/class_thermal.go +++ b/sysfs/class_thermal.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build !windows,!freebsd package sysfs From 6df3a34ff951e769a1f542490c0e86dab3c2c1ea Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Fri, 26 Feb 2021 08:11:43 -0500 Subject: [PATCH 02/31] Use Linux only build tags in sysfs Signed-off-by: Robert Fratto --- sysfs/class_cooling_device.go | 2 +- sysfs/class_cooling_device_test.go | 2 +- sysfs/class_fibrechannel.go | 2 +- sysfs/class_fibrechannel_test.go | 2 +- sysfs/class_infiniband.go | 2 +- sysfs/class_infiniband_test.go | 2 +- sysfs/class_power_supply.go | 2 +- sysfs/class_power_supply_test.go | 2 +- sysfs/class_powercap.go | 2 +- sysfs/class_powercap_test.go | 2 +- sysfs/class_thermal.go | 2 +- sysfs/class_thermal_test.go | 2 +- sysfs/clocksource.go | 2 +- sysfs/clocksource_test.go | 2 +- sysfs/net_class.go | 2 +- sysfs/net_class_test.go | 2 +- sysfs/system_cpu.go | 2 +- sysfs/system_cpu_test.go | 2 +- sysfs/vmstat_numa.go | 2 ++ sysfs/vmstat_numa_test.go | 2 ++ sysfs/vulnerability.go | 2 ++ 21 files changed, 24 insertions(+), 18 deletions(-) diff --git a/sysfs/class_cooling_device.go b/sysfs/class_cooling_device.go index 8927b02ac..a67067f84 100644 --- a/sysfs/class_cooling_device.go +++ b/sysfs/class_cooling_device.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_cooling_device_test.go b/sysfs/class_cooling_device_test.go index a94a12cc5..7555d38b6 100644 --- a/sysfs/class_cooling_device_test.go +++ b/sysfs/class_cooling_device_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_fibrechannel.go b/sysfs/class_fibrechannel.go index fec80046f..96584e74e 100644 --- a/sysfs/class_fibrechannel.go +++ b/sysfs/class_fibrechannel.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_fibrechannel_test.go b/sysfs/class_fibrechannel_test.go index 09ddc8dcf..569371845 100644 --- a/sysfs/class_fibrechannel_test.go +++ b/sysfs/class_fibrechannel_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_infiniband.go b/sysfs/class_infiniband.go index 80c3fcdc5..cb71824f2 100644 --- a/sysfs/class_infiniband.go +++ b/sysfs/class_infiniband.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_infiniband_test.go b/sysfs/class_infiniband_test.go index 5c04dd5c1..dd377a63c 100644 --- a/sysfs/class_infiniband_test.go +++ b/sysfs/class_infiniband_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_power_supply.go b/sysfs/class_power_supply.go index d6f2e2025..4ca816592 100644 --- a/sysfs/class_power_supply.go +++ b/sysfs/class_power_supply.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_power_supply_test.go b/sysfs/class_power_supply_test.go index cd66fc40c..a83e595f4 100644 --- a/sysfs/class_power_supply_test.go +++ b/sysfs/class_power_supply_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_powercap.go b/sysfs/class_powercap.go index 6f107255b..208e80907 100644 --- a/sysfs/class_powercap.go +++ b/sysfs/class_powercap.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_powercap_test.go b/sysfs/class_powercap_test.go index 66437096d..c78d1c5ef 100644 --- a/sysfs/class_powercap_test.go +++ b/sysfs/class_powercap_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/class_thermal.go b/sysfs/class_thermal.go index 71144d4c7..6b4823e9b 100644 --- a/sysfs/class_thermal.go +++ b/sysfs/class_thermal.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows,!freebsd +// +build linux package sysfs diff --git a/sysfs/class_thermal_test.go b/sysfs/class_thermal_test.go index 94af8ae96..0bce736f1 100644 --- a/sysfs/class_thermal_test.go +++ b/sysfs/class_thermal_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/clocksource.go b/sysfs/clocksource.go index d96c3892f..b857f750d 100644 --- a/sysfs/clocksource.go +++ b/sysfs/clocksource.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/clocksource_test.go b/sysfs/clocksource_test.go index 4fb0e9827..7c38d4b5f 100644 --- a/sysfs/clocksource_test.go +++ b/sysfs/clocksource_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/net_class.go b/sysfs/net_class.go index d840a520d..e6e223984 100644 --- a/sysfs/net_class.go +++ b/sysfs/net_class.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/net_class_test.go b/sysfs/net_class_test.go index 41963db32..bc219f340 100644 --- a/sysfs/net_class_test.go +++ b/sysfs/net_class_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/system_cpu.go b/sysfs/system_cpu.go index ddb9ebfe3..a4e616765 100644 --- a/sysfs/system_cpu.go +++ b/sysfs/system_cpu.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/system_cpu_test.go b/sysfs/system_cpu_test.go index eb6ab7a5d..522b58b56 100644 --- a/sysfs/system_cpu_test.go +++ b/sysfs/system_cpu_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/vmstat_numa.go b/sysfs/vmstat_numa.go index d71cd4a15..f33ef084a 100644 --- a/sysfs/vmstat_numa.go +++ b/sysfs/vmstat_numa.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import ( diff --git a/sysfs/vmstat_numa_test.go b/sysfs/vmstat_numa_test.go index 64977b944..81c0a1801 100644 --- a/sysfs/vmstat_numa_test.go +++ b/sysfs/vmstat_numa_test.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import ( diff --git a/sysfs/vulnerability.go b/sysfs/vulnerability.go index d41ecfb09..9e2d9cdbd 100644 --- a/sysfs/vulnerability.go +++ b/sysfs/vulnerability.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import ( From f514e443f9d9a4f41b9a86b366af504fecdfae79 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Mon, 1 Mar 2021 13:10:19 +0100 Subject: [PATCH 03/31] Add support for NVMe The sysfs contains some useful information about NVMe devices that should be exporter by the Prometheus node exporter. Add a `NVMeClass` function to collect the information for the node exporter. See: https://github.com/prometheus/node_exporter/issues/1891 Signed-off-by: Benjamin Drung --- fixtures.ttar | 26 ++++++++++++ sysfs/class_nvme.go | 87 ++++++++++++++++++++++++++++++++++++++++ sysfs/class_nvme_test.go | 48 ++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 sysfs/class_nvme.go create mode 100644 sysfs/class_nvme_test.go diff --git a/fixtures.ttar b/fixtures.ttar index 1e76173da..cf9243ac9 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -3960,6 +3960,32 @@ Lines: 1 1 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/nvme +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/nvme/nvme0 +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/nvme/nvme0/firmware_rev +Lines: 1 +1B2QEXP7 +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/nvme/nvme0/model +Lines: 1 +Samsung SSD 970 PRO 512GB +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/nvme/nvme0/serial +Lines: 1 +S680HF8N190894I +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/nvme/nvme0/state +Lines: 1 +live +Mode: 664 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/class/power_supply Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sysfs/class_nvme.go b/sysfs/class_nvme.go new file mode 100644 index 000000000..561587427 --- /dev/null +++ b/sysfs/class_nvme.go @@ -0,0 +1,87 @@ +// Copyright 2021 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. + +package sysfs + +import ( + "fmt" + "io/ioutil" + "path/filepath" + + "github.com/prometheus/procfs/internal/util" +) + +const nvmeClassPath = "class/nvme" + +// NVMeDevice contains info from files in /sys/class/nvme for a single NVMe device. +type NVMeDevice struct { + Name string + Serial string // /sys/class/nvme//serial + Model string // /sys/class/nvme//model + State string // /sys/class/nvme//state + FirmwareRevision string // /sys/class/nvme//firmware_rev +} + +// NVMeClass is a collection of every NVMe device in /sys/class/nvme. +// +// The map keys are the names of the NVMe devices. +type NVMeClass map[string]NVMeDevice + +// NVMeClass returns info for all NVMe devices read from /sys/class/nvme. +func (fs FS) NVMeClass() (NVMeClass, error) { + path := fs.sys.Path(nvmeClassPath) + + dirs, err := ioutil.ReadDir(path) + if err != nil { + return nil, fmt.Errorf("failed to list NVMe devices at %q: %v", path, err) + } + + nc := make(NVMeClass, len(dirs)) + for _, d := range dirs { + device, err := fs.parseNVMeDevice(d.Name()) + if err != nil { + return nil, err + } + + nc[device.Name] = *device + } + + return nc, nil +} + +// Parse one NVMe device. +func (fs FS) parseNVMeDevice(name string) (*NVMeDevice, error) { + path := fs.sys.Path(nvmeClassPath, name) + device := NVMeDevice{Name: name} + + for _, f := range [...]string{"firmware_rev", "model", "serial", "state"} { + name := filepath.Join(path, f) + value, err := util.SysReadFile(name) + if err != nil { + return nil, fmt.Errorf("failed to read file %q: %v", name, err) + } + + switch f { + case "firmware_rev": + device.FirmwareRevision = value + case "model": + device.Model = value + case "serial": + device.Serial = value + case "state": + device.State = value + } + } + + return &device, nil +} diff --git a/sysfs/class_nvme_test.go b/sysfs/class_nvme_test.go new file mode 100644 index 000000000..d4610ccab --- /dev/null +++ b/sysfs/class_nvme_test.go @@ -0,0 +1,48 @@ +// Copyright 2021 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 sysfs + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestNVMeClass(t *testing.T) { + fs, err := NewFS(sysTestFixtures) + if err != nil { + t.Fatal(err) + } + + got, err := fs.NVMeClass() + if err != nil { + t.Fatal(err) + } + + want := NVMeClass{ + "nvme0": NVMeDevice{ + Name: "nvme0", + FirmwareRevision: "1B2QEXP7", + Model: "Samsung SSD 970 PRO 512GB", + Serial: "S680HF8N190894I", + State: "live", + }, + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("unexpected NVMe class (-want +got):\n%s", diff) + } +} From 6ea67793be1aba89fc4082de8b78ccaff805b099 Mon Sep 17 00:00:00 2001 From: prombot Date: Wed, 17 Mar 2021 00:02:04 +0000 Subject: [PATCH 04/31] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 3ac29c636..2b73d86a6 100644 --- a/Makefile.common +++ b/Makefile.common @@ -83,7 +83,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_ GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.18.0 +GOLANGCI_LINT_VERSION ?= v1.36.0 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) From fbd03f7876aad6baed767f44cbac4d97265db200 Mon Sep 17 00:00:00 2001 From: MashaSamoylova Date: Wed, 24 Mar 2021 18:57:06 +0700 Subject: [PATCH 05/31] Add Inode filed into netIPSocketLine structe Signed-off-by: MashaSamoylova --- net_ip_socket.go | 10 ++++++++-- net_ip_socket_test.go | 27 +++++++++++++++++---------- net_tcp_test.go | 5 +++++ net_udp_test.go | 5 +++++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/net_ip_socket.go b/net_ip_socket.go index ac01dd847..8c9ee3de8 100644 --- a/net_ip_socket.go +++ b/net_ip_socket.go @@ -65,6 +65,7 @@ type ( TxQueue uint64 RxQueue uint64 UID uint64 + Inode uint64 } ) @@ -150,9 +151,9 @@ func parseIP(hexIP string) (net.IP, error) { // parseNetIPSocketLine parses a single line, represented by a list of fields. func parseNetIPSocketLine(fields []string) (*netIPSocketLine, error) { line := &netIPSocketLine{} - if len(fields) < 8 { + if len(fields) < 10 { return nil, fmt.Errorf( - "cannot parse net socket line as it has less then 8 columns %q", + "cannot parse net socket line as it has less then 10 columns %q", strings.Join(fields, " "), ) } @@ -216,5 +217,10 @@ func parseNetIPSocketLine(fields []string) (*netIPSocketLine, error) { return nil, fmt.Errorf("cannot parse uid value in socket line: %w", err) } + // inode + if line.Inode, err = strconv.ParseUint(fields[9], 0, 64); err != nil { + return nil, fmt.Errorf("cannot parse inode value in socket line: %w", err) + } + return line, nil } diff --git a/net_ip_socket_test.go b/net_ip_socket_test.go index a8bf91fff..9bbad87fe 100644 --- a/net_ip_socket_test.go +++ b/net_ip_socket_test.go @@ -28,7 +28,7 @@ func Test_parseNetIPSocketLine(t *testing.T) { }{ { name: "reading valid lines, no issue should happened", - fields: []string{"11:", "00000000:0000", "00000000:0000", "0A", "00000017:0000002A", "0:0", "0", "1000"}, + fields: []string{"11:", "00000000:0000", "00000000:0000", "0A", "00000017:0000002A", "0:0", "0", "1000", "0", "39309"}, want: &netIPSocketLine{ Sl: 11, LocalAddr: net.IP{0, 0, 0, 0}, @@ -39,53 +39,60 @@ func Test_parseNetIPSocketLine(t *testing.T) { TxQueue: 23, RxQueue: 42, UID: 1000, + Inode: 39309, }, }, { - name: "error case - invalid line - number of fields/columns < 8", - fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "0:0", "0"}, + name: "error case - invalid line - number of fields/columns < 10", + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "0:0", "0", "0"}, want: nil, wantErr: true, }, { name: "error case - parse sl - not a valid uint", - fields: []string{"a:", "00000000:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "0"}, + fields: []string{"a:", "00000000:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - parse local_address - not a valid hex", - fields: []string{"1:", "0000000O:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "0"}, + fields: []string{"1:", "0000000O:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - parse rem_address - not a valid hex", - fields: []string{"1:", "00000000:0000", "0000000O:0000", "07", "00000000:00000001", "0:0", "0", "0"}, + fields: []string{"1:", "00000000:0000", "0000000O:0000", "07", "00000000:00000001", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - cannot parse line - missing colon", - fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "0000000000000001", "0:0", "0", "0"}, + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "0000000000000001", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - parse tx_queue - not a valid hex", - fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "DEADCODE:00000001", "0:0", "0", "0"}, + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "DEADCODE:00000001", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - parse rx_queue - not a valid hex", - fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "00000000:FEEDCODE", "0:0", "0", "0"}, + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "00000000:FEEDCODE", "0:0", "0", "0", "0", "39309"}, want: nil, wantErr: true, }, { name: "error case - parse UID - not a valid uint", - fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "-10"}, + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "-10", "0", "39309"}, + want: nil, + wantErr: true, + }, + { + name: "error case - parse Inode - not a valid uint", + fields: []string{"1:", "00000000:0000", "00000000:0000", "07", "00000000:00000001", "0:0", "0", "-10", "0", "-39309"}, want: nil, wantErr: true, }, diff --git a/net_tcp_test.go b/net_tcp_test.go index f00d4b54e..1be706da9 100644 --- a/net_tcp_test.go +++ b/net_tcp_test.go @@ -40,6 +40,7 @@ func Test_newNetTCP(t *testing.T) { TxQueue: 0, RxQueue: 1, UID: 0, + Inode: 2740, }, &netIPSocketLine{ Sl: 1, @@ -51,6 +52,7 @@ func Test_newNetTCP(t *testing.T) { TxQueue: 1, RxQueue: 0, UID: 0, + Inode: 2740, }, &netIPSocketLine{ Sl: 2, @@ -62,6 +64,7 @@ func Test_newNetTCP(t *testing.T) { TxQueue: 1, RxQueue: 1, UID: 0, + Inode: 2740, }, }, wantErr: false, @@ -80,6 +83,7 @@ func Test_newNetTCP(t *testing.T) { TxQueue: 0, RxQueue: 0, UID: 981, + Inode: 21040, }, &netIPSocketLine{ Sl: 6073, @@ -91,6 +95,7 @@ func Test_newNetTCP(t *testing.T) { TxQueue: 0, RxQueue: 0, UID: 1000, + Inode: 11337031, }, }, wantErr: false, diff --git a/net_udp_test.go b/net_udp_test.go index f3d56d022..50237557c 100644 --- a/net_udp_test.go +++ b/net_udp_test.go @@ -40,6 +40,7 @@ func Test_newNetUDP(t *testing.T) { TxQueue: 0, RxQueue: 1, UID: 0, + Inode: 2740, }, &netIPSocketLine{ Sl: 1, @@ -51,6 +52,7 @@ func Test_newNetUDP(t *testing.T) { TxQueue: 1, RxQueue: 0, UID: 0, + Inode: 2740, }, &netIPSocketLine{ Sl: 2, @@ -62,6 +64,7 @@ func Test_newNetUDP(t *testing.T) { TxQueue: 1, RxQueue: 1, UID: 0, + Inode: 2740, }, }, wantErr: false, @@ -80,6 +83,7 @@ func Test_newNetUDP(t *testing.T) { TxQueue: 0, RxQueue: 0, UID: 981, + Inode: 21040, }, &netIPSocketLine{ Sl: 6073, @@ -91,6 +95,7 @@ func Test_newNetUDP(t *testing.T) { TxQueue: 0, RxQueue: 0, UID: 1000, + Inode: 11337031, }, }, wantErr: false, From e291fd0d45792d95363a5a544e2f90e3226cdf47 Mon Sep 17 00:00:00 2001 From: Trey Dockendorf Date: Mon, 5 Apr 2021 11:45:05 -0400 Subject: [PATCH 06/31] Add several Infiniband counters Counters added: * excessive_buffer_overrun_errors * local_link_integrity_errors Signed-off-by: Trey Dockendorf --- sysfs/class_infiniband.go | 46 ++++++------ sysfs/class_infiniband_test.go | 128 +++++++++++++++++---------------- 2 files changed, 94 insertions(+), 80 deletions(-) diff --git a/sysfs/class_infiniband.go b/sysfs/class_infiniband.go index cb71824f2..e9ee28460 100644 --- a/sysfs/class_infiniband.go +++ b/sysfs/class_infiniband.go @@ -42,26 +42,28 @@ type InfiniBandCounters struct { LegacyPortXmitData64 *uint64 // counters_ext/port_xmit_data_64 LegacyPortXmitPackets64 *uint64 // counters_ext/port_xmit_packets_64 - LinkDowned *uint64 // counters/link_downed - LinkErrorRecovery *uint64 // counters/link_error_recovery - MulticastRcvPackets *uint64 // counters/multicast_rcv_packets - MulticastXmitPackets *uint64 // counters/multicast_xmit_packets - PortRcvConstraintErrors *uint64 // counters/port_rcv_constraint_errors - PortRcvData *uint64 // counters/port_rcv_data - PortRcvDiscards *uint64 // counters/port_rcv_discards - PortRcvErrors *uint64 // counters/port_rcv_errors - PortRcvPackets *uint64 // counters/port_rcv_packets - PortRcvRemotePhysicalErrors *uint64 // counters/port_rcv_remote_physical_errors - PortRcvSwitchRelayErrors *uint64 // counters/port_rcv_switch_relay_errors - PortXmitConstraintErrors *uint64 // counters/port_xmit_constraint_errors - PortXmitData *uint64 // counters/port_xmit_data - PortXmitDiscards *uint64 // counters/port_xmit_discards - PortXmitPackets *uint64 // counters/port_xmit_packets - PortXmitWait *uint64 // counters/port_xmit_wait - SymbolError *uint64 // counters/symbol_error - UnicastRcvPackets *uint64 // counters/unicast_rcv_packets - UnicastXmitPackets *uint64 // counters/unicast_xmit_packets - VL15Dropped *uint64 // counters/VL15_dropped + ExcessiveBufferOverrunErrors *uint64 // counters/excessive_buffer_overrun_errors + LinkDowned *uint64 // counters/link_downed + LinkErrorRecovery *uint64 // counters/link_error_recovery + LocalLinkIntegrityErrors *uint64 // counters/local_link_integrity_errors + MulticastRcvPackets *uint64 // counters/multicast_rcv_packets + MulticastXmitPackets *uint64 // counters/multicast_xmit_packets + PortRcvConstraintErrors *uint64 // counters/port_rcv_constraint_errors + PortRcvData *uint64 // counters/port_rcv_data + PortRcvDiscards *uint64 // counters/port_rcv_discards + PortRcvErrors *uint64 // counters/port_rcv_errors + PortRcvPackets *uint64 // counters/port_rcv_packets + PortRcvRemotePhysicalErrors *uint64 // counters/port_rcv_remote_physical_errors + PortRcvSwitchRelayErrors *uint64 // counters/port_rcv_switch_relay_errors + PortXmitConstraintErrors *uint64 // counters/port_xmit_constraint_errors + PortXmitData *uint64 // counters/port_xmit_data + PortXmitDiscards *uint64 // counters/port_xmit_discards + PortXmitPackets *uint64 // counters/port_xmit_packets + PortXmitWait *uint64 // counters/port_xmit_wait + SymbolError *uint64 // counters/symbol_error + UnicastRcvPackets *uint64 // counters/unicast_rcv_packets + UnicastXmitPackets *uint64 // counters/unicast_xmit_packets + VL15Dropped *uint64 // counters/VL15_dropped } // InfiniBandPort contains info from files in @@ -270,10 +272,14 @@ func parseInfiniBandCounters(portPath string) (*InfiniBandCounters, error) { vp := util.NewValueParser(value) switch f.Name() { + case "excessive_buffer_overrun_errors": + counters.ExcessiveBufferOverrunErrors = vp.PUInt64() case "link_downed": counters.LinkDowned = vp.PUInt64() case "link_error_recovery": counters.LinkErrorRecovery = vp.PUInt64() + case "local_link_integrity_errors": + counters.LocalLinkIntegrityErrors = vp.PUInt64() case "multicast_rcv_packets": counters.MulticastRcvPackets = vp.PUInt64() case "multicast_xmit_packets": diff --git a/sysfs/class_infiniband_test.go b/sysfs/class_infiniband_test.go index dd377a63c..d7592ea51 100644 --- a/sysfs/class_infiniband_test.go +++ b/sysfs/class_infiniband_test.go @@ -63,37 +63,41 @@ func TestInfiniBandClass(t *testing.T) { } var ( - port1LinkDowned uint64 - port1LinkErrorRecovery uint64 - port1PortRcvConstraintErrors uint64 - port1PortRcvData uint64 = 8884894436 - port1PortRcvErrors uint64 - port1PortRcvPackets uint64 = 87169372 - port1PortRcvRemotePhysicalErrors uint64 - port1PortRcvSwitchRelayErrors uint64 - port1PortXmitConstraintErrors uint64 - port1PortXmitData uint64 = 106036453180 - port1PortXmitDiscards uint64 - port1PortXmitPackets uint64 = 85734114 - port1PortXmitWait uint64 = 3599 - port1SymbolError uint64 - port1VL15Dropped uint64 + port1ExcessiveBufferOverrunErrors uint64 + port1LinkDowned uint64 + port1LinkErrorRecovery uint64 + port1LocalLinkIntegrityErrors uint64 + port1PortRcvConstraintErrors uint64 + port1PortRcvData uint64 = 8884894436 + port1PortRcvErrors uint64 + port1PortRcvPackets uint64 = 87169372 + port1PortRcvRemotePhysicalErrors uint64 + port1PortRcvSwitchRelayErrors uint64 + port1PortXmitConstraintErrors uint64 + port1PortXmitData uint64 = 106036453180 + port1PortXmitDiscards uint64 + port1PortXmitPackets uint64 = 85734114 + port1PortXmitWait uint64 = 3599 + port1SymbolError uint64 + port1VL15Dropped uint64 - port2LinkDowned uint64 - port2LinkErrorRecovery uint64 - port2PortRcvConstraintErrors uint64 - port2PortRcvData uint64 = 9841747136 - port2PortRcvErrors uint64 - port2PortRcvPackets uint64 = 89332064 - port2PortRcvRemotePhysicalErrors uint64 - port2PortRcvSwitchRelayErrors uint64 - port2PortXmitConstraintErrors uint64 - port2PortXmitData uint64 = 106161427560 - port2PortXmitDiscards uint64 - port2PortXmitPackets uint64 = 88622850 - port2PortXmitWait uint64 = 3846 - port2SymbolError uint64 - port2VL15Dropped uint64 + port2ExcessiveBufferOverrunErrors uint64 + port2LinkDowned uint64 + port2LinkErrorRecovery uint64 + port2LocalLinkIntegrityErrors uint64 + port2PortRcvConstraintErrors uint64 + port2PortRcvData uint64 = 9841747136 + port2PortRcvErrors uint64 + port2PortRcvPackets uint64 = 89332064 + port2PortRcvRemotePhysicalErrors uint64 + port2PortRcvSwitchRelayErrors uint64 + port2PortXmitConstraintErrors uint64 + port2PortXmitData uint64 = 106161427560 + port2PortXmitDiscards uint64 + port2PortXmitPackets uint64 = 88622850 + port2PortXmitWait uint64 = 3846 + port2SymbolError uint64 + port2VL15Dropped uint64 ) want := InfiniBandClass{ @@ -112,21 +116,23 @@ func TestInfiniBandClass(t *testing.T) { PhysStateID: 5, Rate: 5000000000, Counters: InfiniBandCounters{ - LinkDowned: &port1LinkDowned, - LinkErrorRecovery: &port1LinkErrorRecovery, - PortRcvConstraintErrors: &port1PortRcvConstraintErrors, - PortRcvData: &port1PortRcvData, - PortRcvErrors: &port1PortRcvErrors, - PortRcvPackets: &port1PortRcvPackets, - PortRcvRemotePhysicalErrors: &port1PortRcvRemotePhysicalErrors, - PortRcvSwitchRelayErrors: &port1PortRcvSwitchRelayErrors, - PortXmitConstraintErrors: &port1PortXmitConstraintErrors, - PortXmitData: &port1PortXmitData, - PortXmitDiscards: &port1PortXmitDiscards, - PortXmitPackets: &port1PortXmitPackets, - PortXmitWait: &port1PortXmitWait, - SymbolError: &port1SymbolError, - VL15Dropped: &port1VL15Dropped, + ExcessiveBufferOverrunErrors: &port1ExcessiveBufferOverrunErrors, + LinkDowned: &port1LinkDowned, + LinkErrorRecovery: &port1LinkErrorRecovery, + LocalLinkIntegrityErrors: &port1LocalLinkIntegrityErrors, + PortRcvConstraintErrors: &port1PortRcvConstraintErrors, + PortRcvData: &port1PortRcvData, + PortRcvErrors: &port1PortRcvErrors, + PortRcvPackets: &port1PortRcvPackets, + PortRcvRemotePhysicalErrors: &port1PortRcvRemotePhysicalErrors, + PortRcvSwitchRelayErrors: &port1PortRcvSwitchRelayErrors, + PortXmitConstraintErrors: &port1PortXmitConstraintErrors, + PortXmitData: &port1PortXmitData, + PortXmitDiscards: &port1PortXmitDiscards, + PortXmitPackets: &port1PortXmitPackets, + PortXmitWait: &port1PortXmitWait, + SymbolError: &port1SymbolError, + VL15Dropped: &port1VL15Dropped, }, }, 2: { @@ -138,21 +144,23 @@ func TestInfiniBandClass(t *testing.T) { PhysStateID: 5, Rate: 5000000000, Counters: InfiniBandCounters{ - LinkDowned: &port2LinkDowned, - LinkErrorRecovery: &port2LinkErrorRecovery, - PortRcvConstraintErrors: &port2PortRcvConstraintErrors, - PortRcvData: &port2PortRcvData, - PortRcvErrors: &port2PortRcvErrors, - PortRcvPackets: &port2PortRcvPackets, - PortRcvRemotePhysicalErrors: &port2PortRcvRemotePhysicalErrors, - PortRcvSwitchRelayErrors: &port2PortRcvSwitchRelayErrors, - PortXmitConstraintErrors: &port2PortXmitConstraintErrors, - PortXmitData: &port2PortXmitData, - PortXmitDiscards: &port2PortXmitDiscards, - PortXmitPackets: &port2PortXmitPackets, - PortXmitWait: &port2PortXmitWait, - SymbolError: &port2SymbolError, - VL15Dropped: &port2VL15Dropped, + ExcessiveBufferOverrunErrors: &port2ExcessiveBufferOverrunErrors, + LinkDowned: &port2LinkDowned, + LinkErrorRecovery: &port2LinkErrorRecovery, + LocalLinkIntegrityErrors: &port2LocalLinkIntegrityErrors, + PortRcvConstraintErrors: &port2PortRcvConstraintErrors, + PortRcvData: &port2PortRcvData, + PortRcvErrors: &port2PortRcvErrors, + PortRcvPackets: &port2PortRcvPackets, + PortRcvRemotePhysicalErrors: &port2PortRcvRemotePhysicalErrors, + PortRcvSwitchRelayErrors: &port2PortRcvSwitchRelayErrors, + PortXmitConstraintErrors: &port2PortXmitConstraintErrors, + PortXmitData: &port2PortXmitData, + PortXmitDiscards: &port2PortXmitDiscards, + PortXmitPackets: &port2PortXmitPackets, + PortXmitWait: &port2PortXmitWait, + SymbolError: &port2SymbolError, + VL15Dropped: &port2VL15Dropped, }, }, }, From 6a1f500a79d018b324448f936eacbbc2e0b74684 Mon Sep 17 00:00:00 2001 From: binjip978 Date: Sun, 11 Apr 2021 09:59:24 +0300 Subject: [PATCH 07/31] Add RSSLimit, rt_priority, policy and delay_acct_block to pid/stat Signed-off-by: binjip978 --- proc_stat.go | 27 +++++++++++++++++++++++++++ proc_stat_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/proc_stat.go b/proc_stat.go index 67ca0e9fb..d3a860e4a 100644 --- a/proc_stat.go +++ b/proc_stat.go @@ -100,6 +100,15 @@ type ProcStat struct { VSize uint // Resident set size in pages. RSS int + // Soft limit in bytes on the rss of the process. + RSSLimit uint64 + // Real-time scheduling priority, a number in the range 1 to 99 for processes + // scheduled under a real-time policy, or 0, for non-real-time processes. + RTPriority uint + // Scheduling policy. + Policy uint + // Aggregated block I/O delays, measured in clock ticks (centiseconds). + DelayAcctBlkIOTicks uint64 proc fs.FS } @@ -155,6 +164,24 @@ func (p Proc) Stat() (ProcStat, error) { &s.Starttime, &s.VSize, &s.RSS, + &s.RSSLimit, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &ignore, + &s.RTPriority, + &s.Policy, + &s.DelayAcctBlkIOTicks, ) if err != nil { return ProcStat{}, err diff --git a/proc_stat_test.go b/proc_stat_test.go index 8b23cf18b..eafefb777 100644 --- a/proc_stat_test.go +++ b/proc_stat_test.go @@ -29,6 +29,7 @@ func TestProcStat(t *testing.T) { t.Fatal(err) } + // pid stat int fields for _, test := range []struct { name string want int @@ -45,6 +46,34 @@ func TestProcStat(t *testing.T) { t.Errorf("want %s %d, have %d", test.name, test.want, test.have) } } + + // pid stat uint64 fields + for _, test := range []struct { + name string + want uint64 + have uint64 + }{ + {name: "RSS Limit", want: 18446744073709551615, have: s.RSSLimit}, + {name: "delayacct_blkio_ticks", want: 31, have: s.DelayAcctBlkIOTicks}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } + + // pid stat uint fields + for _, test := range []struct { + name string + want uint + have uint + }{ + {name: "rt_priority", want: 0, have: s.RTPriority}, + {name: "policy", want: 0, have: s.Policy}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } } func TestProcStatComm(t *testing.T) { From 8e91b32f3b0e718fda134937b2ae68a361f7bd12 Mon Sep 17 00:00:00 2001 From: Julian Kornberger Date: Sun, 11 Apr 2021 10:43:09 +0200 Subject: [PATCH 08/31] Add NetClassByIface See also: prometheus/node_exporter#1915 Signed-off-by: Julian Kornberger --- sysfs/net_class.go | 26 ++++++++++++++++++++------ sysfs/net_class_test.go | 21 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/sysfs/net_class.go b/sysfs/net_class.go index e6e223984..c1fed2bc0 100644 --- a/sysfs/net_class.go +++ b/sysfs/net_class.go @@ -82,6 +82,19 @@ func (fs FS) NetClassDevices() ([]string, error) { return res, nil } +// NetClassByIface returns info for a single net interfaces (iface) +func (fs FS) NetClassByIface(devicePath string) (*NetClassIface, error) { + path := fs.sys.Path(netclassPath) + + interfaceClass, err := parseNetClassIface(filepath.Join(path, devicePath)) + if err != nil { + return nil, err + } + interfaceClass.Name = devicePath + + return interfaceClass, nil +} + // NetClass returns info for all net interfaces (iface) read from /sys/class/net/. func (fs FS) NetClass() (NetClass, error) { devices, err := fs.NetClassDevices() @@ -91,20 +104,21 @@ func (fs FS) NetClass() (NetClass, error) { path := fs.sys.Path(netclassPath) netClass := NetClass{} - for _, deviceDir := range devices { - interfaceClass, err := netClass.parseNetClassIface(filepath.Join(path, deviceDir)) + for _, devicePath := range devices { + interfaceClass, err := parseNetClassIface(filepath.Join(path, devicePath)) if err != nil { return nil, err } - interfaceClass.Name = deviceDir - netClass[deviceDir] = *interfaceClass + interfaceClass.Name = devicePath + netClass[devicePath] = *interfaceClass } + return netClass, nil } // parseNetClassIface scans predefined files in /sys/class/net/ // directory and gets their contents. -func (nc NetClass) parseNetClassIface(devicePath string) (*NetClassIface, error) { +func parseNetClassIface(devicePath string) (*NetClassIface, error) { interfaceClass := NetClassIface{} files, err := ioutil.ReadDir(devicePath) @@ -180,6 +194,6 @@ func (nc NetClass) parseNetClassIface(devicePath string) (*NetClassIface, error) interfaceClass.Type = vp.PInt64() } } - return &interfaceClass, nil + return &interfaceClass, nil } diff --git a/sysfs/net_class_test.go b/sysfs/net_class_test.go index bc219f340..f85660756 100644 --- a/sysfs/net_class_test.go +++ b/sysfs/net_class_test.go @@ -39,6 +39,27 @@ func TestNewNetClassDevices(t *testing.T) { } } +func TestNewNetClassDevicesByIface(t *testing.T) { + fs, err := NewFS(sysTestFixtures) + if err != nil { + t.Fatal(err) + } + + _, err = fs.NetClassByIface("non-existent") + if err == nil { + t.Fatal("expected error, have none") + } + + device, err := fs.NetClassByIface("eth0") + if err != nil { + t.Fatal(err) + } + + if device.Name != "eth0" { + t.Errorf("Found unexpected device, want %s, have %s", "eth0", device.Name) + } +} + func TestNetClass(t *testing.T) { fs, err := NewFS(sysTestFixtures) if err != nil { From 6da175d0c75badb18e69340fa0fa46e7b60dad62 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Sat, 22 May 2021 12:22:53 +0200 Subject: [PATCH 09/31] Update build * Add test for fixture repacking * Move linters out of per-version test. * Use build matrix to simplify version updating. * Add all supported Go versions. Signed-off-by: SuperQ --- .circleci/config.yml | 62 +++++++++++++++++++++++++------------------- Makefile | 2 ++ 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26ed5f5e9..eb700b7ce 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,31 +1,37 @@ --- version: 2.1 -commands: - default: - steps: - - run: make style check_license test lint - no-test: +jobs: + lint: + docker: + - image: cimg/go:1.16 steps: - - run: make style check_license lint + - checkout + - run: make check_license + - run: make fixtures + - run: make update_fixtures + - run: git diff --exit-code -jobs: test: parameters: - command: - type: string go_version: type: string os: type: string + run_test: + type: boolean + default: true docker: - image: circleci/golang:<< parameters.go_version >> environment: GOOS: "<< parameters.os >>" - working_directory: /go/src/github.com/prometheus/procfs steps: - checkout - - << parameters.command >> + - run: make style lint + - when: + condition: << parameters.run_test >> + steps: + - run: make test codespell: docker: @@ -40,24 +46,26 @@ workflows: version: 2 procfs: jobs: + - lint - test: - command: default - name: linux-1-15 - os: linux - go_version: "1.15" - - test: - command: default - name: linux-1-14 + name: test-linux os: linux - go_version: "1.14" - - test: - command: no-test - name: windows-1-15 - os: windows - go_version: "1.15" + matrix: + parameters: + go_version: + - "1.13" + - "1.14" + - "1.15" + - "1.16" - test: - command: no-test - name: windows-1-14 + name: test-windows os: windows - go_version: "1.14" + run_test: false + matrix: + parameters: + go_version: + - "1.13" + - "1.14" + - "1.15" + - "1.16" - codespell diff --git a/Makefile b/Makefile index 616a0d25e..fa2bd5b52 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ include Makefile.common ./ttar -C $(dir $*) -x -f $*.ttar touch $@ +fixtures: fixtures/.unpacked + update_fixtures: rm -vf fixtures/.unpacked ./ttar -c -f fixtures.ttar fixtures/ From 1369220736db115f399da9fda096a229df9fa02c Mon Sep 17 00:00:00 2001 From: SuperQ Date: Sat, 22 May 2021 12:30:26 +0200 Subject: [PATCH 10/31] Repack fixtures. Signed-off-by: SuperQ --- fixtures.ttar | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/fixtures.ttar b/fixtures.ttar index 1e76173da..3abeed89c 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -4978,35 +4978,6 @@ Mode: 644 Directory: fixtures/sys/devices/system Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node1/vmstat -Lines: 6 -nr_free_pages 1 -nr_zone_inactive_anon 2 -nr_zone_active_anon 3 -nr_zone_inactive_file 4 -nr_zone_active_file 5 -nr_zone_unevictable 6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node2/vmstat -Lines: 6 -nr_free_pages 7 -nr_zone_inactive_anon 8 -nr_zone_active_anon 9 -nr_zone_inactive_file 10 -nr_zone_active_file 11 -nr_zone_unevictable 12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/devices/system/clocksource Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5254,6 +5225,35 @@ Mode: 644 Directory: fixtures/sys/devices/system/cpu/cpufreq/policy1 Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node/node1 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/node/node1/vmstat +Lines: 6 +nr_free_pages 1 +nr_zone_inactive_anon 2 +nr_zone_active_anon 3 +nr_zone_inactive_file 4 +nr_zone_active_file 5 +nr_zone_unevictable 6 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node/node2 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/node/node2/vmstat +Lines: 6 +nr_free_pages 7 +nr_zone_inactive_anon 8 +nr_zone_active_anon 9 +nr_zone_inactive_file 10 +nr_zone_active_file 11 +nr_zone_unevictable 12 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/fs Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 7f49865f412840e5b1dab04a8d1317026c02e082 Mon Sep 17 00:00:00 2001 From: SuperQ Date: Wed, 2 Jun 2021 08:16:19 +0200 Subject: [PATCH 11/31] Fix linter issue. Signed-off-by: SuperQ --- mountstats_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mountstats_test.go b/mountstats_test.go index f218e3749..09e26b98f 100644 --- a/mountstats_test.go +++ b/mountstats_test.go @@ -418,7 +418,7 @@ func mountsStr(mounts []*Mount) string { out += fmt.Sprintf("\n\t- bytes: %v", stats.Bytes) out += fmt.Sprintf("\n\t- events: %v", stats.Events) out += fmt.Sprintf("\n\t- transport: %v", stats.Transport) - out += fmt.Sprintf("\n\t- per-operation stats:") + out += "\n\t- per-operation stats:" for _, o := range stats.Operations { out += fmt.Sprintf("\n\t\t- %v", o) From b6e87638408d66a659f15a46e45a976bc704fe8a Mon Sep 17 00:00:00 2001 From: prombot Date: Sat, 5 Jun 2021 00:01:33 +0000 Subject: [PATCH 12/31] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.common b/Makefile.common index 2b73d86a6..ce80d530a 100644 --- a/Makefile.common +++ b/Makefile.common @@ -78,12 +78,12 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.7.0 +PROMU_VERSION ?= 0.12.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.36.0 +GOLANGCI_LINT_VERSION ?= v1.39.0 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) From c53ce81ce20f646c2e0e3aff91f63474e1563e2f Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Sun, 14 Mar 2021 16:04:42 +0100 Subject: [PATCH 13/31] Parse /sys/class/drm/cardN/device/ stats This commits adds support for reading card stats exposed by drm. Only `amdgpu` driver currently exposes these stats but it should be easy to add more driver support if required. FreeBSD uses the same driver through `kms-drm` but it does not expose the attributes we are interested in through niether `sysctl` or `linsysfs`. Signed-off-by: Siavash Safi --- sysfs/class_drm.go | 26 +++++++ sysfs/class_drm_amdgpu.go | 121 +++++++++++++++++++++++++++++++++ sysfs/class_drm_amdgpu_test.go | 53 +++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 sysfs/class_drm.go create mode 100644 sysfs/class_drm_amdgpu.go create mode 100644 sysfs/class_drm_amdgpu_test.go diff --git a/sysfs/class_drm.go b/sysfs/class_drm.go new file mode 100644 index 000000000..1febea25b --- /dev/null +++ b/sysfs/class_drm.go @@ -0,0 +1,26 @@ +// Copyright 2021 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 linux + +package sysfs + +import ( + "path/filepath" + + "github.com/prometheus/procfs/internal/util" +) + +func readDRMCardField(card, field string) (string, error) { + return util.SysReadFile(filepath.Join(card, "device", field)) +} diff --git a/sysfs/class_drm_amdgpu.go b/sysfs/class_drm_amdgpu.go new file mode 100644 index 000000000..308d1d134 --- /dev/null +++ b/sysfs/class_drm_amdgpu.go @@ -0,0 +1,121 @@ +// Copyright 2021 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 linux + +package sysfs + +import ( + "errors" + "fmt" + "path/filepath" + "regexp" + "syscall" + + "github.com/prometheus/procfs/internal/util" +) + +const ( + // Supported device drivers. + deviceDriverAMDGPU = "amdgpu" +) + +// ClassDRMCardAMDGPUStats contains info from files in +// /sys/class/drm/card/device for a single amdgpu card. +// Not all cards expose all metrics. +// https://www.kernel.org/doc/html/latest/gpu/amdgpu.html +type ClassDRMCardAMDGPUStats struct { + Name string // The card name. + GPUBusyPercent uint64 // How busy the GPU is as a percentage. + MemoryGTTSize uint64 // The size of the graphics translation table (GTT) block in bytes. + MemoryGTTUsed uint64 // The used amount of the graphics translation table (GTT) block in bytes. + MemoryVisibleVRAMSize uint64 // The size of visible VRAM in bytes. + MemoryVisibleVRAMUsed uint64 // The used amount of visible VRAM in bytes. + MemoryVRAMSize uint64 // The size of VRAM in bytes. + MemoryVRAMUsed uint64 // The used amount of VRAM in bytes. + MemoryVRAMVendor string // The VRAM vendor name. + PowerDPMForcePerformanceLevel string // The current power performance level. + UniqueID string // The unique ID of the GPU that will persist from machine to machine. +} + +// ClassDRMCardAMDGPUStats returns DRM card metrics for all amdgpu cards. +func (fs FS) ClassDRMCardAMDGPUStats() ([]ClassDRMCardAMDGPUStats, error) { + cards, err := filepath.Glob(fs.sys.Path("class/drm/card[0-9]")) + if err != nil { + return nil, err + } + + var stats []ClassDRMCardAMDGPUStats + for _, card := range cards { + cardStats, err := parseClassDRMAMDGPUCard(card) + if err != nil { + if errors.Is(err, syscall.ENODATA) { + continue + } + return nil, err + } + cardStats.Name = filepath.Base(card) + stats = append(stats, cardStats) + } + return stats, nil +} + +func parseClassDRMAMDGPUCard(card string) (ClassDRMCardAMDGPUStats, error) { + uevent, err := util.SysReadFile(filepath.Join(card, "device/uevent")) + if err != nil { + return ClassDRMCardAMDGPUStats{}, err + } + + match, err := regexp.MatchString(fmt.Sprintf("DRIVER=%s", deviceDriverAMDGPU), uevent) + if err != nil { + return ClassDRMCardAMDGPUStats{}, err + } + if !match { + return ClassDRMCardAMDGPUStats{}, nil + } + + stats := ClassDRMCardAMDGPUStats{Name: card} + // Read only specific files for faster data gathering. + if v, err := readDRMCardField(card, "gpu_busy_percent"); err == nil { + stats.GPUBusyPercent = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_gtt_total"); err == nil { + stats.MemoryGTTSize = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_gtt_used"); err == nil { + stats.MemoryGTTUsed = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_vis_vram_total"); err == nil { + stats.MemoryVisibleVRAMSize = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_vis_vram_used"); err == nil { + stats.MemoryVisibleVRAMUsed = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_vram_total"); err == nil { + stats.MemoryVRAMSize = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_vram_used"); err == nil { + stats.MemoryVRAMUsed = *util.NewValueParser(v).PUInt64() + } + if v, err := readDRMCardField(card, "mem_info_vram_vendor"); err == nil { + stats.MemoryVRAMVendor = v + } + if v, err := readDRMCardField(card, "power_dpm_force_performance_level"); err == nil { + stats.PowerDPMForcePerformanceLevel = v + } + if v, err := readDRMCardField(card, "unique_id"); err == nil { + stats.UniqueID = v + } + + return stats, nil +} diff --git a/sysfs/class_drm_amdgpu_test.go b/sysfs/class_drm_amdgpu_test.go new file mode 100644 index 000000000..b9fb1519a --- /dev/null +++ b/sysfs/class_drm_amdgpu_test.go @@ -0,0 +1,53 @@ +// Copyright 2021 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 linux + +package sysfs + +import ( + "reflect" + "testing" +) + +func TestClassDRMCardStats(t *testing.T) { + fs, err := NewFS(sysTestFixtures) + if err != nil { + t.Fatal(err) + } + + drmTest, err := fs.ClassDRMCardAMDGPUStats() + if err != nil { + t.Fatal(err) + } + + classDRMCardStats := []ClassDRMCardAMDGPUStats{ + { + Name: "card0", + GPUBusyPercent: 4, + MemoryGTTSize: 8573157376, + MemoryGTTUsed: 144560128, + MemoryVisibleVRAMSize: 8573157376, + MemoryVisibleVRAMUsed: 1490378752, + MemoryVRAMSize: 8573157376, + MemoryVRAMUsed: 1490378752, + MemoryVRAMVendor: "samsung", + PowerDPMForcePerformanceLevel: "manual", + UniqueID: "0123456789abcdef", + }, + } + + if !reflect.DeepEqual(classDRMCardStats, drmTest) { + t.Errorf("Result not correct: want %v, have %v", classDRMCardStats, drmTest) + } +} From 1fccbdd7fb549a4399b1f341a37a14e81bf7f45e Mon Sep 17 00:00:00 2001 From: Siavash Safi Date: Sun, 14 Mar 2021 16:10:07 +0100 Subject: [PATCH 14/31] Add tests for ClassDrmCardStats & update fixtures The fixtures are a snapshot from my Vega64 GPU, other cards might expose more or less stats based on kernel documentation. https://www.kernel.org/doc/html/latest/gpu/amdgpu.html Signed-off-by: Siavash Safi --- fixtures.ttar | 512 +++++++++++++++++++++++++++++++-- sysfs/class_drm_amdgpu_test.go | 2 +- 2 files changed, 484 insertions(+), 30 deletions(-) diff --git a/fixtures.ttar b/fixtures.ttar index 1e76173da..b0352c518 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -3455,6 +3455,460 @@ Mode: 664 Directory: fixtures/sys/class Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/drm +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/drm/card0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/drm/card0/device +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/aer_dev_correctable +Lines: 9 +RxErr 0 +BadTLP 0 +BadDLLP 0 +Rollover 0 +Timeout 0 +NonFatalErr 0 +CorrIntErr 0 +HeaderOF 0 +TOTAL_ERR_COR 0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/aer_dev_fatal +Lines: 19 +Undefined 0 +DLP 0 +SDES 0 +TLP 0 +FCP 0 +CmpltTO 0 +CmpltAbrt 0 +UnxCmplt 0 +RxOF 0 +MalfTLP 0 +ECRC 0 +UnsupReq 0 +ACSViol 0 +UncorrIntErr 0 +BlockedTLP 0 +AtomicOpBlocked 0 +TLPBlockedErr 0 +PoisonTLPBlocked 0 +TOTAL_ERR_FATAL 0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/aer_dev_nonfatal +Lines: 19 +Undefined 0 +DLP 0 +SDES 0 +TLP 0 +FCP 0 +CmpltTO 0 +CmpltAbrt 0 +UnxCmplt 0 +RxOF 0 +MalfTLP 0 +ECRC 0 +UnsupReq 0 +ACSViol 0 +UncorrIntErr 0 +BlockedTLP 0 +AtomicOpBlocked 0 +TLPBlockedErr 0 +PoisonTLPBlocked 0 +TOTAL_ERR_NONFATAL 0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/ari_enabled +Lines: 1 +0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/boot_vga +Lines: 1 +1 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/broken_parity_status +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/class +Lines: 1 +0x030000 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/consistent_dma_mask_bits +Lines: 1 +44 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/current_link_speed +Lines: 1 +8.0 GT/s PCIe +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/current_link_width +Lines: 1 +16 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/d3cold_allowed +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/device +Lines: 1 +0x687f +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/dma_mask_bits +Lines: 1 +44 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/driver_override +Lines: 1 +(null) +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/enable +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/gpu_busy_percent +Lines: 1 +4 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/irq +Lines: 1 +95 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/local_cpulist +Lines: 1 +0-15 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/local_cpus +Lines: 1 +0000ffff +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/max_link_speed +Lines: 1 +8.0 GT/s PCIe +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/max_link_width +Lines: 1 +16 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_total +Lines: 1 +8573157376 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_used +Lines: 1 +144560128 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_total +Lines: 1 +8573157376 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_used +Lines: 1 +1490378752 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_vram_total +Lines: 1 +8573157376 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_vram_used +Lines: 1 +1490378752 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/mem_info_vram_vendor +Lines: 1 +samsung +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/modalias +Lines: 1 +pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/msi_bus +Lines: 1 +1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/numa_node +Lines: 1 +-1 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pcie_bw +Lines: 1 +6641 815 256 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pcie_replay_count +Lines: 1 +0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/power_dpm_force_performance_level +Lines: 1 +manual +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/power_dpm_state +Lines: 1 +performance +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/power_state +Lines: 1 +D0 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_cur_state +Lines: 1 +1 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_dpm_dcefclk +Lines: 5 +0: 600Mhz * +1: 720Mhz +2: 800Mhz +3: 847Mhz +4: 900Mhz +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_dpm_mclk +Lines: 4 +0: 167Mhz * +1: 500Mhz +2: 800Mhz +3: 945Mhz +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_dpm_pcie +Lines: 2 +0: 8.0GT/s, x16 +1: 8.0GT/s, x16 * +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_dpm_sclk +Lines: 8 +0: 852Mhz * +1: 991Mhz +2: 1084Mhz +3: 1138Mhz +4: 1200Mhz +5: 1401Mhz +6: 1536Mhz +7: 1630Mhz +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_dpm_socclk +Lines: 8 +0: 600Mhz +1: 720Mhz * +2: 800Mhz +3: 847Mhz +4: 900Mhz +5: 960Mhz +6: 1028Mhz +7: 1107Mhz +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_features +Lines: 32 +Current ppfeatures: 0x0000000019a1ff4f +FEATURES BITMASK ENABLEMENT +DPM_PREFETCHER 0x0000000000000001 Y +GFXCLK_DPM 0x0000000000000002 Y +UCLK_DPM 0x0000000000000004 Y +SOCCLK_DPM 0x0000000000000008 Y +UVD_DPM 0x0000000000000010 N +VCE_DPM 0x0000000000000020 N +ULV 0x0000000000000040 Y +MP0CLK_DPM 0x0000000000000080 N +LINK_DPM 0x0000000000000100 Y +DCEFCLK_DPM 0x0000000000000200 Y +AVFS 0x0000000000000400 Y +GFXCLK_DS 0x0000000000000800 Y +SOCCLK_DS 0x0000000000001000 Y +LCLK_DS 0x0000000000002000 Y +PPT 0x0000000000004000 Y +TDC 0x0000000000008000 Y +THERMAL 0x0000000000010000 Y +GFX_PER_CU_CG 0x0000000000020000 N +RM 0x0000000000040000 N +DCEFCLK_DS 0x0000000000080000 N +ACDC 0x0000000000100000 N +VR0HOT 0x0000000000200000 Y +VR1HOT 0x0000000000400000 N +FW_CTF 0x0000000000800000 Y +LED_DISPLAY 0x0000000001000000 Y +FAN_CONTROL 0x0000000002000000 N +FAST_PPT 0x0000000004000000 N +DIDT 0x0000000008000000 Y +ACG 0x0000000010000000 Y +PCC_LIMIT 0x0000000020000000 N +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_force_state +Lines: 1 + +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_mclk_od +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_num_states +Lines: 3 +states: 2 +0 boot +1 performance +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_od_clk_voltage +Lines: 18 +OD_SCLK: +0: 852Mhz 800mV +1: 991Mhz 900mV +2: 1084Mhz 950mV +3: 1138Mhz 1000mV +4: 1200Mhz 1050mV +5: 1401Mhz 1100mV +6: 1536Mhz 1150mV +7: 1630Mhz 1200mV +OD_MCLK: +0: 167Mhz 800mV +1: 500Mhz 800mV +2: 800Mhz 950mV +3: 945Mhz 1100mV +OD_RANGE: +SCLK: 852MHz 2400MHz +MCLK: 167MHz 1500MHz +VDDC: 800mV 1200mV +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_power_profile_mode +Lines: 8 +NUM MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL + 0 BOOTUP_DEFAULT : 70 60 0 0 + 1 3D_FULL_SCREEN*: 70 60 1 3 + 2 POWER_SAVING : 90 60 0 0 + 3 VIDEO : 70 60 0 0 + 4 VR : 70 90 0 0 + 5 COMPUTE : 30 60 0 6 + 6 CUSTOM : 0 0 0 0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/pp_sclk_od +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/product_name +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/product_number +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/resource +Lines: 13 +0x0000007c00000000 0x0000007dffffffff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000007e00000000 0x0000007e0fffffff 0x000000000014220c +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x000000000000d000 0x000000000000d0ff 0x0000000000040101 +0x00000000fcd00000 0x00000000fcd7ffff 0x0000000000040200 +0x00000000fcd80000 0x00000000fcd9ffff 0x0000000000046200 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +0x0000000000000000 0x0000000000000000 0x0000000000000000 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/revision +Lines: 1 +0xc1 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/serial_number +Lines: 1 + +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/subsystem_device +Lines: 1 +0x04c4 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/subsystem_vendor +Lines: 1 +0x1043 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/thermal_throttling_logging +Lines: 1 +0000:09:00.0: thermal throttling logging enabled, with interval 60 seconds +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/uevent +Lines: 6 +DRIVER=amdgpu +PCI_CLASS=30000 +PCI_ID=1002:687F +PCI_SUBSYS_ID=1043:04C4 +PCI_SLOT_NAME=0000:09:00.0 +MODALIAS=pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/unique_id +Lines: 1 +0123456789abcdef +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/vbios_version +Lines: 1 +115-D050PIL-100 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/drm/card0/device/vendor +Lines: 1 +0x1002 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/class/fc_host Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -4978,35 +5432,6 @@ Mode: 644 Directory: fixtures/sys/devices/system Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node1/vmstat -Lines: 6 -nr_free_pages 1 -nr_zone_inactive_anon 2 -nr_zone_active_anon 3 -nr_zone_inactive_file 4 -nr_zone_active_file 5 -nr_zone_unevictable 6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node2/vmstat -Lines: 6 -nr_free_pages 7 -nr_zone_inactive_anon 8 -nr_zone_active_anon 9 -nr_zone_inactive_file 10 -nr_zone_active_file 11 -nr_zone_unevictable 12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/devices/system/clocksource Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5254,6 +5679,35 @@ Mode: 644 Directory: fixtures/sys/devices/system/cpu/cpufreq/policy1 Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node +Mode: 775 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node/node1 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/node/node1/vmstat +Lines: 6 +nr_free_pages 1 +nr_zone_inactive_anon 2 +nr_zone_active_anon 3 +nr_zone_inactive_file 4 +nr_zone_active_file 5 +nr_zone_unevictable 6 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/system/node/node2 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/node/node2/vmstat +Lines: 6 +nr_free_pages 7 +nr_zone_inactive_anon 8 +nr_zone_active_anon 9 +nr_zone_inactive_file 10 +nr_zone_active_file 11 +nr_zone_unevictable 12 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/fs Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sysfs/class_drm_amdgpu_test.go b/sysfs/class_drm_amdgpu_test.go index b9fb1519a..902764e35 100644 --- a/sysfs/class_drm_amdgpu_test.go +++ b/sysfs/class_drm_amdgpu_test.go @@ -20,7 +20,7 @@ import ( "testing" ) -func TestClassDRMCardStats(t *testing.T) { +func TestClassDRMCardAMDGPUStats(t *testing.T) { fs, err := NewFS(sysTestFixtures) if err != nil { t.Fatal(err) From e1d8b423e5bc2383e4944ff65b5579881e84d729 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Sat, 13 Mar 2021 13:37:34 +0100 Subject: [PATCH 15/31] Add check for sysfs build tag CI check to validate that all sysfs files contain a linux-only build tag. Signed-off-by: Ben Kochie --- .circleci/config.yml | 1 + scripts/check_build_tags.sh | 12 ++++++++++++ sysfs/class_nvme.go | 2 ++ sysfs/class_nvme_test.go | 2 +- sysfs/doc.go | 2 ++ sysfs/fs.go | 2 ++ sysfs/fs_test.go | 2 ++ 7 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 scripts/check_build_tags.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index eb700b7ce..d563c54bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,6 +8,7 @@ jobs: steps: - checkout - run: make check_license + - run: ./scripts/check_build_tags.sh - run: make fixtures - run: make update_fixtures - run: git diff --exit-code diff --git a/scripts/check_build_tags.sh b/scripts/check_build_tags.sh new file mode 100755 index 000000000..104769bf1 --- /dev/null +++ b/scripts/check_build_tags.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +fail=0 +while read -r f ; do + if ! grep -q '+build linux' "$f" ; then + echo "missing linux build tag: $f" + fail=1 + fi +done < <(find sysfs -name '*.go') + +exit "${fail}" + diff --git a/sysfs/class_nvme.go b/sysfs/class_nvme.go index 561587427..57e247b16 100644 --- a/sysfs/class_nvme.go +++ b/sysfs/class_nvme.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import ( diff --git a/sysfs/class_nvme_test.go b/sysfs/class_nvme_test.go index d4610ccab..884144736 100644 --- a/sysfs/class_nvme_test.go +++ b/sysfs/class_nvme_test.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !windows +// +build linux package sysfs diff --git a/sysfs/doc.go b/sysfs/doc.go index 9a6c244e9..cb251c81e 100644 --- a/sysfs/doc.go +++ b/sysfs/doc.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + // Package sysfs provides functions to retrieve system and kernel metrics // from the pseudo-filesystem sys. package sysfs diff --git a/sysfs/fs.go b/sysfs/fs.go index b3354f3d5..c11e9a68c 100644 --- a/sysfs/fs.go +++ b/sysfs/fs.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import ( diff --git a/sysfs/fs_test.go b/sysfs/fs_test.go index 2ef5a733e..7745fbe77 100644 --- a/sysfs/fs_test.go +++ b/sysfs/fs_test.go @@ -11,6 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// +build linux + package sysfs import "testing" From 4464b7e61cfabf4c9fb9db8c91b73fdec455c1fb Mon Sep 17 00:00:00 2001 From: prombot Date: Fri, 25 Jun 2021 00:02:10 +0000 Subject: [PATCH 16/31] Update common Prometheus files Signed-off-by: prombot --- Makefile.common | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index ce80d530a..bbdec8ef5 100644 --- a/Makefile.common +++ b/Makefile.common @@ -118,7 +118,7 @@ endif %: common-% ; .PHONY: common-all -common-all: precheck style check_license lint unused build test +common-all: precheck style check_license lint yamllint unused build test .PHONY: common-style common-style: @@ -198,6 +198,11 @@ else endif endif +.PHONY: common-yamllint +common-yamllint: + @echo ">> running yamllint on all YAML files in the repository" + yamllint . + # For backward-compatibility. .PHONY: common-staticcheck common-staticcheck: lint From f90a468106ca5b90cf050ffaba032440b9d31914 Mon Sep 17 00:00:00 2001 From: Eisuke Matsushita Date: Thu, 1 Jul 2021 12:57:46 +0900 Subject: [PATCH 17/31] fix doc.go func (fs FS) NewStat() (Stat, error) is deprecated. Signed-off-by: Eisuke Matsushita --- doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc.go b/doc.go index e2acd6d40..d31a82600 100644 --- a/doc.go +++ b/doc.go @@ -31,7 +31,7 @@ // log.Fatalf("could not get process: %s", err) // } // -// stat, err := p.NewStat() +// stat, err := p.Stat() // if err != nil { // log.Fatalf("could not get process stat: %s", err) // } From 953e37b515b34ee502919458d08ded0b895156b8 Mon Sep 17 00:00:00 2001 From: Luiz Angelo Daros de Luca Date: Fri, 21 May 2021 15:14:57 -0300 Subject: [PATCH 18/31] Add scsi_tape parser Signed-off-by: Luiz Angelo Daros de Luca --- fixtures.ttar | 496 +++++++++++++++++++++++++++++++++++ sysfs/class_scsitape.go | 140 ++++++++++ sysfs/class_scsitape_test.go | 56 ++++ 3 files changed, 692 insertions(+) create mode 100644 sysfs/class_scsitape.go create mode 100644 sysfs/class_scsitape_test.go diff --git a/fixtures.ttar b/fixtures.ttar index a4ed426d9..34c1d7075 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -4644,6 +4644,33 @@ Path: fixtures/sys/class/powercap/intel-rapl:a/uevent Lines: 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/scsi_tape +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/nst0 +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/nst0a +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/nst0l +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/nst0m +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/st0 +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/st0a +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/st0l +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/scsi_tape/st0m +SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/class/thermal Mode: 775 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5055,6 +5082,475 @@ Mode: 444 Directory: fixtures/sys/devices/pci0000:00 Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/in_flight +Lines: 1 +1EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/io_ns +Lines: 1 +9247011087720EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/other_cnt +Lines: 1 +1409EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_byte_cnt +Lines: 1 +979383912EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_cnt +Lines: 1 +3741EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_ns +Lines: 1 +33788355744EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/resid_cnt +Lines: 1 +19EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_byte_cnt +Lines: 1 +1496246784000EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_cnt +Lines: 1 +53772916EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_ns +Lines: 1 +5233597394395EOF +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0 Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sysfs/class_scsitape.go b/sysfs/class_scsitape.go new file mode 100644 index 000000000..d227c10fa --- /dev/null +++ b/sysfs/class_scsitape.go @@ -0,0 +1,140 @@ +// Copyright 2021 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 linux + +package sysfs + +import ( + "fmt" + "io/ioutil" + "path/filepath" + "regexp" + + "github.com/prometheus/procfs/internal/util" +) + +const scsiTapeClassPath = "class/scsi_tape" + +type SCSITapeCounters struct { + WriteNs uint64 // /sys/class/scsi_tape//stats/write_ns + ReadByteCnt uint64 // /sys/class/scsi_tape//stats/read_byte_cnt + IoNs uint64 // /sys/class/scsi_tape//stats/io_ns + WriteCnt uint64 // /sys/class/scsi_tape//stats/write_cnt + ResidCnt uint64 // /sys/class/scsi_tape//stats/resid_cnt + ReadNs uint64 // /sys/class/scsi_tape//stats/read_ns + InFlight uint64 // /sys/class/scsi_tape//stats/in_flight + OtherCnt uint64 // /sys/class/scsi_tape//stats/other_cnt + ReadCnt uint64 // /sys/class/scsi_tape//stats/read_cnt + WriteByteCnt uint64 // /sys/class/scsi_tape//stats/write_byte_cnt +} + +type SCSITape struct { + Name string // /sys/class/scsi_tape/ + Counters SCSITapeCounters // /sys/class/scsi_tape//statistics/* +} + +type SCSITapeClass map[string]SCSITape + +// SCSITapeClass parses st[0-9]+ devices in /sys/class/scsi_tape. +func (fs FS) SCSITapeClass() (SCSITapeClass, error) { + path := fs.sys.Path(scsiTapeClassPath) + + dirs, err := ioutil.ReadDir(path) + if err != nil { + return nil, err + } + + // There are n?st[0-9]+[a-b]? variants depending on device features. + // n/2 is probably overestimated but never underestimated + stc := make(SCSITapeClass, len(dirs)/2) + validDevice := regexp.MustCompile(`^st[0-9]+$`) + + for _, d := range dirs { + if !validDevice.Match([]byte(d.Name())) { + continue + } + tape, err := fs.parseSCSITape(d.Name()) + if err != nil { + return nil, err + } + + stc[tape.Name] = *tape + } + + return stc, nil +} + +// Parse a single scsi_tape +func (fs FS) parseSCSITape(name string) (*SCSITape, error) { + path := fs.sys.Path(scsiTapeClassPath, name) + tape := SCSITape{Name: name} + + counters, err := parseSCSITapeStatistics(path) + if err != nil { + return nil, err + } + tape.Counters = *counters + + return &tape, nil +} + +// parseSCSITapeStatistics parses metrics from a single tape. +func parseSCSITapeStatistics(tapePath string) (*SCSITapeCounters, error) { + var counters SCSITapeCounters + + path := filepath.Join(tapePath, "stats") + files, err := ioutil.ReadDir(path) + if err != nil { + return nil, err + } + + for _, f := range files { + name := filepath.Join(path, f.Name()) + value, err := util.SysReadFile(name) + if err != nil { + return nil, fmt.Errorf("failed to read file %q: %w", name, err) + } + + vp := util.NewValueParser(value) + switch f.Name() { + case "in_flight": + counters.InFlight = *vp.PUInt64() + case "io_ns": + counters.IoNs = *vp.PUInt64() + case "other_cnt": + counters.OtherCnt = *vp.PUInt64() + case "read_byte_cnt": + counters.ReadByteCnt = *vp.PUInt64() + case "read_cnt": + counters.ReadCnt = *vp.PUInt64() + case "read_ns": + counters.ReadNs = *vp.PUInt64() + case "resid_cnt": + counters.ResidCnt = *vp.PUInt64() + case "write_byte_cnt": + counters.WriteByteCnt = *vp.PUInt64() + case "write_cnt": + counters.WriteCnt = *vp.PUInt64() + case "write_ns": + counters.WriteNs = *vp.PUInt64() + } + + if err := vp.Err(); err != nil { + return nil, err + } + + } + + return &counters, nil +} diff --git a/sysfs/class_scsitape_test.go b/sysfs/class_scsitape_test.go new file mode 100644 index 000000000..17480d441 --- /dev/null +++ b/sysfs/class_scsitape_test.go @@ -0,0 +1,56 @@ +// Copyright 2021 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 linux + +package sysfs + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestSCSITapeClass(t *testing.T) { + fs, err := NewFS(sysTestFixtures) + if err != nil { + t.Fatal(err) + } + + got, err := fs.SCSITapeClass() + if err != nil { + t.Fatal(err) + } + + want := SCSITapeClass{ + "st0": SCSITape{ + Name: "st0", + Counters: SCSITapeCounters{ + WriteNs: 5233597394395, + ReadByteCnt: 979383912, + IoNs: 9247011087720, + WriteCnt: 53772916, + WriteByteCnt: 1496246784000, + ResidCnt: 19, + ReadNs: 33788355744, + InFlight: 1, + OtherCnt: 1409, + ReadCnt: 3741, + }, + }, + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("unexpected SCSITape class (-want +got):\n%s", diff) + } +} From 99f3c3718eb80878c45873c659eb6603e9024329 Mon Sep 17 00:00:00 2001 From: John Seekins Date: Mon, 5 Jul 2021 09:17:10 -0600 Subject: [PATCH 19/31] add additional stats from mdstat (#380) * Add several Infiniband counters Counters added: * excessive_buffer_overrun_errors * local_link_integrity_errors Signed-off-by: Trey Dockendorf Signed-off-by: John Seekins * add additional stats from mdstat Signed-off-by: John Seekins * return successful values every time Signed-off-by: John Seekins * add count of 'downed' disks Signed-off-by: John Seekins Co-authored-by: Trey Dockendorf --- mdstat.go | 105 ++++++++++++++++++++++++++++++++++++------------- mdstat_test.go | 34 ++++++++-------- 2 files changed, 94 insertions(+), 45 deletions(-) diff --git a/mdstat.go b/mdstat.go index 4c4493bfa..f0b9e5f75 100644 --- a/mdstat.go +++ b/mdstat.go @@ -22,9 +22,12 @@ import ( ) var ( - statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[[U_]+\]`) - recoveryLineRE = regexp.MustCompile(`\((\d+)/\d+\)`) - componentDeviceRE = regexp.MustCompile(`(.*)\[\d+\]`) + statusLineRE = regexp.MustCompile(`(\d+) blocks .*\[(\d+)/(\d+)\] \[([U_]+)\]`) + recoveryLineBlocksRE = regexp.MustCompile(`\((\d+)/\d+\)`) + recoveryLinePctRE = regexp.MustCompile(`= (.+)%`) + recoveryLineFinishRE = regexp.MustCompile(`finish=(.+)min`) + recoveryLineSpeedRE = regexp.MustCompile(`speed=(.+)[A-Z]`) + componentDeviceRE = regexp.MustCompile(`(.*)\[\d+\]`) ) // MDStat holds info parsed from /proc/mdstat. @@ -39,12 +42,20 @@ type MDStat struct { DisksTotal int64 // Number of failed disks. DisksFailed int64 + // Number of "down" disks. (the _ indicator in the status line) + DisksDown int64 // Spare disks in the device. DisksSpare int64 // Number of blocks the device holds. BlocksTotal int64 // Number of blocks on the device that are in sync. BlocksSynced int64 + // progress percentage of current sync + BlocksSyncedPct float64 + // estimated finishing time for current sync (in minutes) + BlocksSyncedFinishTime float64 + // current sync speed (in Kilobytes/sec) + BlocksSyncedSpeed float64 // Name of md component devices Devices []string } @@ -91,7 +102,7 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { // Failed disks have the suffix (F) & Spare disks have the suffix (S). fail := int64(strings.Count(line, "(F)")) spare := int64(strings.Count(line, "(S)")) - active, total, size, err := evalStatusLine(lines[i], lines[i+1]) + active, total, down, size, err := evalStatusLine(lines[i], lines[i+1]) if err != nil { return nil, fmt.Errorf("error parsing md device lines: %w", err) @@ -105,6 +116,9 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { // If device is syncing at the moment, get the number of currently // synced bytes, otherwise that number equals the size of the device. syncedBlocks := size + speed := float64(0) + finish := float64(0) + pct := float64(0) recovering := strings.Contains(lines[syncLineIdx], "recovery") resyncing := strings.Contains(lines[syncLineIdx], "resync") checking := strings.Contains(lines[syncLineIdx], "check") @@ -124,7 +138,7 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { strings.Contains(lines[syncLineIdx], "DELAYED") { syncedBlocks = 0 } else { - syncedBlocks, err = evalRecoveryLine(lines[syncLineIdx]) + syncedBlocks, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx]) if err != nil { return nil, fmt.Errorf("error parsing sync line in md device %q: %w", mdName, err) } @@ -132,69 +146,104 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { } mdStats = append(mdStats, MDStat{ - Name: mdName, - ActivityState: state, - DisksActive: active, - DisksFailed: fail, - DisksSpare: spare, - DisksTotal: total, - BlocksTotal: size, - BlocksSynced: syncedBlocks, - Devices: evalComponentDevices(deviceFields), + Name: mdName, + ActivityState: state, + DisksActive: active, + DisksFailed: fail, + DisksDown: down, + DisksSpare: spare, + DisksTotal: total, + BlocksTotal: size, + BlocksSynced: syncedBlocks, + BlocksSyncedPct: pct, + BlocksSyncedFinishTime: finish, + BlocksSyncedSpeed: speed, + Devices: evalComponentDevices(deviceFields), }) } return mdStats, nil } -func evalStatusLine(deviceLine, statusLine string) (active, total, size int64, err error) { +func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { sizeStr := strings.Fields(statusLine)[0] size, err = strconv.ParseInt(sizeStr, 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) + return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) } if strings.Contains(deviceLine, "raid0") || strings.Contains(deviceLine, "linear") { // In the device deviceLine, only disks have a number associated with them in []. total = int64(strings.Count(deviceLine, "[")) - return total, total, size, nil + return total, total, 0, size, nil } if strings.Contains(deviceLine, "inactive") { - return 0, 0, size, nil + return 0, 0, 0, size, nil } matches := statusLineRE.FindStringSubmatch(statusLine) - if len(matches) != 4 { - return 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine) + if len(matches) != 5 { + return 0, 0, 0, 0, fmt.Errorf("couldn't find all the substring matches: %s", statusLine) } total, err = strconv.ParseInt(matches[2], 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) + return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) } active, err = strconv.ParseInt(matches[3], 10, 64) if err != nil { - return 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) + return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) } + down = int64(strings.Count(matches[4], "_")) - return active, total, size, nil + return active, total, down, size, nil } -func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, err error) { - matches := recoveryLineRE.FindStringSubmatch(recoveryLine) +func evalRecoveryLine(recoveryLine string) (syncedBlocks int64, pct float64, finish float64, speed float64, err error) { + matches := recoveryLineBlocksRE.FindStringSubmatch(recoveryLine) if len(matches) != 2 { - return 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine) + return 0, 0, 0, 0, fmt.Errorf("unexpected recoveryLine: %s", recoveryLine) } syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64) if err != nil { - return 0, fmt.Errorf("error parsing int from recoveryLine %q: %w", recoveryLine, err) + return 0, 0, 0, 0, fmt.Errorf("error parsing int from recoveryLine %q: %w", recoveryLine, err) } - return syncedBlocks, nil + // Get percentage complete + matches = recoveryLinePctRE.FindStringSubmatch(recoveryLine) + if len(matches) != 2 { + return syncedBlocks, 0, 0, 0, fmt.Errorf("unexpected recoveryLine matching percentage: %s", recoveryLine) + } + pct, err = strconv.ParseFloat(strings.TrimSpace(matches[1]), 64) + if err != nil { + return syncedBlocks, 0, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err) + } + + // Get time expected left to complete + matches = recoveryLineFinishRE.FindStringSubmatch(recoveryLine) + if len(matches) != 2 { + return syncedBlocks, pct, 0, 0, fmt.Errorf("unexpected recoveryLine matching est. finish time: %s", recoveryLine) + } + finish, err = strconv.ParseFloat(matches[1], 64) + if err != nil { + return syncedBlocks, pct, 0, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err) + } + + // Get recovery speed + matches = recoveryLineSpeedRE.FindStringSubmatch(recoveryLine) + if len(matches) != 2 { + return syncedBlocks, pct, finish, 0, fmt.Errorf("unexpected recoveryLine matching speed: %s", recoveryLine) + } + speed, err = strconv.ParseFloat(matches[1], 64) + if err != nil { + return syncedBlocks, pct, finish, 0, fmt.Errorf("error parsing float from recoveryLine %q: %w", recoveryLine, err) + } + + return syncedBlocks, pct, finish, speed, nil } func evalComponentDevices(deviceFields []string) []string { diff --git a/mdstat_test.go b/mdstat_test.go index 1b9a8ea81..d572cb346 100644 --- a/mdstat_test.go +++ b/mdstat_test.go @@ -25,23 +25,23 @@ func TestFS_MDStat(t *testing.T) { } refs := map[string]MDStat{ - "md127": {Name: "md127", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 312319552, BlocksSynced: 312319552, Devices: []string{"sdi2", "sdj2"}}, - "md0": {Name: "md0", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 248896, BlocksSynced: 248896, Devices: []string{"sdi1", "sdj1"}}, - "md4": {Name: "md4", ActivityState: "inactive", DisksActive: 0, DisksTotal: 0, DisksFailed: 1, DisksSpare: 1, BlocksTotal: 4883648, BlocksSynced: 4883648, Devices: []string{"sda3", "sdb3"}}, - "md6": {Name: "md6", ActivityState: "recovering", DisksActive: 1, DisksTotal: 2, DisksFailed: 1, DisksSpare: 1, BlocksTotal: 195310144, BlocksSynced: 16775552, Devices: []string{"sdb2", "sdc", "sda2"}}, - "md3": {Name: "md3", ActivityState: "active", DisksActive: 8, DisksTotal: 8, DisksFailed: 0, DisksSpare: 2, BlocksTotal: 5853468288, BlocksSynced: 5853468288, Devices: []string{"sda1", "sdh1", "sdg1", "sdf1", "sde1", "sdd1", "sdc1", "sdb1", "sdd1", "sdd2"}}, - "md8": {Name: "md8", ActivityState: "resyncing", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 2, BlocksTotal: 195310144, BlocksSynced: 16775552, Devices: []string{"sdb1", "sda1", "sdc", "sde"}}, - "md7": {Name: "md7", ActivityState: "active", DisksActive: 3, DisksTotal: 4, DisksFailed: 1, DisksSpare: 0, BlocksTotal: 7813735424, BlocksSynced: 7813735424, Devices: []string{"sdb1", "sde1", "sdd1", "sdc1"}}, - "md9": {Name: "md9", ActivityState: "resyncing", DisksActive: 4, DisksTotal: 4, DisksSpare: 1, DisksFailed: 2, BlocksTotal: 523968, BlocksSynced: 0, Devices: []string{"sdc2", "sdd2", "sdb2", "sda2", "sde", "sdf", "sdg"}}, - "md10": {Name: "md10", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 314159265, BlocksSynced: 314159265, Devices: []string{"sda1", "sdb1"}}, - "md11": {Name: "md11", ActivityState: "resyncing", DisksActive: 2, DisksTotal: 2, DisksFailed: 1, DisksSpare: 2, BlocksTotal: 4190208, BlocksSynced: 0, Devices: []string{"sdb2", "sdc2", "sdc3", "hda", "ssdc2"}}, - "md12": {Name: "md12", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksSpare: 0, DisksFailed: 0, BlocksTotal: 3886394368, BlocksSynced: 3886394368, Devices: []string{"sdc2", "sdd2"}}, - "md120": {Name: "md120", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 2095104, BlocksSynced: 2095104, Devices: []string{"sda1", "sdb1"}}, - "md126": {Name: "md126", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 1855870976, BlocksSynced: 1855870976, Devices: []string{"sdb", "sdc"}}, - "md219": {Name: "md219", ActivityState: "inactive", DisksTotal: 0, DisksFailed: 0, DisksActive: 0, DisksSpare: 3, BlocksTotal: 7932, BlocksSynced: 7932, Devices: []string{"sdc", "sda"}}, - "md00": {Name: "md00", ActivityState: "active", DisksActive: 1, DisksTotal: 1, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 4186624, BlocksSynced: 4186624, Devices: []string{"xvdb"}}, - "md101": {Name: "md101", ActivityState: "active", DisksActive: 3, DisksTotal: 3, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 322560, BlocksSynced: 322560, Devices: []string{"sdb", "sdd", "sdc"}}, - "md201": {Name: "md201", ActivityState: "checking", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksSpare: 0, BlocksTotal: 1993728, BlocksSynced: 114176, Devices: []string{"sda3", "sdb3"}}, + "md127": {Name: "md127", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 312319552, BlocksSynced: 312319552, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdi2", "sdj2"}}, + "md0": {Name: "md0", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 248896, BlocksSynced: 248896, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdi1", "sdj1"}}, + "md4": {Name: "md4", ActivityState: "inactive", DisksActive: 0, DisksTotal: 0, DisksFailed: 1, DisksDown: 0, DisksSpare: 1, BlocksTotal: 4883648, BlocksSynced: 4883648, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sda3", "sdb3"}}, + "md6": {Name: "md6", ActivityState: "recovering", DisksActive: 1, DisksTotal: 2, DisksFailed: 1, DisksDown: 1, DisksSpare: 1, BlocksTotal: 195310144, BlocksSynced: 16775552, BlocksSyncedPct: 8.5, BlocksSyncedFinishTime: 17, BlocksSyncedSpeed: 259783, Devices: []string{"sdb2", "sdc", "sda2"}}, + "md3": {Name: "md3", ActivityState: "active", DisksActive: 8, DisksTotal: 8, DisksFailed: 0, DisksDown: 0, DisksSpare: 2, BlocksTotal: 5853468288, BlocksSynced: 5853468288, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sda1", "sdh1", "sdg1", "sdf1", "sde1", "sdd1", "sdc1", "sdb1", "sdd1", "sdd2"}}, + "md8": {Name: "md8", ActivityState: "resyncing", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 2, BlocksTotal: 195310144, BlocksSynced: 16775552, BlocksSyncedPct: 8.5, BlocksSyncedFinishTime: 17, BlocksSyncedSpeed: 259783, Devices: []string{"sdb1", "sda1", "sdc", "sde"}}, + "md7": {Name: "md7", ActivityState: "active", DisksActive: 3, DisksTotal: 4, DisksFailed: 1, DisksDown: 1, DisksSpare: 0, BlocksTotal: 7813735424, BlocksSynced: 7813735424, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdb1", "sde1", "sdd1", "sdc1"}}, + "md9": {Name: "md9", ActivityState: "resyncing", DisksActive: 4, DisksTotal: 4, DisksSpare: 1, DisksDown: 0, DisksFailed: 2, BlocksTotal: 523968, BlocksSynced: 0, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdc2", "sdd2", "sdb2", "sda2", "sde", "sdf", "sdg"}}, + "md10": {Name: "md10", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 314159265, BlocksSynced: 314159265, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sda1", "sdb1"}}, + "md11": {Name: "md11", ActivityState: "resyncing", DisksActive: 2, DisksTotal: 2, DisksFailed: 1, DisksDown: 0, DisksSpare: 2, BlocksTotal: 4190208, BlocksSynced: 0, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdb2", "sdc2", "sdc3", "hda", "ssdc2"}}, + "md12": {Name: "md12", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksSpare: 0, DisksDown: 0, DisksFailed: 0, BlocksTotal: 3886394368, BlocksSynced: 3886394368, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdc2", "sdd2"}}, + "md120": {Name: "md120", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 2095104, BlocksSynced: 2095104, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sda1", "sdb1"}}, + "md126": {Name: "md126", ActivityState: "active", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 1855870976, BlocksSynced: 1855870976, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdb", "sdc"}}, + "md219": {Name: "md219", ActivityState: "inactive", DisksTotal: 0, DisksFailed: 0, DisksActive: 0, DisksDown: 0, DisksSpare: 3, BlocksTotal: 7932, BlocksSynced: 7932, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdc", "sda"}}, + "md00": {Name: "md00", ActivityState: "active", DisksActive: 1, DisksTotal: 1, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 4186624, BlocksSynced: 4186624, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"xvdb"}}, + "md101": {Name: "md101", ActivityState: "active", DisksActive: 3, DisksTotal: 3, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 322560, BlocksSynced: 322560, BlocksSyncedPct: 0, BlocksSyncedFinishTime: 0, BlocksSyncedSpeed: 0, Devices: []string{"sdb", "sdd", "sdc"}}, + "md201": {Name: "md201", ActivityState: "checking", DisksActive: 2, DisksTotal: 2, DisksFailed: 0, DisksDown: 0, DisksSpare: 0, BlocksTotal: 1993728, BlocksSynced: 114176, BlocksSyncedPct: 5.7, BlocksSyncedFinishTime: 0.2, BlocksSyncedSpeed: 114176, Devices: []string{"sda3", "sdb3"}}, } if want, have := len(refs), len(mdStats); want != have { From b62dc6f496de715cbdeeb22300f3067a60228a87 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Mon, 5 Jul 2021 17:17:33 +0200 Subject: [PATCH 20/31] Add CmdLine function to parse /proc/cmdline (#393) Our company internal Prometheus exporter uses the procfs library and needs to read `/proc/cmdline`. Since `fs.proc.Path` cannot be accessed from outside, add `CmdLine` to procfs to read `/proc/cmdline`. Signed-off-by: Benjamin Drung --- cmdline.go | 30 ++++++++++++++++++++++++++++++ cmdline_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ fixtures.ttar | 5 +++++ 3 files changed, 82 insertions(+) create mode 100644 cmdline.go create mode 100644 cmdline_test.go diff --git a/cmdline.go b/cmdline.go new file mode 100644 index 000000000..bf4f3b48c --- /dev/null +++ b/cmdline.go @@ -0,0 +1,30 @@ +// Copyright 2021 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. + +package procfs + +import ( + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// CmdLine returns the command line of the kernel. +func (fs FS) CmdLine() ([]string, error) { + data, err := util.ReadFileNoStat(fs.proc.Path("cmdline")) + if err != nil { + return nil, err + } + + return strings.Fields(string(data)), nil +} diff --git a/cmdline_test.go b/cmdline_test.go new file mode 100644 index 000000000..f9cc1b829 --- /dev/null +++ b/cmdline_test.go @@ -0,0 +1,47 @@ +// Copyright 2021 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 linux + +package procfs + +import ( + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestCmdline(t *testing.T) { + fs, err := NewFS(procTestFixtures) + if err != nil { + t.Fatal(err) + } + + got, err := fs.CmdLine() + if err != nil { + t.Fatal(err) + } + + want := []string{ + "BOOT_IMAGE=/vmlinuz-5.11.0-22-generic", + "root=UUID=456a0345-450d-4f7b-b7c9-43e3241d99ad", + "ro", + "quiet", + "splash", + "vt.handoff=7", + } + + if diff := cmp.Diff(want, got); diff != "" { + t.Fatalf("unexpected CmdLine (-want +got):\n%s", diff) + } +} diff --git a/fixtures.ttar b/fixtures.ttar index 34c1d7075..8dc6c1b0b 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -644,6 +644,11 @@ Node 0, zone DMA32 759 572 791 475 194 45 12 0 Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/proc/cmdline +Lines: 1 +BOOT_IMAGE=/vmlinuz-5.11.0-22-generic root=UUID=456a0345-450d-4f7b-b7c9-43e3241d99ad ro quiet splash vt.handoff=7 +Mode: 444 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/proc/cpuinfo Lines: 216 processor : 0 From 6299d7d78bc2c07187a14d50e92f0c68b128eff5 Mon Sep 17 00:00:00 2001 From: Ian Kirker Date: Mon, 5 Jul 2021 16:18:44 +0100 Subject: [PATCH 21/31] Initial fix for non-detection of OmniPath cards (#387) * Fixes InfiniBand fileset incompatibility with OmniPath cards (#341) Currently these cards aren't picked up correctly because the driver doesn't provide the hca_type file the parse function expects. This patch stops the parse function treating that as an error. Signed-off-by: Ian Kirker * Adds test for OmniPath device detection This adds fixtures and a test for the OmniPath detection and metric reading added in a previous commit. This could use a check from someone better acquainted with the driver and relevant metrics, but it should do some approximation of the job for now. It might even be sensible to specifically detect major versions of devices, since the detailed metric file layout might even vary between mlx4 and mlx5. There's also a factor of 4 included in the Mellanox metric pickup that I'm not sure about: might need to detect device to tell whether we need that, and that's a bit more work. Signed-off-by: Ian Kirker * Fixes some mistakes that slipped in during merge/rebase Whoops. Signed-off-by: Ian Kirker --- fixtures.ttar | 122 +++++++++++++++++++++ sysfs/class_infiniband.go | 4 + sysfs/class_infiniband_test.go | 190 +++++++++++++++++++++------------ 3 files changed, 248 insertions(+), 68 deletions(-) diff --git a/fixtures.ttar b/fixtures.ttar index 8dc6c1b0b..e7d35069c 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -4051,6 +4051,128 @@ Mode: 644 Directory: fixtures/sys/class/infiniband Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/infiniband/hfi1_0 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/board_id +Lines: 1 +HPE 100Gb 1-port OP101 QSFP28 x16 PCIe Gen3 with Intel Omni-Path Adapter +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/fw_ver +Lines: 1 +1.27.0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/infiniband/hfi1_0/ports +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1 +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/VL15_dropped +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/excessive_buffer_overrun_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_downed +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_error_recovery +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/local_link_integrity_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_constraint_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_data +Lines: 1 +345091702026 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_packets +Lines: 1 +638036947 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_remote_physical_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_switch_relay_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_constraint_errors +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_data +Lines: 1 +273558326543 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_discards +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_packets +Lines: 1 +568318856 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_wait +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/symbol_error +Lines: 1 +0 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/phys_state +Lines: 1 +5: LinkUp +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/rate +Lines: 1 +100 Gb/sec (4X EDR) +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/state +Lines: 1 +4: ACTIVE +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Directory: fixtures/sys/class/infiniband/mlx4_0 Mode: 755 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sysfs/class_infiniband.go b/sysfs/class_infiniband.go index e9ee28460..7adebe888 100644 --- a/sysfs/class_infiniband.go +++ b/sysfs/class_infiniband.go @@ -128,6 +128,10 @@ func (fs FS) parseInfiniBandDevice(name string) (*InfiniBandDevice, error) { name := filepath.Join(path, f) value, err := util.SysReadFile(name) if err != nil { + // Not all InfiniBand drivers provide hca_type. + if os.IsNotExist(err) && (f == "hca_type") { + continue + } return nil, fmt.Errorf("failed to read file %q: %w", name, err) } diff --git a/sysfs/class_infiniband_test.go b/sysfs/class_infiniband_test.go index d7592ea51..79f4b1fb5 100644 --- a/sysfs/class_infiniband_test.go +++ b/sysfs/class_infiniband_test.go @@ -63,44 +63,98 @@ func TestInfiniBandClass(t *testing.T) { } var ( - port1ExcessiveBufferOverrunErrors uint64 - port1LinkDowned uint64 - port1LinkErrorRecovery uint64 - port1LocalLinkIntegrityErrors uint64 - port1PortRcvConstraintErrors uint64 - port1PortRcvData uint64 = 8884894436 - port1PortRcvErrors uint64 - port1PortRcvPackets uint64 = 87169372 - port1PortRcvRemotePhysicalErrors uint64 - port1PortRcvSwitchRelayErrors uint64 - port1PortXmitConstraintErrors uint64 - port1PortXmitData uint64 = 106036453180 - port1PortXmitDiscards uint64 - port1PortXmitPackets uint64 = 85734114 - port1PortXmitWait uint64 = 3599 - port1SymbolError uint64 - port1VL15Dropped uint64 + hfi1Port1ExcessiveBufferOverrunErrors uint64 + hfi1Port1LinkDowned uint64 + hfi1Port1LinkErrorRecovery uint64 + hfi1Port1LocalLinkIntegrityErrors uint64 + hfi1Port1PortRcvConstraintErrors uint64 + hfi1Port1PortRcvData uint64 = 1380366808104 + hfi1Port1PortRcvErrors uint64 + hfi1Port1PortRcvPackets uint64 = 638036947 + hfi1Port1PortRcvRemotePhysicalErrors uint64 + hfi1Port1PortRcvSwitchRelayErrors uint64 + hfi1Port1PortXmitConstraintErrors uint64 + hfi1Port1PortXmitData uint64 = 1094233306172 + hfi1Port1PortXmitDiscards uint64 + hfi1Port1PortXmitPackets uint64 = 568318856 + hfi1Port1PortXmitWait uint64 + hfi1Port1SymbolError uint64 + hfi1Port1VL15Dropped uint64 - port2ExcessiveBufferOverrunErrors uint64 - port2LinkDowned uint64 - port2LinkErrorRecovery uint64 - port2LocalLinkIntegrityErrors uint64 - port2PortRcvConstraintErrors uint64 - port2PortRcvData uint64 = 9841747136 - port2PortRcvErrors uint64 - port2PortRcvPackets uint64 = 89332064 - port2PortRcvRemotePhysicalErrors uint64 - port2PortRcvSwitchRelayErrors uint64 - port2PortXmitConstraintErrors uint64 - port2PortXmitData uint64 = 106161427560 - port2PortXmitDiscards uint64 - port2PortXmitPackets uint64 = 88622850 - port2PortXmitWait uint64 = 3846 - port2SymbolError uint64 - port2VL15Dropped uint64 + mlx4Port1ExcessiveBufferOverrunErrors uint64 + mlx4Port1LinkDowned uint64 + mlx4Port1LinkErrorRecovery uint64 + mlx4Port1LocalLinkIntegrityErrors uint64 + mlx4Port1PortRcvConstraintErrors uint64 + mlx4Port1PortRcvData uint64 = 8884894436 + mlx4Port1PortRcvErrors uint64 + mlx4Port1PortRcvPackets uint64 = 87169372 + mlx4Port1PortRcvRemotePhysicalErrors uint64 + mlx4Port1PortRcvSwitchRelayErrors uint64 + mlx4Port1PortXmitConstraintErrors uint64 + mlx4Port1PortXmitData uint64 = 106036453180 + mlx4Port1PortXmitDiscards uint64 + mlx4Port1PortXmitPackets uint64 = 85734114 + mlx4Port1PortXmitWait uint64 = 3599 + mlx4Port1SymbolError uint64 + mlx4Port1VL15Dropped uint64 + + mlx4Port2ExcessiveBufferOverrunErrors uint64 + mlx4Port2LinkDowned uint64 + mlx4Port2LinkErrorRecovery uint64 + mlx4Port2LocalLinkIntegrityErrors uint64 + mlx4Port2PortRcvConstraintErrors uint64 + mlx4Port2PortRcvData uint64 = 9841747136 + mlx4Port2PortRcvErrors uint64 + mlx4Port2PortRcvPackets uint64 = 89332064 + mlx4Port2PortRcvRemotePhysicalErrors uint64 + mlx4Port2PortRcvSwitchRelayErrors uint64 + mlx4Port2PortXmitConstraintErrors uint64 + mlx4Port2PortXmitData uint64 = 106161427560 + mlx4Port2PortXmitDiscards uint64 + mlx4Port2PortXmitPackets uint64 = 88622850 + mlx4Port2PortXmitWait uint64 = 3846 + mlx4Port2SymbolError uint64 + mlx4Port2VL15Dropped uint64 ) want := InfiniBandClass{ + "hfi1_0": InfiniBandDevice{ + Name: "hfi1_0", + BoardID: "HPE 100Gb 1-port OP101 QSFP28 x16 PCIe Gen3 with Intel Omni-Path Adapter", + FirmwareVersion: "1.27.0", + HCAType: "", + Ports: map[uint]InfiniBandPort{ + 1: { + Name: "hfi1_0", + Port: 1, + State: "ACTIVE", + StateID: 4, + PhysState: "LinkUp", + PhysStateID: 5, + Rate: 12500000000, + Counters: InfiniBandCounters{ + ExcessiveBufferOverrunErrors: &hfi1Port1ExcessiveBufferOverrunErrors, + LinkDowned: &hfi1Port1LinkDowned, + LinkErrorRecovery: &hfi1Port1LinkErrorRecovery, + LocalLinkIntegrityErrors: &hfi1Port1LocalLinkIntegrityErrors, + PortRcvConstraintErrors: &hfi1Port1PortRcvConstraintErrors, + PortRcvData: &hfi1Port1PortRcvData, + PortRcvErrors: &hfi1Port1PortRcvErrors, + PortRcvPackets: &hfi1Port1PortRcvPackets, + PortRcvRemotePhysicalErrors: &hfi1Port1PortRcvRemotePhysicalErrors, + PortRcvSwitchRelayErrors: &hfi1Port1PortRcvSwitchRelayErrors, + PortXmitConstraintErrors: &hfi1Port1PortXmitConstraintErrors, + PortXmitData: &hfi1Port1PortXmitData, + PortXmitDiscards: &hfi1Port1PortXmitDiscards, + PortXmitPackets: &hfi1Port1PortXmitPackets, + PortXmitWait: &hfi1Port1PortXmitWait, + SymbolError: &hfi1Port1SymbolError, + VL15Dropped: &hfi1Port1VL15Dropped, + }, + }, + }, + }, "mlx4_0": InfiniBandDevice{ Name: "mlx4_0", BoardID: "SM_1141000001000", @@ -116,23 +170,23 @@ func TestInfiniBandClass(t *testing.T) { PhysStateID: 5, Rate: 5000000000, Counters: InfiniBandCounters{ - ExcessiveBufferOverrunErrors: &port1ExcessiveBufferOverrunErrors, - LinkDowned: &port1LinkDowned, - LinkErrorRecovery: &port1LinkErrorRecovery, - LocalLinkIntegrityErrors: &port1LocalLinkIntegrityErrors, - PortRcvConstraintErrors: &port1PortRcvConstraintErrors, - PortRcvData: &port1PortRcvData, - PortRcvErrors: &port1PortRcvErrors, - PortRcvPackets: &port1PortRcvPackets, - PortRcvRemotePhysicalErrors: &port1PortRcvRemotePhysicalErrors, - PortRcvSwitchRelayErrors: &port1PortRcvSwitchRelayErrors, - PortXmitConstraintErrors: &port1PortXmitConstraintErrors, - PortXmitData: &port1PortXmitData, - PortXmitDiscards: &port1PortXmitDiscards, - PortXmitPackets: &port1PortXmitPackets, - PortXmitWait: &port1PortXmitWait, - SymbolError: &port1SymbolError, - VL15Dropped: &port1VL15Dropped, + ExcessiveBufferOverrunErrors: &mlx4Port1ExcessiveBufferOverrunErrors, + LinkDowned: &mlx4Port1LinkDowned, + LinkErrorRecovery: &mlx4Port1LinkErrorRecovery, + LocalLinkIntegrityErrors: &mlx4Port1LocalLinkIntegrityErrors, + PortRcvConstraintErrors: &mlx4Port1PortRcvConstraintErrors, + PortRcvData: &mlx4Port1PortRcvData, + PortRcvErrors: &mlx4Port1PortRcvErrors, + PortRcvPackets: &mlx4Port1PortRcvPackets, + PortRcvRemotePhysicalErrors: &mlx4Port1PortRcvRemotePhysicalErrors, + PortRcvSwitchRelayErrors: &mlx4Port1PortRcvSwitchRelayErrors, + PortXmitConstraintErrors: &mlx4Port1PortXmitConstraintErrors, + PortXmitData: &mlx4Port1PortXmitData, + PortXmitDiscards: &mlx4Port1PortXmitDiscards, + PortXmitPackets: &mlx4Port1PortXmitPackets, + PortXmitWait: &mlx4Port1PortXmitWait, + SymbolError: &mlx4Port1SymbolError, + VL15Dropped: &mlx4Port1VL15Dropped, }, }, 2: { @@ -144,23 +198,23 @@ func TestInfiniBandClass(t *testing.T) { PhysStateID: 5, Rate: 5000000000, Counters: InfiniBandCounters{ - ExcessiveBufferOverrunErrors: &port2ExcessiveBufferOverrunErrors, - LinkDowned: &port2LinkDowned, - LinkErrorRecovery: &port2LinkErrorRecovery, - LocalLinkIntegrityErrors: &port2LocalLinkIntegrityErrors, - PortRcvConstraintErrors: &port2PortRcvConstraintErrors, - PortRcvData: &port2PortRcvData, - PortRcvErrors: &port2PortRcvErrors, - PortRcvPackets: &port2PortRcvPackets, - PortRcvRemotePhysicalErrors: &port2PortRcvRemotePhysicalErrors, - PortRcvSwitchRelayErrors: &port2PortRcvSwitchRelayErrors, - PortXmitConstraintErrors: &port2PortXmitConstraintErrors, - PortXmitData: &port2PortXmitData, - PortXmitDiscards: &port2PortXmitDiscards, - PortXmitPackets: &port2PortXmitPackets, - PortXmitWait: &port2PortXmitWait, - SymbolError: &port2SymbolError, - VL15Dropped: &port2VL15Dropped, + ExcessiveBufferOverrunErrors: &mlx4Port2ExcessiveBufferOverrunErrors, + LinkDowned: &mlx4Port2LinkDowned, + LinkErrorRecovery: &mlx4Port2LinkErrorRecovery, + LocalLinkIntegrityErrors: &mlx4Port2LocalLinkIntegrityErrors, + PortRcvConstraintErrors: &mlx4Port2PortRcvConstraintErrors, + PortRcvData: &mlx4Port2PortRcvData, + PortRcvErrors: &mlx4Port2PortRcvErrors, + PortRcvPackets: &mlx4Port2PortRcvPackets, + PortRcvRemotePhysicalErrors: &mlx4Port2PortRcvRemotePhysicalErrors, + PortRcvSwitchRelayErrors: &mlx4Port2PortRcvSwitchRelayErrors, + PortXmitConstraintErrors: &mlx4Port2PortXmitConstraintErrors, + PortXmitData: &mlx4Port2PortXmitData, + PortXmitDiscards: &mlx4Port2PortXmitDiscards, + PortXmitPackets: &mlx4Port2PortXmitPackets, + PortXmitWait: &mlx4Port2PortXmitWait, + SymbolError: &mlx4Port2SymbolError, + VL15Dropped: &mlx4Port2VL15Dropped, }, }, }, From 8a561cafefd4367551f3d556e067638f92c7cac3 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Mon, 5 Jul 2021 22:20:51 +0200 Subject: [PATCH 22/31] Update status badgets (#388) Update status badgets * Replace godoc with pkg.go.dev. * Replace Travis with CircleCI. Signed-off-by: SuperQ --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 55d1e3261..43c37735a 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ metrics from the pseudo-filesystems /proc and /sys. *WARNING*: This package is a work in progress. Its API may still break in backwards-incompatible ways without warnings. Use it at your own risk. -[![GoDoc](https://godoc.org/github.com/prometheus/procfs?status.png)](https://godoc.org/github.com/prometheus/procfs) -[![Build Status](https://travis-ci.org/prometheus/procfs.svg?branch=master)](https://travis-ci.org/prometheus/procfs) +[![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/procfs.svg)](https://pkg.go.dev/github.com/prometheus/procfs) +[![CircleCI](https://circleci.com/gh/prometheus/procfs/tree/master.svg?style=svg)](https://circleci.com/gh/prometheus/procfs/tree/master) [![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs) ## Usage From cf1df7228d919a45372decaf99d003f99daf9398 Mon Sep 17 00:00:00 2001 From: PrometheusBot Date: Tue, 6 Jul 2021 10:14:58 +0200 Subject: [PATCH 23/31] Update common Prometheus files (#395) Signed-off-by: prombot --- Makefile.common | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.common b/Makefile.common index bbdec8ef5..a1b1ca40f 100644 --- a/Makefile.common +++ b/Makefile.common @@ -201,7 +201,11 @@ endif .PHONY: common-yamllint common-yamllint: @echo ">> running yamllint on all YAML files in the repository" +ifeq (, $(shell which yamllint)) + @echo "yamllint not installed so skipping" +else yamllint . +endif # For backward-compatibility. .PHONY: common-staticcheck From f73f4d0c0aaac31bbd7e3f565c4d3e57df1b9ecd Mon Sep 17 00:00:00 2001 From: Luiz Angelo Daros de Luca Date: Tue, 6 Jul 2021 06:02:51 -0300 Subject: [PATCH 24/31] Fix diskstats stats using sysfs (#394) /sys/block/ is normally a symlink while code previously checked for a directory. Added flush request and time spend flushing diskstats for kernel 5.5+ to sysfs. Signed-off-by: Luiz Angelo Daros de Luca --- blockdevice/stats.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blockdevice/stats.go b/blockdevice/stats.go index 1e826f87c..52139d3e8 100644 --- a/blockdevice/stats.go +++ b/blockdevice/stats.go @@ -182,7 +182,7 @@ const ( procDiskstatsPath = "diskstats" procDiskstatsFormat = "%d %d %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" sysBlockPath = "block" - sysBlockStatFormat = "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" + sysBlockStatFormat = "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" sysBlockQueue = "queue" ) @@ -274,9 +274,7 @@ func (fs FS) SysBlockDevices() ([]string, error) { } devices := []string{} for _, deviceDir := range deviceDirs { - if deviceDir.IsDir() { - devices = append(devices, deviceDir.Name()) - } + devices = append(devices, deviceDir.Name()) } return devices, nil } @@ -306,6 +304,8 @@ func (fs FS) SysBlockDeviceStat(device string) (IOStats, int, error) { &stat.DiscardMerges, &stat.DiscardSectors, &stat.DiscardTicks, + &stat.FlushRequestsCompleted, + &stat.TimeSpentFlushing, ) // An io.EOF error is ignored because it just means we read fewer than the full 15 fields. if err == io.EOF { From 139df5dd0e4ea08354c3491ceb1a710821109d66 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Tue, 20 Jul 2021 15:24:27 +0200 Subject: [PATCH 25/31] nvme: Wrap underlying errors instead of hiding them (#397) Prometheus node exporter checks the returned error variable of `NVMeClass` for being `os.ErrNotExist`. This check will never match, because `NVMeClass` uses `fmt.Errorf` to convert the error. So wrap the error result using `%w` to allow checking for `os.ErrNotExist`. Signed-off-by: Benjamin Drung --- sysfs/class_nvme.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysfs/class_nvme.go b/sysfs/class_nvme.go index 57e247b16..2e4fa3481 100644 --- a/sysfs/class_nvme.go +++ b/sysfs/class_nvme.go @@ -45,7 +45,7 @@ func (fs FS) NVMeClass() (NVMeClass, error) { dirs, err := ioutil.ReadDir(path) if err != nil { - return nil, fmt.Errorf("failed to list NVMe devices at %q: %v", path, err) + return nil, fmt.Errorf("failed to list NVMe devices at %q: %w", path, err) } nc := make(NVMeClass, len(dirs)) @@ -70,7 +70,7 @@ func (fs FS) parseNVMeDevice(name string) (*NVMeDevice, error) { name := filepath.Join(path, f) value, err := util.SysReadFile(name) if err != nil { - return nil, fmt.Errorf("failed to read file %q: %v", name, err) + return nil, fmt.Errorf("failed to read file %q: %w", name, err) } switch f { From 8506463359f1d69d08805f7a4db1a2711576e76e Mon Sep 17 00:00:00 2001 From: Nathan Monfils Date: Tue, 20 Jul 2021 14:16:32 +0200 Subject: [PATCH 26/31] Fix cgroup path computation In testing scenarios, the process path is not necessarily `/proc//cgroup`, but `fixtures//cgroup` or similar. Signed-off-by: Nathan Monfils --- proc_cgroup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proc_cgroup.go b/proc_cgroup.go index 0094a13c0..be45b7987 100644 --- a/proc_cgroup.go +++ b/proc_cgroup.go @@ -90,7 +90,7 @@ func parseCgroups(data []byte) ([]Cgroup, error) { // control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes, // so the len of the returned struct is equal to the number of active hierarchies on this system func (p Proc) Cgroups() ([]Cgroup, error) { - data, err := util.ReadFileNoStat(fmt.Sprintf("/proc/%d/cgroup", p.PID)) + data, err := util.ReadFileNoStat(p.path("cgroup")) if err != nil { return nil, err } From f8ee60a4661aa12a2e7912c1d193551c8c6523af Mon Sep 17 00:00:00 2001 From: Sergei Semenchuk Date: Wed, 21 Jul 2021 16:04:41 +0300 Subject: [PATCH 27/31] fix zoneinfo name parsing (#398) Add aditional test coverage for Normal, Movable and Devize zones Signed-off-by: binjip978 --- zoneinfo.go | 1 - zoneinfo_test.go | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/zoneinfo.go b/zoneinfo.go index 0b9bb6796..209e2ac98 100644 --- a/zoneinfo.go +++ b/zoneinfo.go @@ -99,7 +99,6 @@ func parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) { continue } if strings.HasPrefix(strings.TrimSpace(line), "per-node stats") { - zoneinfoElement.Zone = "" continue } parts := strings.Fields(strings.TrimSpace(line)) diff --git a/zoneinfo_test.go b/zoneinfo_test.go index 87b0ab1a4..f64398033 100644 --- a/zoneinfo_test.go +++ b/zoneinfo_test.go @@ -23,16 +23,28 @@ import ( func TestZoneinfo(t *testing.T) { fs := getProcFixtures(t) - protection1 := []*int64{newPInt64(0), newPInt64(2877), newPInt64(7826), newPInt64(7826), newPInt64(7826)} - protection2 := []*int64{newPInt64(0), newPInt64(0), newPInt64(4949), newPInt64(4949), newPInt64(4949)} + + protectionDMA := []*int64{newPInt64(0), newPInt64(2877), newPInt64(7826), newPInt64(7826), newPInt64(7826)} + protectionDMA32 := []*int64{newPInt64(0), newPInt64(0), newPInt64(4949), newPInt64(4949), newPInt64(4949)} + protectionNormal := []*int64{newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0)} + protectionMovable := []*int64{newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0)} + protectionDevice := []*int64{newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0), newPInt64(0)} + refs := []Zoneinfo{ - {Node: "0", Zone: "", NrFreePages: newPInt64(3952), Min: newPInt64(33), Low: newPInt64(41), High: newPInt64(49), Spanned: newPInt64(4095), Present: newPInt64(3975), Managed: newPInt64(3956), NrActiveAnon: newPInt64(547580), NrInactiveAnon: newPInt64(230981), NrIsolatedAnon: newPInt64(0), NrAnonPages: newPInt64(795576), NrAnonTransparentHugepages: newPInt64(0), NrActiveFile: newPInt64(346282), NrInactiveFile: newPInt64(316904), NrIsolatedFile: newPInt64(0), NrFilePages: newPInt64(761874), NrSlabReclaimable: newPInt64(131220), NrSlabUnreclaimable: newPInt64(47320), NrKernelStack: newPInt64(0), NrMapped: newPInt64(215483), NrDirty: newPInt64(908), NrWriteback: newPInt64(0), NrUnevictable: newPInt64(115467), NrShmem: newPInt64(224925), NrDirtied: newPInt64(8007423), NrWritten: newPInt64(7752121), NumaHit: newPInt64(1), NumaMiss: newPInt64(0), NumaForeign: newPInt64(0), NumaInterleave: newPInt64(0), NumaLocal: newPInt64(1), NumaOther: newPInt64(0), Protection: protection1}, - {Node: "0", Zone: "DMA32", NrFreePages: newPInt64(204252), Min: newPInt64(19510), Low: newPInt64(21059), High: newPInt64(22608), Spanned: newPInt64(1044480), Present: newPInt64(759231), Managed: newPInt64(742806), NrKernelStack: newPInt64(2208), NumaHit: newPInt64(113952967), NumaMiss: newPInt64(0), NumaForeign: newPInt64(0), NumaInterleave: newPInt64(0), NumaLocal: newPInt64(113952967), NumaOther: newPInt64(0), Protection: protection2}, + {Node: "0", Zone: "DMA", NrFreePages: newPInt64(3952), Min: newPInt64(33), Low: newPInt64(41), High: newPInt64(49), Spanned: newPInt64(4095), Present: newPInt64(3975), Managed: newPInt64(3956), NrActiveAnon: newPInt64(547580), NrInactiveAnon: newPInt64(230981), NrIsolatedAnon: newPInt64(0), NrAnonPages: newPInt64(795576), NrAnonTransparentHugepages: newPInt64(0), NrActiveFile: newPInt64(346282), NrInactiveFile: newPInt64(316904), NrIsolatedFile: newPInt64(0), NrFilePages: newPInt64(761874), NrSlabReclaimable: newPInt64(131220), NrSlabUnreclaimable: newPInt64(47320), NrKernelStack: newPInt64(0), NrMapped: newPInt64(215483), NrDirty: newPInt64(908), NrWriteback: newPInt64(0), NrUnevictable: newPInt64(115467), NrShmem: newPInt64(224925), NrDirtied: newPInt64(8007423), NrWritten: newPInt64(7752121), NumaHit: newPInt64(1), NumaMiss: newPInt64(0), NumaForeign: newPInt64(0), NumaInterleave: newPInt64(0), NumaLocal: newPInt64(1), NumaOther: newPInt64(0), Protection: protectionDMA}, + {Node: "0", Zone: "DMA32", NrFreePages: newPInt64(204252), Min: newPInt64(19510), Low: newPInt64(21059), High: newPInt64(22608), Spanned: newPInt64(1044480), Present: newPInt64(759231), Managed: newPInt64(742806), NrKernelStack: newPInt64(2208), NumaHit: newPInt64(113952967), NumaMiss: newPInt64(0), NumaForeign: newPInt64(0), NumaInterleave: newPInt64(0), NumaLocal: newPInt64(113952967), NumaOther: newPInt64(0), Protection: protectionDMA32}, + {Node: "0", Zone: "Normal", NrFreePages: newPInt64(18553), Min: newPInt64(11176), Low: newPInt64(13842), High: newPInt64(16508), Spanned: newPInt64(1308160), Present: newPInt64(1308160), Managed: newPInt64(1268711), NrKernelStack: newPInt64(15136), NumaHit: newPInt64(162718019), NumaMiss: newPInt64(0), NumaForeign: newPInt64(0), NumaInterleave: newPInt64(26812), NumaLocal: newPInt64(162718019), NumaOther: newPInt64(0), Protection: protectionNormal}, + {Node: "0", Zone: "Movable", Min: newPInt64(0), Low: newPInt64(0), High: newPInt64(0), Spanned: newPInt64(0), Present: newPInt64(0), Managed: newPInt64(0), Protection: protectionMovable}, + {Node: "0", Zone: "Device", Min: newPInt64(0), Low: newPInt64(0), High: newPInt64(0), Spanned: newPInt64(0), Present: newPInt64(0), Managed: newPInt64(0), Protection: protectionDevice}, } + data, err := fs.Zoneinfo() if err != nil { t.Fatalf("failed to parse zoneinfo: %v", err) } + if len(data) != 5 { + t.Fatal("failed to get all all node info") + } for index, ref := range refs { want, got := ref, data[index] From e979fa412a1763bbf9e3b52fc6d636ad3be8bcc5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Kulakov Date: Tue, 27 Jul 2021 16:23:44 +0300 Subject: [PATCH 28/31] Fix data types for ignored stat fields #401 Some ignored fields in the /proc/[pid]/stat file may have values that are bigger than the max value of the current Go type that is used for the ignored variable. That leads to issues in runtime on some systems that use the maximum possible values for the related fields. See for details: * https://man7.org/linux/man-pages/man5/proc.5.html * https://man7.org/linux/man-pages/man3/scanf.3.html Signed-off-by: Vyacheslav Kulakov --- proc_stat.go | 33 +++++++++++++++++---------------- proc_stat_test.go | 12 ++++++++++++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/proc_stat.go b/proc_stat.go index d3a860e4a..8c7b6e80a 100644 --- a/proc_stat.go +++ b/proc_stat.go @@ -128,7 +128,8 @@ func (p Proc) Stat() (ProcStat, error) { } var ( - ignore int + ignoreInt64 int64 + ignoreUint64 uint64 s = ProcStat{PID: p.PID, proc: p.fs} l = bytes.Index(data, []byte("(")) @@ -160,25 +161,25 @@ func (p Proc) Stat() (ProcStat, error) { &s.Priority, &s.Nice, &s.NumThreads, - &ignore, + &ignoreInt64, &s.Starttime, &s.VSize, &s.RSS, &s.RSSLimit, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, - &ignore, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreUint64, + &ignoreInt64, + &ignoreInt64, &s.RTPriority, &s.Policy, &s.DelayAcctBlkIOTicks, diff --git a/proc_stat_test.go b/proc_stat_test.go index eafefb777..53491050e 100644 --- a/proc_stat_test.go +++ b/proc_stat_test.go @@ -76,6 +76,18 @@ func TestProcStat(t *testing.T) { } } +func TestProcStatIgnored(t *testing.T) { + p, err := getProcFixtures(t).Proc(26232) + if err != nil { + t.Fatal(err) + } + + _, err = p.Stat() + if err != nil { + t.Errorf("want not error, have %s", err) + } +} + func TestProcStatComm(t *testing.T) { s1, err := testProcStat(26231) if err != nil { From f436cbb89ece38bf080d446b3ca27053b305eaac Mon Sep 17 00:00:00 2001 From: Aleksei Zakharov Date: Mon, 9 Aug 2021 18:06:36 +0300 Subject: [PATCH 29/31] Add NetStat to parse /proc/net/stat/... (#316) * Add NetStat to parse /proc/net/stat/... Signed-off-by: Aleksei Zakharov --- fixtures.ttar | 17 ++++++++ netstat.go | 68 +++++++++++++++++++++++++++++ netstat_test.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 netstat.go create mode 100644 netstat_test.go diff --git a/fixtures.ttar b/fixtures.ttar index e7d35069c..5e7eeef4a 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -2209,6 +2209,23 @@ Lines: 1 00015c73 00020e76 F0000769 00000000 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Directory: fixtures/proc/net/stat +Mode: 755 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/proc/net/stat/arp_cache +Lines: 3 +entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls +00000014 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 00000009 0000000a 0000000b 0000000c +00000014 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/proc/net/stat/ndisc_cache +Lines: 3 +entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls +00000024 000000f0 000000f1 000000f2 000000f3 000000f4 000000f5 000000f6 000000f7 000000f8 000000f9 000000fa 000000fb +00000024 000000fc 000000fd 000000fe 000000ff 00000100 00000101 00000102 00000103 00000104 00000105 00000106 00000107 +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/proc/net/tcp Lines: 4 sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode diff --git a/netstat.go b/netstat.go new file mode 100644 index 000000000..94d892f11 --- /dev/null +++ b/netstat.go @@ -0,0 +1,68 @@ +// Copyright 2020 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. + +package procfs + +import ( + "bufio" + "os" + "path/filepath" + "strconv" + "strings" +) + +// NetStat contains statistics for all the counters from one file +type NetStat struct { + Filename string + Stats map[string][]uint64 +} + +// NetStat retrieves stats from /proc/net/stat/ +func (fs FS) NetStat() ([]NetStat, error) { + statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) + if err != nil { + return nil, err + } + + var netStatsTotal []NetStat + + for _, filePath := range statFiles { + file, err := os.Open(filePath) + if err != nil { + return nil, err + } + + netStatFile := NetStat{ + Filename: filepath.Base(filePath), + Stats: make(map[string][]uint64), + } + scanner := bufio.NewScanner(file) + scanner.Scan() + // First string is always a header for stats + var headers []string + headers = append(headers, strings.Fields(scanner.Text())...) + + // Other strings represent per-CPU counters + for scanner.Scan() { + for num, counter := range strings.Fields(scanner.Text()) { + value, err := strconv.ParseUint(counter, 16, 32) + if err != nil { + return nil, err + } + netStatFile.Stats[headers[num]] = append(netStatFile.Stats[headers[num]], value) + } + } + netStatsTotal = append(netStatsTotal, netStatFile) + } + return netStatsTotal, nil +} diff --git a/netstat_test.go b/netstat_test.go new file mode 100644 index 000000000..1d3936251 --- /dev/null +++ b/netstat_test.go @@ -0,0 +1,114 @@ +// Copyright 2020 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. + +package procfs + +import ( + "testing" +) + +func TestNetStat(t *testing.T) { + const ( + filesCount = 2 + CPUsCount = 2 + arpCacheMetricsCount = 13 + ndiscCacheMetricsCount = 13 + ) + + fs, err := NewFS(procTestFixtures) + if err != nil { + t.Fatalf("failed to open procfs: %v", err) + } + + netStats, err := fs.NetStat() + if err != nil { + t.Fatalf("NetStat() error: %s", err) + } + + if len(netStats) != filesCount { + t.Fatalf("unexpected number of files parsed %d, expected %d", len(netStats), filesCount) + } + + expectedStats := [2]NetStat{ + { + Filename: "arp_cache", + Stats: make(map[string][]uint64), + }, + { + Filename: "ndisc_cache", + Stats: make(map[string][]uint64), + }, + } + + for _, expected := range expectedStats { + if expected.Filename == "arp_cache" { + expected.Stats["entries"] = []uint64{20, 20} + expected.Stats["allocs"] = []uint64{1, 13} + expected.Stats["destroys"] = []uint64{2, 14} + expected.Stats["hash_grows"] = []uint64{3, 15} + expected.Stats["lookups"] = []uint64{4, 16} + expected.Stats["hits"] = []uint64{5, 17} + expected.Stats["res_failed"] = []uint64{6, 18} + expected.Stats["rcv_probes_mcast"] = []uint64{7, 19} + expected.Stats["rcv_probes_ucast"] = []uint64{8, 20} + expected.Stats["periodic_gc_runs"] = []uint64{9, 21} + expected.Stats["forced_gc_runs"] = []uint64{10, 22} + expected.Stats["unresolved_discards"] = []uint64{11, 23} + expected.Stats["table_fulls"] = []uint64{12, 24} + } + if expected.Filename == "ndisc_cache" { + expected.Stats["entries"] = []uint64{36, 36} + expected.Stats["allocs"] = []uint64{240, 252} + expected.Stats["destroys"] = []uint64{241, 253} + expected.Stats["hash_grows"] = []uint64{242, 254} + expected.Stats["lookups"] = []uint64{243, 255} + expected.Stats["hits"] = []uint64{244, 256} + expected.Stats["res_failed"] = []uint64{245, 257} + expected.Stats["rcv_probes_mcast"] = []uint64{246, 258} + expected.Stats["rcv_probes_ucast"] = []uint64{247, 259} + expected.Stats["periodic_gc_runs"] = []uint64{248, 260} + expected.Stats["forced_gc_runs"] = []uint64{249, 261} + expected.Stats["unresolved_discards"] = []uint64{250, 262} + expected.Stats["table_fulls"] = []uint64{251, 263} + } + } + + for _, netStatFile := range netStats { + if netStatFile.Filename == "arp_cache" && len(netStatFile.Stats) != arpCacheMetricsCount { + t.Fatalf("unexpected arp_cache metrics count %d, expected %d", len(netStatFile.Stats), arpCacheMetricsCount) + } + if netStatFile.Filename == "ndisc_cache" && len(netStatFile.Stats) != ndiscCacheMetricsCount { + t.Fatalf("unexpected ndisc_cache metrics count %d, expected %d", len(netStatFile.Stats), ndiscCacheMetricsCount) + } + for _, expected := range expectedStats { + for header, stats := range netStatFile.Stats { + if header == "" { + t.Fatalf("Found empty metric name") + } + if len(stats) != CPUsCount { + t.Fatalf("NetStat() parsed %d lines with metrics, expected %d", len(stats), CPUsCount) + } + if netStatFile.Filename == expected.Filename { + if expected.Stats[header] == nil { + t.Fatalf("unexpected metric header: %s", header) + } + for cpu, value := range netStatFile.Stats[header] { + if expected.Stats[header][cpu] != value { + t.Fatalf("unexpected value for %s for cpu %d in %s: %d, expected %d", header, cpu, netStatFile.Filename, value, expected.Stats[header][cpu]) + } + } + } + } + } + } +} From 4d08435ddcfb75cd30b589be41d7e654b6f8a794 Mon Sep 17 00:00:00 2001 From: Christian Stewart Date: Fri, 27 Aug 2021 00:24:49 -0700 Subject: [PATCH 30/31] Fix build with GopherJS (#406) Signed-off-by: Christian Stewart --- proc_maps.go | 1 + 1 file changed, 1 insertion(+) diff --git a/proc_maps.go b/proc_maps.go index 1d7772d51..8425e3082 100644 --- a/proc_maps.go +++ b/proc_maps.go @@ -12,6 +12,7 @@ // limitations under the License. // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +// +build !js package procfs From 21d221eae0ffb0c7d1bd3886c30dc00ae7b24c88 Mon Sep 17 00:00:00 2001 From: slava Date: Tue, 31 Aug 2021 00:06:23 +0300 Subject: [PATCH 31/31] Fix data types for CUTime and CSTime stat fields #403 (#404) * Fix data types for CUTime and CSTime stat fields #403 These two stat fields (CUTime and CSTime) in the /proc/[pid]/stat file should have the signed long data type according to the documentation. But currently in the code their data type is just unsigned int. This commit fixes it and adds more tests. See for details: * https://man7.org/linux/man-pages/man5/proc.5.html * https://man7.org/linux/man-pages/man3/scanf.3.html Signed-off-by: Vyacheslav Kulakov --- fixtures.ttar | 2 +- proc_stat.go | 9 +++++++-- proc_stat_test.go | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/fixtures.ttar b/fixtures.ttar index 5e7eeef4a..30df09144 100644 --- a/fixtures.ttar +++ b/fixtures.ttar @@ -589,7 +589,7 @@ SymlinkTo: /does/not/exist # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/proc/26232/stat Lines: 1 -33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 -9223372036854775808 9223372036854775807 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 -9223372036854775808 9223372036854775807 0 0 0 0 0 0 0 0 0 0 0 0 0 Mode: 644 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/proc/26232/wchan diff --git a/proc_stat.go b/proc_stat.go index 8c7b6e80a..ad03d85ef 100644 --- a/proc_stat.go +++ b/proc_stat.go @@ -81,10 +81,10 @@ type ProcStat struct { STime uint // Amount of time that this process's waited-for children have been // scheduled in user mode, measured in clock ticks. - CUTime uint + CUTime int // Amount of time that this process's waited-for children have been // scheduled in kernel mode, measured in clock ticks. - CSTime uint + CSTime int // For processes running a real-time scheduling policy, this is the negated // scheduling priority, minus one. Priority int @@ -141,6 +141,11 @@ func (p Proc) Stat() (ProcStat, error) { } s.Comm = string(data[l+1 : r]) + + // Check the following resources for the details about the particular stat + // fields and their data types: + // * https://man7.org/linux/man-pages/man5/proc.5.html + // * https://man7.org/linux/man-pages/man3/scanf.3.html _, err = fmt.Fscan( bytes.NewBuffer(data[r+2:]), &s.State, diff --git a/proc_stat_test.go b/proc_stat_test.go index 53491050e..8be1e1318 100644 --- a/proc_stat_test.go +++ b/proc_stat_test.go @@ -14,6 +14,7 @@ package procfs import ( + "math" "os" "testing" ) @@ -76,16 +77,30 @@ func TestProcStat(t *testing.T) { } } -func TestProcStatIgnored(t *testing.T) { +func TestProcStatLimits(t *testing.T) { p, err := getProcFixtures(t).Proc(26232) if err != nil { t.Fatal(err) } - _, err = p.Stat() + s, err := p.Stat() if err != nil { t.Errorf("want not error, have %s", err) } + + // max values of stat int fields + for _, test := range []struct { + name string + want int + have int + }{ + {name: "waited for children user time", want: math.MinInt64, have: s.CUTime}, + {name: "waited for children system time", want: math.MaxInt64, have: s.CSTime}, + } { + if test.want != test.have { + t.Errorf("want %s %d, have %d", test.name, test.want, test.have) + } + } } func TestProcStatComm(t *testing.T) {