Skip to content

Commit fbe360a

Browse files
ventifusW. Andrew Denton
andauthored
Add device-mapper-specific block device properties (#412)
* Expose device-mapper information as DeviceMapperInfo Signed-off-by: W. Andrew Denton <[email protected]> * Enumerate block device slaves as UnderlyingDeviceInfo Signed-off-by: W. Andrew Denton <[email protected]> * Add missing fixtures. Signed-off-by: W. Andrew Denton <[email protected]> * blockdevice/stats: uppercase initialisms. Signed-off-by: W. Andrew Denton <[email protected]> * Expose device-mapper information as DeviceMapperInfo Signed-off-by: W. Andrew Denton <[email protected]> * Expose device-mapper information as DeviceMapperInfo Signed-off-by: W. Andrew Denton <[email protected]> * Update fixtures. Signed-off-by: W. Andrew Denton <[email protected]> * Capitalize comments. Signed-off-by: W. Andrew Denton <[email protected]> Co-authored-by: W. Andrew Denton <[email protected]>
1 parent c6f5590 commit fbe360a

File tree

3 files changed

+202
-4
lines changed

3 files changed

+202
-4
lines changed

blockdevice/stats.go

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ package blockdevice
1616
import (
1717
"bufio"
1818
"fmt"
19-
"github.com/prometheus/procfs/internal/util"
2019
"io"
2120
"io/ioutil"
2221
"os"
2322
"strings"
2423

2524
"github.com/prometheus/procfs/internal/fs"
25+
"github.com/prometheus/procfs/internal/util"
2626
)
2727

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

181+
// DeviceMapperInfo models the devicemapper files that are located in the sysfs tree for each block device
182+
// and described in the kernel documentation:
183+
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm
184+
type DeviceMapperInfo struct {
185+
// Name is the string containing mapped device name.
186+
Name string
187+
// RqBasedSeqIOMergeDeadline determines how long (in microseconds) a request that is a reasonable merge
188+
// candidate can be queued on the request queue.
189+
RqBasedSeqIOMergeDeadline uint64
190+
// Suspended indicates if the device is suspended (1 is on, 0 is off).
191+
Suspended uint64
192+
// UseBlkMQ indicates if the device is using the request-based blk-mq I/O path mode (1 is on, 0 is off).
193+
UseBlkMQ uint64
194+
// UUID is the DM-UUID string or empty string if DM-UUID is not set.
195+
UUID string
196+
}
197+
198+
// UnderlyingDevices models the list of devices that this device is built from.
199+
type UnderlyingDeviceInfo struct {
200+
// DeviceNames is the list of devices names
201+
DeviceNames []string
202+
}
203+
181204
const (
182205
procDiskstatsPath = "diskstats"
183206
procDiskstatsFormat = "%d %d %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
184207
sysBlockPath = "block"
185208
sysBlockStatFormat = "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
186209
sysBlockQueue = "queue"
210+
sysBlockDM = "dm"
211+
sysUnderlyingDev = "slaves"
187212
)
188213

189214
// FS represents the pseudo-filesystems proc and sys, which provides an
@@ -317,7 +342,7 @@ func (fs FS) SysBlockDeviceStat(device string) (IOStats, int, error) {
317342
// SysBlockDeviceQueueStats returns stats for /sys/block/xxx/queue where xxx is a device name.
318343
func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
319344
stat := BlockQueueStats{}
320-
// files with uint64 fields
345+
// Files with uint64 fields
321346
for file, p := range map[string]*uint64{
322347
"add_random": &stat.AddRandom,
323348
"dax": &stat.DAX,
@@ -355,7 +380,7 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
355380
}
356381
*p = val
357382
}
358-
// files with int64 fields
383+
// Files with int64 fields
359384
for file, p := range map[string]*int64{
360385
"io_poll_delay": &stat.IOPollDelay,
361386
"wbt_lat_usec": &stat.WBTLatUSec,
@@ -366,7 +391,7 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
366391
}
367392
*p = val
368393
}
369-
// files with string fields
394+
// Files with string fields
370395
for file, p := range map[string]*string{
371396
"write_cache": &stat.WriteCache,
372397
"zoned": &stat.Zoned,
@@ -398,3 +423,44 @@ func (fs FS) SysBlockDeviceQueueStats(device string) (BlockQueueStats, error) {
398423
}
399424
return stat, nil
400425
}
426+
427+
func (fs FS) SysBlockDeviceMapperInfo(device string) (DeviceMapperInfo, error) {
428+
info := DeviceMapperInfo{}
429+
// Files with uint64 fields
430+
for file, p := range map[string]*uint64{
431+
"rq_based_seq_io_merge_deadline": &info.RqBasedSeqIOMergeDeadline,
432+
"suspended": &info.Suspended,
433+
"use_blk_mq": &info.UseBlkMQ,
434+
} {
435+
val, err := util.ReadUintFromFile(fs.sys.Path(sysBlockPath, device, sysBlockDM, file))
436+
if err != nil {
437+
return DeviceMapperInfo{}, err
438+
}
439+
*p = val
440+
}
441+
// Files with string fields
442+
for file, p := range map[string]*string{
443+
"name": &info.Name,
444+
"uuid": &info.UUID,
445+
} {
446+
val, err := util.SysReadFile(fs.sys.Path(sysBlockPath, device, sysBlockDM, file))
447+
if err != nil {
448+
return DeviceMapperInfo{}, err
449+
}
450+
*p = val
451+
}
452+
return info, nil
453+
}
454+
455+
func (fs FS) SysBlockDeviceUnderlyingDevices(device string) (UnderlyingDeviceInfo, error) {
456+
underlyingDir, err := os.Open(fs.sys.Path(sysBlockPath, device, sysUnderlyingDev))
457+
if err != nil {
458+
return UnderlyingDeviceInfo{}, err
459+
}
460+
underlying, err := underlyingDir.Readdirnames(0)
461+
if err != nil {
462+
return UnderlyingDeviceInfo{}, err
463+
}
464+
return UnderlyingDeviceInfo{DeviceNames: underlying}, nil
465+
466+
}

