diff --git a/blockdevice/stats.go b/blockdevice/stats.go index 86baac6a..49470bba 100644 --- a/blockdevice/stats.go +++ b/blockdevice/stats.go @@ -492,6 +492,15 @@ func (fs FS) SysBlockDeviceSize(device string) (uint64, error) { return procfs.SectorSize * size, nil } +// SysBlockDeviceRotational returns the rotational value for the block device +// from /sys/block//queue/rotational. +// A value of 1 indicates a rotational device (HDD), 0 indicates a +// non-rotational device (SSD, NVMe). An error is returned if the file +// cannot be read or does not contain a valid integer. +func (fs FS) SysBlockDeviceRotational(device string) (uint64, error) { + return util.ReadUintFromFile(fs.sys.Path(sysBlockPath, device, sysBlockQueue, "rotational")) +} + // 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 93811ea3..1eb97d84 100644 --- a/blockdevice/stats_test.go +++ b/blockdevice/stats_test.go @@ -241,3 +241,29 @@ func TestSysBlockDeviceSize(t *testing.T) { t.Errorf("Incorrect BlockDeviceSize, expected: \n%+v, got: \n%+v", size9Expected, size9) } } + +func TestSysBlockDeviceRotational(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) + } + + // devices[9] is "sda" in the fixtures — a rotational HDD (value: 1). + rotational9, err := blockdevice.SysBlockDeviceRotational(devices[9]) + if err != nil { + t.Fatal(err) + } + if rotational9 != 1 { + t.Errorf("Incorrect rotational value for %s: expected 1, got %d", devices[9], rotational9) + } + + // devices[0] is "dm-0" — no queue/rotational file; expect an error. + _, err = blockdevice.SysBlockDeviceRotational(devices[0]) + if err == nil { + t.Errorf("expected error reading rotational for %s (no queue dir), got nil", devices[0]) + } +}