Skip to content

Commit 0f527e6

Browse files
authored
Add /sys/class/watchdog statistics (prometheus#594)
Signed-off-by: Gavin Lam <[email protected]>
1 parent d254b01 commit 0f527e6

File tree

3 files changed

+268
-0
lines changed

3 files changed

+268
-0
lines changed

sysfs/class_watchdog.go

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2023 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
//go:build linux
15+
// +build linux
16+
17+
package sysfs
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
24+
"github.com/prometheus/procfs/internal/util"
25+
)
26+
27+
const watchdogClassPath = "class/watchdog"
28+
29+
// WatchdogStats contains info from files in /sys/class/watchdog for a single watchdog device.
30+
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-watchdog
31+
type WatchdogStats struct {
32+
Name string
33+
Bootstatus *int64 // /sys/class/watchdog/<Name>/bootstatus
34+
Options *string // /sys/class/watchdog/<Name>/options
35+
FwVersion *int64 // /sys/class/watchdog/<Name>/fw_version
36+
Identity *string // /sys/class/watchdog/<Name>/identity
37+
Nowayout *int64 // /sys/class/watchdog/<Name>/nowayout
38+
State *string // /sys/class/watchdog/<Name>/state
39+
Status *string // /sys/class/watchdog/<Name>/status
40+
Timeleft *int64 // /sys/class/watchdog/<Name>/timeleft
41+
Timeout *int64 // /sys/class/watchdog/<Name>/timeout
42+
Pretimeout *int64 // /sys/class/watchdog/<Name>/pretimeout
43+
PretimeoutGovernor *string // /sys/class/watchdog/<Name>/pretimeout_governor
44+
AccessCs0 *int64 // /sys/class/watchdog/<Name>/access_cs0
45+
}
46+
47+
// WatchdogClass is a collection of statistics for every watchdog device in /sys/class/watchdog.
48+
//
49+
// The map keys are the names of the watchdog devices.
50+
type WatchdogClass map[string]WatchdogStats
51+
52+
// WatchdogClass returns info for all watchdog devices read from /sys/class/watchdog.
53+
func (fs FS) WatchdogClass() (WatchdogClass, error) {
54+
path := fs.sys.Path(watchdogClassPath)
55+
56+
dirs, err := os.ReadDir(path)
57+
if err != nil {
58+
return nil, fmt.Errorf("failed to list watchdog devices at %q: %w", path, err)
59+
}
60+
61+
wds := make(WatchdogClass, len(dirs))
62+
for _, d := range dirs {
63+
stats, err := fs.parseWatchdog(d.Name())
64+
if err != nil {
65+
return nil, err
66+
}
67+
68+
wds[stats.Name] = *stats
69+
}
70+
71+
return wds, nil
72+
}
73+
74+
func (fs FS) parseWatchdog(wdName string) (*WatchdogStats, error) {
75+
path := fs.sys.Path(watchdogClassPath, wdName)
76+
wd := WatchdogStats{Name: wdName}
77+
78+
for _, f := range [...]string{"bootstatus", "options", "fw_version", "identity", "nowayout", "state", "status", "timeleft", "timeout", "pretimeout", "pretimeout_governor", "access_cs0"} {
79+
name := filepath.Join(path, f)
80+
value, err := util.SysReadFile(name)
81+
if err != nil {
82+
if os.IsNotExist(err) {
83+
continue
84+
}
85+
return nil, fmt.Errorf("failed to read file %q: %w", name, err)
86+
}
87+
88+
vp := util.NewValueParser(value)
89+
90+
switch f {
91+
case "bootstatus":
92+
wd.Bootstatus = vp.PInt64()
93+
case "options":
94+
wd.Options = &value
95+
case "fw_version":
96+
wd.FwVersion = vp.PInt64()
97+
case "identity":
98+
wd.Identity = &value
99+
case "nowayout":
100+
wd.Nowayout = vp.PInt64()
101+
case "state":
102+
wd.State = &value
103+
case "status":
104+
wd.Status = &value
105+
case "timeleft":
106+
wd.Timeleft = vp.PInt64()
107+
case "timeout":
108+
wd.Timeout = vp.PInt64()
109+
case "pretimeout":
110+
wd.Pretimeout = vp.PInt64()
111+
case "pretimeout_governor":
112+
wd.PretimeoutGovernor = &value
113+
case "access_cs0":
114+
wd.AccessCs0 = vp.PInt64()
115+
}
116+
117+
if err := vp.Err(); err != nil {
118+
return nil, err
119+
}
120+
}
121+
122+
return &wd, nil
123+
}

