Skip to content

Commit

Permalink
Fix softnet parsing (#271)
Browse files Browse the repository at this point in the history
Allow 9 or more columns from softnet, older kernels had fewer columns.

Fix for prometheus/node_exporter#1625

Signed-off-by: Ben Kochie <[email protected]>
  • Loading branch information
SuperQ authored Mar 9, 2020
1 parent f0819c7 commit 40d8922
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
18 changes: 12 additions & 6 deletions fixtures.ttar
Original file line number Diff line number Diff line change
Expand Up @@ -1551,11 +1551,6 @@ blocksize : 16
min keysize : 16
max keysize : 32

Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/loadavg
Lines: 1
0.02 0.04 0.05 1/497 11947
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/diskstats
Expand Down Expand Up @@ -1644,6 +1639,11 @@ xpc 399724544 92823103 86219234
debug 0
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/loadavg
Lines: 1
0.02 0.04 0.05 1/497 11947
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/mdstat
Lines: 56
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
Expand Down Expand Up @@ -1851,8 +1851,14 @@ FRAG6: inuse 0 memory 0
Mode: 444
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat
Lines: 1
Lines: 2
00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00000000
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/softnet_stat.broken
Lines: 1
00015c73 00020e76 F0000769 00000000
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/proc/net/udp
Expand Down
14 changes: 9 additions & 5 deletions net_softnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
)

// For the proc file format details,
// see https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
// See:
// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343
// * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162
// and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810.

// SoftnetStat contains a single row of data from /proc/net/softnet_stat
Expand All @@ -38,9 +40,11 @@ type SoftnetStat struct {
TimeSqueezed uint32
}

var softNetProcFile = "net/softnet_stat"

// NetSoftnetStat reads data from /proc/net/softnet_stat.
func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {
b, err := util.ReadFileNoStat(fs.proc.Path("net/softnet_stat"))
b, err := util.ReadFileNoStat(fs.proc.Path(softNetProcFile))
if err != nil {
return nil, err
}
Expand All @@ -54,7 +58,7 @@ func (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {
}

func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
const expectedColumns = 11
const minColumns = 9

s := bufio.NewScanner(r)

Expand All @@ -63,8 +67,8 @@ func parseSoftnet(r io.Reader) ([]SoftnetStat, error) {
columns := strings.Fields(s.Text())
width := len(columns)

if width != 11 {
return nil, fmt.Errorf("%d columns were detected, but %d were expected", width, expectedColumns)
if width < minColumns {
return nil, fmt.Errorf("%d columns were detected, but at least %d were expected", width, minColumns)
}

// We only parse the first three columns at the moment.
Expand Down
19 changes: 18 additions & 1 deletion net_softnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ func TestNetSoftnet(t *testing.T) {
Processed: 0x00015c73,
Dropped: 0x00020e76,
TimeSqueezed: 0xf0000769,
}}
},
{
Processed: 0x01663fb2,
TimeSqueezed: 0x0109a4,
}}

got, err := fs.NetSoftnetStat()
if err != nil {
Expand All @@ -40,3 +44,16 @@ func TestNetSoftnet(t *testing.T) {
t.Fatalf("unexpected softnet stats(-want +got):\n%s", diff)
}
}

func TestBadSoftnet(t *testing.T) {
softNetProcFile = "net/softnet_stat.broken"
fs, err := NewFS(procTestFixtures)
if err != nil {
t.Fatal(err)
}

_, err = fs.NetSoftnetStat()
if err == nil {
t.Fatal("expected error, got nil")
}
}

0 comments on commit 40d8922

Please sign in to comment.