Skip to content

Commit

Permalink
Add device-mapper-specific block device properties (#412)
Browse files Browse the repository at this point in the history
* Expose device-mapper information as DeviceMapperInfo

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Enumerate block device slaves as UnderlyingDeviceInfo

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Add missing fixtures.

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* blockdevice/stats: uppercase initialisms.

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Expose device-mapper information as DeviceMapperInfo

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Expose device-mapper information as DeviceMapperInfo

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Update fixtures.

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

* Capitalize comments.

Signed-off-by: W. Andrew Denton <git@flying-snail.net>

Co-authored-by: W. Andrew Denton <git@flying-snail.net>
  • Loading branch information
ventifus and W. Andrew Denton committed Jan 10, 2022
1 parent c6f5590 commit fbe360a
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 4 deletions.
74 changes: 70 additions & 4 deletions blockdevice/stats.go
Expand Up @@ -16,13 +16,13 @@ package blockdevice
import (
"bufio"
"fmt"
"github.com/prometheus/procfs/internal/util"
"io"
"io/ioutil"
"os"
"strings"

"github.com/prometheus/procfs/internal/fs"
"github.com/prometheus/procfs/internal/util"
)

// Info contains identifying information for a block device such as a disk drive.
Expand Down Expand Up @@ -178,12 +178,37 @@ type BlockQueueStats struct {
WriteZeroesMaxBytes uint64
}

// DeviceMapperInfo models the devicemapper files that are located in the sysfs tree for each block device
// and described in the kernel documentation:
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm
type DeviceMapperInfo struct {
// Name is the string containing mapped device name.
Name string
// RqBasedSeqIOMergeDeadline determines how long (in microseconds) a request that is a reasonable merge
// candidate can be queued on the request queue.
RqBasedSeqIOMergeDeadline uint64
// Suspended indicates if the device is suspended (1 is on, 0 is off).
Suspended uint64
// UseBlkMQ indicates if the device is using the request-based blk-mq I/O path mode (1 is on, 0 is off).
UseBlkMQ uint64
// UUID is the DM-UUID string or empty string if DM-UUID is not set.
UUID string
}

// UnderlyingDevices models the list of devices that this device is built from.
type UnderlyingDeviceInfo struct {
// DeviceNames is the list of devices names
DeviceNames []string
}

const (
procDiskstatsPath = "diskstats"
procDiskstatsFormat = "%d %d %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
sysBlockPath = "block"
sysBlockStatFormat = "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
sysBlockQueue = "queue"
sysBlockDM = "dm"
sysUnderlyingDev = "slaves"
)

// FS represents the pseudo-filesystems proc and sys, which provides an
Expand Down Expand Up @@ -317,7 +342,7 @@ func (fs FS) SysBlockDeviceStat(device string) (IOStats, int, error) {
// SysBlockDeviceQueueStats returns stats for /sys/block/xxx/queue where xxx is a device name.
func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
stat := BlockQueueStats{}
// files with uint64 fields
// Files with uint64 fields
for file, p := range map[string]*uint64{
"add_random": &stat.AddRandom,
"dax": &stat.DAX,
Expand Down Expand Up @@ -355,7 +380,7 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
}
*p = val
}
// files with int64 fields
// Files with int64 fields
for file, p := range map[string]*int64{
"io_poll_delay": &stat.IOPollDelay,
"wbt_lat_usec": &stat.WBTLatUSec,
Expand All @@ -366,7 +391,7 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
}
*p = val
}
// files with string fields
// Files with string fields
for file, p := range map[string]*string{
"write_cache": &stat.WriteCache,
"zoned": &stat.Zoned,
Expand Down Expand Up @@ -398,3 +423,44 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
}
return stat, nil
}

func (fs FS) SysBlockDeviceMapperInfo(device string) (DeviceMapperInfo, error) {
info := DeviceMapperInfo{}
// Files with uint64 fields
for file, p := range map[string]*uint64{
"rq_based_seq_io_merge_deadline": &info.RqBasedSeqIOMergeDeadline,
"suspended": &info.Suspended,
"use_blk_mq": &info.UseBlkMQ,
} {
val, err := util.ReadUintFromFile(fs.sys.Path(sysBlockPath, device, sysBlockDM, file))
if err != nil {
return DeviceMapperInfo{}, err
}
*p = val
}
// Files with string fields
for file, p := range map[string]*string{
"name": &info.Name,
"uuid": &info.UUID,
} {
val, err := util.SysReadFile(fs.sys.Path(sysBlockPath, device, sysBlockDM, file))
if err != nil {
return DeviceMapperInfo{}, err
}
*p = val
}
return info, nil
}