sysfs/class_watchdog_test.go

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2023 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
//go:build linux
15+
// +build linux
16+
17+
package sysfs
18+
19+
import (
20+
"testing"
21+
22+
"github.com/google/go-cmp/cmp"
23+
)
24+
25+
func TestWatchdogClass(t *testing.T) {
26+
fs, err := NewFS(sysTestFixtures)
27+
if err != nil {
28+
t.Fatal(err)
29+
}
30+
31+
got, err := fs.WatchdogClass()
32+
if err != nil {
33+
t.Fatal(err)
34+
}
35+
36+
var (
37+
bootstatus int64 = 1
38+
fwVersion int64 = 2
39+
nowayout int64
40+
timeleft int64 = 300
41+
timeout int64 = 60
42+
pretimeout int64 = 120
43+
accessCs0 int64
44+
45+
options = "0x8380"
46+
identity = "Software Watchdog"
47+
state = "active"
48+
status = "0x8000"
49+
pretimeoutGovernor = "noop"
50+
)
51+
52+
want := WatchdogClass{
53+
"watchdog0": {
54+
Name: "watchdog0",
55+
Bootstatus: &bootstatus,
56+
Options: &options,
57+
FwVersion: &fwVersion,
58+
Identity: &identity,
59+
Nowayout: &nowayout,
60+
State: &state,
61+
Status: &status,
62+
Timeleft: &timeleft,
63+
Timeout: &timeout,
64+
Pretimeout: &pretimeout,
65+
PretimeoutGovernor: &pretimeoutGovernor,
66+
AccessCs0: &accessCs0,
67+
},
68+
"watchdog1": {
69+
Name: "watchdog1",
70+
},
71+
}
72+
73+
if diff := cmp.Diff(want, got); diff != "" {
74+
t.Fatalf("unexpected watchdog class (-want +got):\n%s", diff)
75+
}
76+
}

testdata/fixtures.ttar

+69
Original file line numberDiff line numberDiff line change
@@ -6270,6 +6270,75 @@ Lines: 1
62706270
acpitz
62716271
Mode: 664
62726272
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6273+
Directory: fixtures/sys/class/watchdog
6274+
Mode: 775
6275+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6276+
Directory: fixtures/sys/class/watchdog/watchdog0
6277+
Mode: 775
6278+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6279+
Path: fixtures/sys/class/watchdog/watchdog0/access_cs0
6280+
Lines: 1
6281+
0EOF
6282+
Mode: 644
6283+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6284+
Path: fixtures/sys/class/watchdog/watchdog0/bootstatus
6285+
Lines: 1
6286+
1EOF
6287+
Mode: 444
6288+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6289+
Path: fixtures/sys/class/watchdog/watchdog0/fw_version
6290+
Lines: 1
6291+
2EOF
6292+
Mode: 444
6293+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6294+
Path: fixtures/sys/class/watchdog/watchdog0/identity
6295+
Lines: 1
6296+
Software WatchdogEOF
6297+
Mode: 444
6298+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6299+
Path: fixtures/sys/class/watchdog/watchdog0/nowayout
6300+
Lines: 1
6301+
0EOF
6302+
Mode: 644
6303+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6304+
Path: fixtures/sys/class/watchdog/watchdog0/options
6305+
Lines: 1
6306+
0x8380EOF
6307+
Mode: 444
6308+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6309+
Path: fixtures/sys/class/watchdog/watchdog0/pretimeout
6310+
Lines: 1
6311+
120EOF
6312+
Mode: 444
6313+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6314+
Path: fixtures/sys/class/watchdog/watchdog0/pretimeout_governor
6315+
Lines: 1
6316+
noopEOF
6317+
Mode: 644
6318+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6319+
Path: fixtures/sys/class/watchdog/watchdog0/state
6320+
Lines: 1
6321+
activeEOF
6322+
Mode: 444
6323+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6324+
Path: fixtures/sys/class/watchdog/watchdog0/status
6325+
Lines: 1
6326+
0x8000EOF
6327+
Mode: 444
6328+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6329+
Path: fixtures/sys/class/watchdog/watchdog0/timeleft
6330+
Lines: 1
6331+
300EOF
6332+
Mode: 444
6333+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6334+
Path: fixtures/sys/class/watchdog/watchdog0/timeout
6335+
Lines: 1
6336+
60EOF
6337+
Mode: 444
6338+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6339+
Directory: fixtures/sys/class/watchdog/watchdog1
6340+
Mode: 775
6341+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
62736342
Directory: fixtures/sys/devices
62746343
Mode: 755
62756344
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

0 commit comments

Comments
 (0)