Skip to content

Commit

Permalink
sysinfo: Ignore "hidden" sysfs device entries
Browse files Browse the repository at this point in the history
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 <sagi@grimberg.me>
  • Loading branch information
sagigrimberg committed Jun 26, 2023
1 parent 0a9c9fa commit b7b05f8
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
4 changes: 4 additions & 0 deletions utils/sysfs/fakesysfs/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ func (fs *FakeSysFs) GetBlockDeviceNumbers(name string) (string, error) {
return "8:0\n", nil
}

func (fs *FakeSysFs) IsBlockDeviceHidden(name string) (bool, error) {
return false, nil
}

func (fs *FakeSysFs) GetNetworkDevices() ([]os.FileInfo, error) {
return []os.FileInfo{&fs.info}, nil
}
Expand Down
23 changes: 23 additions & 0 deletions utils/sysfs/sysfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ type SysFs interface {
GetBlockDeviceScheduler(string) (string, error)
// Get device major:minor number string.
GetBlockDeviceNumbers(string) (string, error)
// Is the device "hidden" (meaning will not have a device handle)
// This is the case with native nvme multipathing.
IsBlockDeviceHidden(string) (bool, error)

GetNetworkDevices() ([]os.FileInfo, error)
GetNetworkAddress(string) (string, error)
Expand Down Expand Up @@ -212,6 +215,26 @@ func (fs *realSysFs) GetBlockDeviceNumbers(name string) (string, error) {
return string(dev), nil
}

func (fs *realSysFs) IsBlockDeviceHidden(name string) (bool, error) {
// See: https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-block
// https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
// - c8487d854ba5 ("lsblk: Ignore hidden devices")
devHiddenPath := path.Join(blockDir, name, "/hidden")
hidden, err := os.ReadFile(devHiddenPath)
if err != nil && os.IsNotExist(err) {
// older OS may not have /hidden sysfs entry, so for sure
// it is not a hidden device...
return false, nil
}
if err != nil {
return false, fmt.Errorf("failed to read %s: %s", devHiddenPath, err)
}
if string(hidden) == "1" {
return true, nil
}
return false, nil
}

func (fs *realSysFs) GetBlockDeviceScheduler(name string) (string, error) {
sched, err := os.ReadFile(path.Join(blockDir, name, "/queue/scheduler"))
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions utils/sysinfo/sysinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) {
if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") {
continue
}
// Ignore "hidden" devices (i.e. nvme path device sysfs entries).
// These devices are in the form of /dev/nvme$Xc$Yn$Z and will
// not have a device handle (i.e. "hidden")
isHidden, err := sysfs.IsBlockDeviceHidden(name)
if err != nil {
return nil, err
}
if isHidden {
continue
}
diskInfo := info.DiskInfo{
Name: name,
}
Expand Down

0 comments on commit b7b05f8

Please sign in to comment.