From 969849f4953c8e5d6c913b4ce677aa92df77c538 Mon Sep 17 00:00:00 2001 From: Finn Snape <145353420+fs185143@users.noreply.github.com> Date: Tue, 26 Nov 2024 19:48:12 +0000 Subject: [PATCH] feat(blockdevice): added sysblockdevicesize method and test (#658) * added blockdevice size method + test + data --------- Signed-off-by: fs185143 Signed-off-by: Finn Snape <145353420+fs185143@users.noreply.github.com> --- blockdevice/stats.go | 12 ++++++++++++ blockdevice/stats_test.go | 19 +++++++++++++++++++ btrfs/get.go | 8 ++------ fs.go | 10 ++++++++-- testdata/fixtures.ttar | 5 +++++ 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/blockdevice/stats.go b/blockdevice/stats.go index 75b68845..1bee6d64 100644 --- a/blockdevice/stats.go +++ b/blockdevice/stats.go @@ -21,6 +21,7 @@ import ( "os" "strings" + "github.com/prometheus/procfs" "github.com/prometheus/procfs/internal/fs" "github.com/prometheus/procfs/internal/util" ) @@ -214,6 +215,7 @@ const ( sysBlockQueue = "queue" sysBlockDM = "dm" sysUnderlyingDev = "slaves" + sysBlockSize = "size" sysDevicePath = "device" ) @@ -481,6 +483,16 @@ func (fs FS) SysBlockDeviceUnderlyingDevices(device string) (UnderlyingDeviceInf } +// SysBlockDeviceSize returns the size of the block device from /sys/block//size. +// in bytes by multiplying the value by the Linux sector length of 512. +func (fs FS) SysBlockDeviceSize(device string) (uint64, error) { + size, err := util.ReadUintFromFile(fs.sys.Path(sysBlockPath, device, sysBlockSize)) + if err != nil { + return 0, err + } + return procfs.SectorSize * size, nil +} + // SysBlockDeviceIO returns stats for the block device io counters // IO done count: /sys/block//device/iodone_cnt // IO error count: /sys/block//device/ioerr_cnt. diff --git a/blockdevice/stats_test.go b/blockdevice/stats_test.go index c065c294..0bd6016b 100644 --- a/blockdevice/stats_test.go +++ b/blockdevice/stats_test.go @@ -219,3 +219,22 @@ func TestSysBlockDeviceUnderlyingDevices(t *testing.T) { t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", underlying0Expected, underlying0) } } + +func TestSysBlockDeviceSize(t *testing.T) { + blockdevice, err := NewFS("testdata/fixtures/proc", "testdata/fixtures/sys") + if err != nil { + t.Fatalf("failed to access blockdevice fs: %v", err) + } + devices, err := blockdevice.SysBlockDevices() + if err != nil { + t.Fatal(err) + } + size7, err := blockdevice.SysBlockDeviceSize(devices[7]) + if err != nil { + t.Fatal(err) + } + size7Expected := uint64(1920383410176) + if size7 != size7Expected { + t.Errorf("Incorrect BlockDeviceSize, expected: \n%+v, got: \n%+v", size7Expected, size7) + } +} diff --git a/btrfs/get.go b/btrfs/get.go index db0046b6..4fce6212 100644 --- a/btrfs/get.go +++ b/btrfs/get.go @@ -22,15 +22,11 @@ import ( "strconv" "strings" + "github.com/prometheus/procfs" "github.com/prometheus/procfs/internal/fs" "github.com/prometheus/procfs/internal/util" ) -// SectorSize contains the Linux sector size. -// > Linux always considers sectors to be 512 bytes long independently -// > of the devices real block size. -const SectorSize = 512 - // FS represents the pseudo-filesystem sys, which provides an interface to // kernel data structures. type FS struct { @@ -213,7 +209,7 @@ func (r *reader) readDeviceInfo(d string) map[string]*Device { info := make(map[string]*Device, len(devs)) for _, n := range devs { info[n] = &Device{ - Size: SectorSize * r.readValue("devices/"+n+"/size"), + Size: procfs.SectorSize * r.readValue("devices/"+n+"/size"), } } diff --git a/fs.go b/fs.go index 4980c875..9bdaccc7 100644 --- a/fs.go +++ b/fs.go @@ -24,8 +24,14 @@ type FS struct { isReal bool } -// DefaultMountPoint is the common mount point of the proc filesystem. -const DefaultMountPoint = fs.DefaultProcMountPoint +const ( + // DefaultMountPoint is the common mount point of the proc filesystem. + DefaultMountPoint = fs.DefaultProcMountPoint + + // SectorSize represents the size of a sector in bytes. + // It is specific to Linux block I/O operations. + SectorSize = 512 +) // NewDefaultFS returns a new proc FS mounted under the default proc mountPoint. // It will error if the mount point directory can't be read or is a file. diff --git a/testdata/fixtures.ttar b/testdata/fixtures.ttar index f2bd5e56..07137af8 100644 --- a/testdata/fixtures.ttar +++ b/testdata/fixtures.ttar @@ -4335,6 +4335,11 @@ Lines: 1 none Mode: 444 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/block/sda/size +Lines: 1 +3750748848EOF +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/sys/block/sda/stat Lines: 1 9652963 396792 759304206 412943 8422549 6731723 286915323 13947418 0 5658367 19174573 1 2 3 12