func (fs FS) SysBlockDeviceUnderlyingDevices(device string) (UnderlyingDeviceInfo, error) {
underlyingDir, err := os.Open(fs.sys.Path(sysBlockPath, device, sysUnderlyingDev))
if err != nil {
return UnderlyingDeviceInfo{}, err
}
underlying, err := underlyingDir.Readdirnames(0)
if err != nil {
return UnderlyingDeviceInfo{}, err
}
return UnderlyingDeviceInfo{DeviceNames: underlying}, nil

}
67 changes: 67 additions & 0 deletions blockdevice/stats_test.go
Expand Up @@ -14,6 +14,7 @@
package blockdevice

import (
"os"
"reflect"
"testing"
)
Expand Down Expand Up @@ -152,3 +153,69 @@ func TestBlockDevice(t *testing.T) {
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", blockQueueStatExpected, blockQueueStat)
}
}

func TestBlockDmInfo(t *testing.T) {
blockdevice, err := NewFS("../fixtures/proc", "../fixtures/sys")
if err != nil {
t.Fatalf("failed to access blockdevice fs: %v", err)
}
devices, err := blockdevice.SysBlockDevices()
if err != nil {
t.Fatal(err)
}
dm0Info, err := blockdevice.SysBlockDeviceMapperInfo(devices[0])
if err != nil {
t.Fatal(err)
}

dm0InfoExpected := DeviceMapperInfo{
Name: "vg0--lv_root",
RqBasedSeqIOMergeDeadline: 0,
Suspended: 0,
UseBlkMQ: 0,
UUID: "LVM-3zSHSR5Nbf4j7g6auAAefWY2CMaX01theZYEvQyecVsm2WtX3iY5q51qq5dWWOq7",
}
if !reflect.DeepEqual(dm0Info, dm0InfoExpected) {
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", dm0InfoExpected, dm0Info)
}

dm1Info, err := blockdevice.SysBlockDeviceMapperInfo(devices[1])
if err != nil {
if _, ok := err.(*os.PathError); ok {
// Fail the test if there's an error other than PathError.
if !os.IsNotExist(err) {
t.Fatal(err)
}
} else {
t.Fatal(err)
}
} else {
t.Fatal("SysBlockDeviceMapperInfo on sda was supposed to fail.")
}
dm1InfoExpected := DeviceMapperInfo{}
if !reflect.DeepEqual(dm1Info, dm1InfoExpected) {
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", dm0InfoExpected, dm0Info)
}
}

func TestSysBlockDeviceUnderlyingDevices(t *testing.T) {
blockdevice, err := NewFS("../fixtures/proc", "../fixtures/sys")
if err != nil {
t.Fatalf("failed to access blockdevice fs: %v", err)
}
devices, err := blockdevice.SysBlockDevices()
if err != nil {
t.Fatal(err)
}

underlying0, err := blockdevice.SysBlockDeviceUnderlyingDevices(devices[0])
if err != nil {
t.Fatal(err)
}
underlying0Expected := UnderlyingDeviceInfo{
DeviceNames: []string{"sda"},
}
if !reflect.DeepEqual(underlying0, underlying0Expected) {
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", underlying0Expected, underlying0)
}
}
65 changes: 65 additions & 0 deletions fixtures.ttar
Expand Up @@ -3231,6 +3231,41 @@ Mode: 775
Directory: fixtures/sys/block/dm-0
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/block/dm-0/dm
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/dm/name
Lines: 1
vg0--lv_rootEOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/dm/rq_based_seq_io_merge_deadline
Lines: 1
0EOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/dm/suspended
Lines: 1
0EOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/dm/use_blk_mq
Lines: 1
0EOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/dm/uuid
Lines: 1
LVM-3zSHSR5Nbf4j7g6auAAefWY2CMaX01theZYEvQyecVsm2WtX3iY5q51qq5dWWOq7EOF
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/block/dm-0/slaves
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/slaves/sda
Lines: 0
Mode: 664
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/block/dm-0/stat
Lines: 1
6447303 0 710266738 1529043 953216 0 31201176 4557464 0 796160 6088971
Expand Down Expand Up @@ -3478,6 +3513,27 @@ Mode: 664
Directory: fixtures/sys/class
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/class/block
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-0
SymlinkTo: ../../devices/virtual/block/dm-0
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-1
SymlinkTo: ../../devices/virtual/block/dm-1
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-2
SymlinkTo: ../../devices/virtual/block/dm-2
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-3
SymlinkTo: ../../devices/virtual/block/dm-3
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-4
SymlinkTo: ../../devices/virtual/block/dm-4
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Path: fixtures/sys/class/block/dm-5
SymlinkTo: ../../devices/virtual/block/dm-5
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/class/dmi
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down Expand Up @@ -6496,6 +6552,15 @@ nr_zone_active_file 11
nr_zone_unevictable 12
Mode: 644
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/virtual
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/virtual/block
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/devices/virtual/block/dm-0
Mode: 775
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directory: fixtures/sys/fs
Mode: 755
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Expand Down

0 comments on commit fbe360a

Please sign in to comment.