Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions pkg/implementation/physicaldrivegetter/rhel8.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ type (
}

BlockDevice struct {
DevicePath string
Size uint64
Rotational string
Type string
Tran string
MountPoint string
PartitionType string
FilesystemType string
DevicePath string
Size uint64
Rotational string
Type string
Tran string
MountPoint string
PartitionType string
FileSystemType string
ParentKernelName string
}
)

Expand All @@ -55,9 +56,17 @@ func (r *RHEL8) PhysicalDrives(
return nil, errors.Wrap(err, "failed to list block devices")
}

pkNames := make(map[string]struct{})

physicalDrives := make([]*physicaldrive.PhysicalDrive, 0, len(blockDevices))

for _, device := range blockDevices {
// We need to find the parent kernel names of the block devices
// to set the Used status correctly.
if device.ParentKernelName != "" {
pkNames[device.ParentKernelName] = struct{}{}
}

physicalDrive, err := r.PhysicalDrive(&physicaldrive.Metadata{
ID: device.DevicePath,
})
Expand All @@ -68,6 +77,17 @@ func (r *RHEL8) PhysicalDrives(
physicalDrives = append(physicalDrives, physicalDrive)
}

// Set the Used status if the physical drive is a disk
// and its parent kernel name is in the list of block devices
// of the partitions.
for pkName := range pkNames {
for _, physicalDrive := range physicalDrives {
if pkName == physicalDrive.ID {
physicalDrive.Status = physicaldrive.PDStatusUsed
}
}
}

return physicalDrives, nil
}

Expand Down Expand Up @@ -207,7 +227,10 @@ func (r *RHEL8) physicalDriveStatus(device *BlockDevice) (physicaldrive.PDStatus
return physicaldrive.PDStatusFailed, "", nil
}

if device.MountPoint != "" || device.FilesystemType != "" || device.PartitionType != "" {
if device.MountPoint != "" ||
device.FileSystemType != "" ||
device.PartitionType != "" ||
device.ParentKernelName != "" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree on this one, a partition would have the ParentKernelName to set but it does not mean this partition is actually used

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#19

return physicaldrive.PDStatusUsed, reason, nil
}

Expand All @@ -221,7 +244,7 @@ func (r *RHEL8) getBlockDevice(devicePath string) (*BlockDevice, error) {
"--bytes",
"--nodeps",
"--output",
"name,rota,size,type,tran,mountpoint,fstype,parttype",
"name,rota,size,type,tran,mountpoint,fstype,parttype,pkname",
})
if err != nil {
return nil, errors.Wrap(err, "failed to get block device using lsblk")
Expand All @@ -245,7 +268,7 @@ func (r *RHEL8) listBlockDevices() ([]BlockDevice, error) {
"--paths",
"--bytes",
"--output",
"name,rota,size,type,tran,mountpoint,fstype,parttype",
"name,rota,size,type,tran,mountpoint,fstype,parttype,pkname",
})
if err != nil {
return nil, errors.Wrap(err, "failed to run list block devices command")
Expand Down Expand Up @@ -327,9 +350,11 @@ func ParseLSBLKOutput(output []byte) ([]BlockDevice, error) {
case "MOUNTPOINT":
device.MountPoint = field
case "FSTYPE":
device.FilesystemType = field
device.FileSystemType = field
case "PARTTYPE":
device.PartitionType = field
case "PKNAME":
device.ParentKernelName = field
}
}
}
Expand Down
49 changes: 40 additions & 9 deletions pkg/implementation/physicaldrivegetter/rhel8_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,15 @@ func TestRHEL8_PhysicalDrives_Success(t *testing.T) {
// Setup mock for listing block devices
mockLSBLK.On("Run", mock.MatchedBy(func(args []string) bool {
return len(args) > 0 && args[0] == "--list"
})).Return([]byte(`NAME ROTA SIZE TYPE TRAN MOUNTPOINT FSTYPE PARTTYPE
/dev/nvme1n1 0 8589934592 disk nvme
/dev/nvme2n1 0 8589934592 disk nvme`), nil)
})).Return([]byte(`NAME ROTA SIZE TYPE TRAN MOUNTPOINT FSTYPE PARTTYPE PKNAME
/dev/nvme1n1 0 8589934592 disk nvme
/dev/nvme1n1p1 0 103809024 part nvme /boot/efi vfat c12a7328-f81f-11d2-ba4b-00a0c93ec93b /dev/nvme1n1
/dev/nvme2n1 0 8589934592 disk nvme`), nil)

// Setup mocks for first device
mockLSBLK.On("Run", mock.MatchedBy(func(args []string) bool {
return len(args) > 0 && args[0] == "/dev/nvme1n1"
})).Return([]byte(`NAME ROTA SIZE TYPE TRAN MOUNTPOINT FSTYPE PARTTYPE
})).Return([]byte(`NAME ROTA SIZE TYPE TRAN MOUNTPOINT FSTYPE PARTTYPE PKNAME
/dev/nvme1n1 0 8589934592 disk nvme`), nil)

mockUDevADM.On("Run", mock.MatchedBy(func(args []string) bool {
Expand All @@ -421,6 +422,26 @@ E: DEVNAME=/dev/nvme1n1
E: DEVLINKS=/dev/disk/by-id/nvme-123`), nil)