blockdevice/stats_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package blockdevice
1515

1616
import (
17+
"os"
1718
"reflect"
1819
"testing"
1920
)
@@ -152,3 +153,69 @@ func TestBlockDevice(t *testing.T) {
152153
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", blockQueueStatExpected, blockQueueStat)
153154
}
154155
}
156+
157+
func TestBlockDmInfo(t *testing.T) {
158+
blockdevice, err := NewFS("../fixtures/proc", "../fixtures/sys")
159+
if err != nil {
160+
t.Fatalf("failed to access blockdevice fs: %v", err)
161+
}
162+
devices, err := blockdevice.SysBlockDevices()
163+
if err != nil {
164+
t.Fatal(err)
165+
}
166+
dm0Info, err := blockdevice.SysBlockDeviceMapperInfo(devices[0])
167+
if err != nil {
168+
t.Fatal(err)
169+
}
170+
171+
dm0InfoExpected := DeviceMapperInfo{
172+
Name: "vg0--lv_root",
173+
RqBasedSeqIOMergeDeadline: 0,
174+
Suspended: 0,
175+
UseBlkMQ: 0,
176+
UUID: "LVM-3zSHSR5Nbf4j7g6auAAefWY2CMaX01theZYEvQyecVsm2WtX3iY5q51qq5dWWOq7",
177+
}
178+
if !reflect.DeepEqual(dm0Info, dm0InfoExpected) {
179+
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", dm0InfoExpected, dm0Info)
180+
}
181+
182+
dm1Info, err := blockdevice.SysBlockDeviceMapperInfo(devices[1])
183+
if err != nil {
184+
if _, ok := err.(*os.PathError); ok {
185+
// Fail the test if there's an error other than PathError.
186+
if !os.IsNotExist(err) {
187+
t.Fatal(err)
188+
}
189+
} else {
190+
t.Fatal(err)
191+
}
192+
} else {
193+
t.Fatal("SysBlockDeviceMapperInfo on sda was supposed to fail.")
194+
}
195+
dm1InfoExpected := DeviceMapperInfo{}
196+
if !reflect.DeepEqual(dm1Info, dm1InfoExpected) {
197+
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", dm0InfoExpected, dm0Info)
198+
}
199+
}
200+
201+
func TestSysBlockDeviceUnderlyingDevices(t *testing.T) {
202+
blockdevice, err := NewFS("../fixtures/proc", "../fixtures/sys")
203+
if err != nil {
204+
t.Fatalf("failed to access blockdevice fs: %v", err)
205+
}
206+
devices, err := blockdevice.SysBlockDevices()
207+
if err != nil {
208+
t.Fatal(err)
209+
}
210+
211+
underlying0, err := blockdevice.SysBlockDeviceUnderlyingDevices(devices[0])
212+
if err != nil {
213+
t.Fatal(err)
214+
}
215+
underlying0Expected := UnderlyingDeviceInfo{
216+
DeviceNames: []string{"sda"},
217+
}
218+
if !reflect.DeepEqual(underlying0, underlying0Expected) {
219+
t.Errorf("Incorrect BlockQueueStat, expected: \n%+v, got: \n%+v", underlying0Expected, underlying0)
220+
}
221+
}

