Skip to content

Commit 88bfa0d

Browse files
committed
sysinfo: Ignore "hidden" sysfs device entries
Some devices are "hidden" from userspace due to various reasons. One reason is native nvme multipathing, where the path devices do not present a device node to the user but only exposes the stacking device as the only nvme device. Still there are sysfs attributes for these hidden devices, but we should ignore them altogether because these are not "real" devices at all. Signed-off-by: Sagi Grimberg <[email protected]>
1 parent 0a9c9fa commit 88bfa0d

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

utils/sysfs/fakesysfs/fake.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ func (fs *FakeSysFs) GetBlockDeviceNumbers(name string) (string, error) {
128128
return "8:0\n", nil
129129
}
130130

131+
func (fs *FakeSysFs) IsBlockDeviceHidden(name string) (bool, error) {
132+
return false, nil
133+
}
134+
131135
func (fs *FakeSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
132136
return []os.FileInfo{&fs.info}, nil
133137
}

utils/sysfs/sysfs.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ type SysFs interface {
101101
GetBlockDeviceScheduler(string) (string, error)
102102
// Get device major:minor number string.
103103
GetBlockDeviceNumbers(string) (string, error)
104+
// Is the device "hidden" (meaning will not have a device handle)
105+
// This is the case with native nvme multipathing.
106+
IsBlockDeviceHidden(string) (bool, error)
104107

105108
GetNetworkDevices() ([]os.FileInfo, error)
106109
GetNetworkAddress(string) (string, error)
@@ -212,6 +215,26 @@ func (fs *realSysFs) GetBlockDeviceNumbers(name string) (string, error) {
212215
return string(dev), nil
213216
}
214217

218+
func (fs *realSysFs) IsBlockDeviceHidden(name string) (bool, error) {
219+
// See: https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-block
220+
// https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
221+
// - c8487d854ba5 ("lsblk: Ignore hidden devices")
222+
devHiddenPath := path.Join(blockDir, name, "/hidden")
223+
hidden, err := os.ReadFile(devHiddenPath)
224+
if err != nil && os.IsNotExist(err) {
225+
// older OS may not have /hidden sysfs entry, so for sure
226+
// it is not a hidden device...
227+
return false, nil
228+
}
229+
if err != nil {
230+
return false, fmt.Errorf("failed to read %s: %w", devHiddenPath, err)
231+
}
232+
if string(hidden) == "1" {
233+
return true, nil
234+
}
235+
return false, nil
236+
}
237+
215238
func (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {
216239
sched, err := os.ReadFile(path.Join(blockDir, name, "/queue/scheduler"))
217240
if err != nil {

utils/sysinfo/sysinfo.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
5757
if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") {
5858
continue
5959
}
60+
// Ignore "hidden" devices (i.e. nvme path device sysfs entries).
61+
// These devices are in the form of /dev/nvme$Xc$Yn$Z and will
62+
// not have a device handle (i.e. "hidden")
63+
isHidden, err := sysfs.IsBlockDeviceHidden(name)
64+
if err != nil {
65+
return nil, err
66+
}
67+
if isHidden {
68+
continue
69+
}
6070
diskInfo := info.DiskInfo{
6171
Name: name,
6272
}

0 commit comments

Comments
 (0)