From 92b01ab4f9543d17bcf87648dd5555cd44cfb65b Mon Sep 17 00:00:00 2001 From: Soulou Date: Mon, 11 Mar 2019 01:21:30 +0100 Subject: [PATCH 1/3] Fix how major and minor identifiers of block devices are read. The current implementation assure that the major and the minor are coded on one byte. But they are not: ``` brw-rw---- 1 root disk 252, 290 Feb 25 11:36 dm-290 ``` 290 as minor in this example is over 1 byte. So after wondering why all my devices iops weren't correctly stored, I found out that several points were added for some disks. For `dm-290` it was overriding `252:34`, instead of getting udev stats for `252:290`. The solution is here: https://sites.uclouvain.be/SystInfo/usr/include/sys/sysmacros.h.html The implementation is directly taken from this, fixing my bug. --- plugins/inputs/diskio/diskio_linux.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/inputs/diskio/diskio_linux.go b/plugins/inputs/diskio/diskio_linux.go index d27fd3b46b898..2d3e5f6b043c6 100644 --- a/plugins/inputs/diskio/diskio_linux.go +++ b/plugins/inputs/diskio/diskio_linux.go @@ -36,7 +36,7 @@ func (s *DiskIO) diskInfo(devName string) (map[string]string, error) { } major := stat.Rdev >> 8 & 0xff - minor := stat.Rdev & 0xff + minor := (stat.Rdev & 0xff) | (stat.Rdev>>12)&^0xff udevDataPath := fmt.Sprintf("%s/b%d:%d", udevPath, major, minor) di := map[string]string{} From 2118fbe78a0f267c88368d3dc312b2481a9d65e2 Mon Sep 17 00:00:00 2001 From: Soulou Date: Fri, 15 Mar 2019 14:36:56 +0100 Subject: [PATCH 2/3] Use unix.Major/unix.Minor instead of custom implementation --- plugins/inputs/diskio/diskio_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/inputs/diskio/diskio_linux.go b/plugins/inputs/diskio/diskio_linux.go index 2d3e5f6b043c6..73eba361c26c0 100644 --- a/plugins/inputs/diskio/diskio_linux.go +++ b/plugins/inputs/diskio/diskio_linux.go @@ -35,8 +35,8 @@ func (s *DiskIO) diskInfo(devName string) (map[string]string, error) { return ic.values, nil } - major := stat.Rdev >> 8 & 0xff - minor := (stat.Rdev & 0xff) | (stat.Rdev>>12)&^0xff + major := unix.Major(stat.Rdev) + minor := unix.Minor(stat.Rdev) udevDataPath := fmt.Sprintf("%s/b%d:%d", udevPath, major, minor) di := map[string]string{} From 205de66dd645dafc7193700154105d84c981b5d0 Mon Sep 17 00:00:00 2001 From: Soulou Date: Thu, 21 Mar 2019 12:00:20 +0100 Subject: [PATCH 3/3] [diskio] Force type of stat.Rdev uint64 for mipsle compatibility For most platforms, stat.Rdev is already a uint64 so this is without any effect for linux,mipsle, unix.Stat_t.Rdev is a uint32, but the way to compute major and minor doesn't change, casting the uint32 has no impact either --- plugins/inputs/diskio/diskio_linux.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/inputs/diskio/diskio_linux.go b/plugins/inputs/diskio/diskio_linux.go index 73eba361c26c0..c727f485b1410 100644 --- a/plugins/inputs/diskio/diskio_linux.go +++ b/plugins/inputs/diskio/diskio_linux.go @@ -35,8 +35,8 @@ func (s *DiskIO) diskInfo(devName string) (map[string]string, error) { return ic.values, nil } - major := unix.Major(stat.Rdev) - minor := unix.Minor(stat.Rdev) + major := unix.Major(uint64(stat.Rdev)) + minor := unix.Minor(uint64(stat.Rdev)) udevDataPath := fmt.Sprintf("%s/b%d:%d", udevPath, major, minor) di := map[string]string{}