mockSmartCTL.On("Run", []string{"-a", "/dev/nvme1n1"}).Return([]byte(`
=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
`), nil)

// Setup mock for partition of the first device
mockLSBLK.On("Run", mock.MatchedBy(func(args []string) bool {
return len(args) > 0 && args[0] == "/dev/nvme1n1p1"
})).Return([]byte(`NAME ROTA SIZE TYPE TRAN MOUNTPOINT FSTYPE PARTTYPE PKNAME
/dev/nvme1n1p1 0 103809024 part nvme /boot/efi vfat c12a7328-f81f-11d2-ba4b-00a0c93ec93b /dev/nvme1n1
`), nil)

mockUDevADM.On("Run", mock.MatchedBy(func(args []string) bool {
return len(args) > 1 && args[2] == "--name=/dev/nvme1n1p1"
})).Return([]byte(`E: ID_MODEL=Amazon Elastic Block Store
E: ID_SERIAL_SHORT=vol05ece746e40ff492f
E: ID_WWN=nvme.1d0f-123456
E: DEVNAME=/dev/nvme1n1p1
E: DEVLINKS=/dev/disk/by-id/nvme-123`), nil)

mockSmartCTL.On("Run", []string{"-a", "/dev/nvme1n1p1"}).Return([]byte(`
=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
`), nil)
Expand Down Expand Up @@ -450,21 +471,31 @@ SMART overall-health self-assessment test result: PASSED

// Assertions
assert.NoError(t, err)
assert.Equal(t, 2, len(physicalDrives))
assert.Equal(t, 3, len(physicalDrives))

// First drive assertions
assert.Equal(t, "Amazon Elastic Block Store", physicalDrives[0].Model)
assert.Equal(t, "vol05ece746e40ff492f", physicalDrives[0].Serial)
assert.Equal(t, "/dev/nvme1n1", physicalDrives[0].ID)
assert.Equal(t, "/dev/nvme1n1", physicalDrives[0].DevicePath)
assert.Equal(t, physicaldrive.DiskTypeNVMe, physicalDrives[0].Type)
assert.Equal(t, physicaldrive.PDStatusUsed, physicalDrives[0].Status)

// Second drive assertions
// Partition of the first drive assertions
assert.Equal(t, "Amazon Elastic Block Store", physicalDrives[1].Model)
assert.Equal(t, "vol05ece746e40ff493g", physicalDrives[1].Serial)
assert.Equal(t, "/dev/nvme2n1", physicalDrives[1].ID)
assert.Equal(t, "/dev/nvme2n1", physicalDrives[1].DevicePath)
assert.Equal(t, "vol05ece746e40ff492f", physicalDrives[1].Serial)
assert.Equal(t, "/dev/nvme1n1p1", physicalDrives[1].ID)
assert.Equal(t, "/dev/nvme1n1p1", physicalDrives[1].DevicePath)
assert.Equal(t, physicaldrive.DiskTypeNVMe, physicalDrives[1].Type)
assert.Equal(t, physicaldrive.PDStatusUsed, physicalDrives[1].Status)

// Second drive assertions
assert.Equal(t, "Amazon Elastic Block Store", physicalDrives[2].Model)
assert.Equal(t, "vol05ece746e40ff493g", physicalDrives[2].Serial)
assert.Equal(t, "/dev/nvme2n1", physicalDrives[2].ID)
assert.Equal(t, "/dev/nvme2n1", physicalDrives[2].DevicePath)
assert.Equal(t, physicaldrive.DiskTypeNVMe, physicalDrives[2].Type)
assert.Equal(t, physicaldrive.PDStatusUnassignedGood, physicalDrives[2].Status)

mockLSBLK.AssertExpectations(t)
mockUDevADM.AssertExpectations(t)
Expand Down
7 changes: 5 additions & 2 deletions pkg/implementation/physicaldrivegetter/ssacli.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func (s *SSACLI) getBlockDevice(devicePath string) (*BlockDevice, error) {
"--bytes",
"--nodeps",
"--output",
"name,rota,size,type,tran,mountpoint,fstype,parttype",
"name,rota,size,type,tran,mountpoint,fstype,parttype,pkname",
})
if err != nil {
return nil, errors.Wrap(err, "failed to get block device using lsblk")
Expand Down Expand Up @@ -294,7 +294,10 @@ func parseSlotInfo(pd *physicaldrive.PhysicalDrive, key, value string) {
// If the device is mounted or has a filesystem type, it is considered used.
// Otherwise, it is considered unassigned good.
func isBlockDeviceUsed(device *BlockDevice) bool {
if device.MountPoint != "" || device.FilesystemType != "" || device.PartitionType != "" {
if device.MountPoint != "" ||
device.FileSystemType != "" ||
device.PartitionType != "" ||
device.ParentKernelName != "" {
return true
}

Expand Down