fixtures.ttar

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,6 +3231,41 @@ Mode: 775
32313231
Directory: fixtures/sys/block/dm-0
32323232
Mode: 775
32333233
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3234+
Directory: fixtures/sys/block/dm-0/dm
3235+
Mode: 755
3236+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3237+
Path: fixtures/sys/block/dm-0/dm/name
3238+
Lines: 1
3239+
vg0--lv_rootEOF
3240+
Mode: 644
3241+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3242+
Path: fixtures/sys/block/dm-0/dm/rq_based_seq_io_merge_deadline
3243+
Lines: 1
3244+
0EOF
3245+
Mode: 644
3246+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3247+
Path: fixtures/sys/block/dm-0/dm/suspended
3248+
Lines: 1
3249+
0EOF
3250+
Mode: 644
3251+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3252+
Path: fixtures/sys/block/dm-0/dm/use_blk_mq
3253+
Lines: 1
3254+
0EOF
3255+
Mode: 644
3256+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3257+
Path: fixtures/sys/block/dm-0/dm/uuid
3258+
Lines: 1
3259+
LVM-3zSHSR5Nbf4j7g6auAAefWY2CMaX01theZYEvQyecVsm2WtX3iY5q51qq5dWWOq7EOF
3260+
Mode: 644
3261+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3262+
Directory: fixtures/sys/block/dm-0/slaves
3263+
Mode: 755
3264+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3265+
Path: fixtures/sys/block/dm-0/slaves/sda
3266+
Lines: 0
3267+
Mode: 664
3268+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32343269
Path: fixtures/sys/block/dm-0/stat
32353270
Lines: 1
32363271
6447303 0 710266738 1529043 953216 0 31201176 4557464 0 796160 6088971
@@ -3478,6 +3513,27 @@ Mode: 664
34783513
Directory: fixtures/sys/class
34793514
Mode: 775
34803515
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3516+
Directory: fixtures/sys/class/block
3517+
Mode: 775
3518+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3519+
Path: fixtures/sys/class/block/dm-0
3520+
SymlinkTo: ../../devices/virtual/block/dm-0
3521+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3522+
Path: fixtures/sys/class/block/dm-1
3523+
SymlinkTo: ../../devices/virtual/block/dm-1
3524+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3525+
Path: fixtures/sys/class/block/dm-2
3526+
SymlinkTo: ../../devices/virtual/block/dm-2
3527+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3528+
Path: fixtures/sys/class/block/dm-3
3529+
SymlinkTo: ../../devices/virtual/block/dm-3
3530+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3531+
Path: fixtures/sys/class/block/dm-4
3532+
SymlinkTo: ../../devices/virtual/block/dm-4
3533+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3534+
Path: fixtures/sys/class/block/dm-5
3535+
SymlinkTo: ../../devices/virtual/block/dm-5
3536+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34813537
Directory: fixtures/sys/class/dmi
34823538
Mode: 775
34833539
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -6496,6 +6552,15 @@ nr_zone_active_file 11
64966552
nr_zone_unevictable 12
64976553
Mode: 644
64986554
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6555+
Directory: fixtures/sys/devices/virtual
6556+
Mode: 775
6557+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6558+
Directory: fixtures/sys/devices/virtual/block
6559+
Mode: 775
6560+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6561+
Directory: fixtures/sys/devices/virtual/block/dm-0
6562+
Mode: 775
6563+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
64996564
Directory: fixtures/sys/fs
65006565
Mode: 755
65016566
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

0 commit comments

Comments
 (0)