Skip to content

Commit

Permalink
Properly detect dm devices
Browse files Browse the repository at this point in the history
Fixes: #298
Signed-off-by: Avishay Traeger <avishay@redhat.com>
  • Loading branch information
avishayt committed Mar 15, 2022
1 parent 50f78dc commit ab4afe5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
4 changes: 4 additions & 0 deletions pkg/block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
DRIVE_TYPE_ODD // Optical disk drive
DRIVE_TYPE_SSD // Solid-state drive
DRIVE_TYPE_ISCSI // iSCSI drive
DRIVE_TYPE_MAPPER // Mapper device
)

var (
Expand All @@ -40,6 +41,7 @@ var (
DRIVE_TYPE_ODD: "ODD",
DRIVE_TYPE_SSD: "SSD",
DRIVE_TYPE_ISCSI: "ISCSI",
DRIVE_TYPE_MAPPER: "Mapper",
}

// NOTE(fromani): the keys are all lowercase and do not match
Expand All @@ -54,6 +56,7 @@ var (
"odd": DRIVE_TYPE_ODD,
"ssd": DRIVE_TYPE_SSD,
"iscsi": DRIVE_TYPE_ISCSI,
"mapper": DRIVE_TYPE_MAPPER,
}
)

Expand Down Expand Up @@ -166,6 +169,7 @@ type Disk struct {
SerialNumber string `json:"serial_number"`
WWN string `json:"wwn"`
Partitions []*Partition `json:"partitions"`
Members []string `json:"members"`
// TODO(jaypipes): Add PCI field for accessing PCI device information
// PCI *PCIDevice `json:"pci"`
}
Expand Down
19 changes: 18 additions & 1 deletion pkg/block/block_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,19 @@ func diskIsRemovable(paths *linuxpath.Paths, disk string) bool {
return removable == "1"
}

func diskMembers(ctx *context.Context, paths *linuxpath.Paths, disk string) []string {
out := make([]string, 0)
path := filepath.Join(paths.SysBlock, disk, "slaves")
files, err := ioutil.ReadDir(path)
if err != nil {
return out
}
for _, file := range files {
out = append(out, file.Name())
}
return out
}

func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
// In Linux, we could use the fdisk, lshw or blockdev commands to list disk
// information, however all of these utilities require root privileges to
Expand All @@ -271,7 +284,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
driveType, storageController := diskTypes(dname)
// TODO(jaypipes): Move this into diskTypes() once abstracting
// diskIsRotational for ease of unit testing
if !diskIsRotational(ctx, paths, dname) {
if driveType != DRIVE_TYPE_MAPPER && !diskIsRotational(ctx, paths, dname) {
driveType = DRIVE_TYPE_SSD
}
size := diskSizeBytes(paths, dname)
Expand All @@ -286,6 +299,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
serialNo := diskSerialNumber(paths, dname)
wwn := diskWWN(paths, dname)
removable := diskIsRemovable(paths, dname)
members := diskMembers(ctx, paths, dname)

d := &Disk{
Name: dname,
Expand All @@ -300,6 +314,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
Model: model,
SerialNumber: serialNo,
WWN: wwn,
Members: members,
}

parts := diskPartitions(ctx, paths, dname)
Expand Down Expand Up @@ -348,6 +363,8 @@ func diskTypes(dname string) (
} else if strings.HasPrefix(dname, "mmc") {
driveType = DRIVE_TYPE_SSD
storageController = STORAGE_CONTROLLER_MMC
} else if strings.HasPrefix(dname, "dm-") {
driveType = DRIVE_TYPE_MAPPER
}

return driveType, storageController
Expand Down
42 changes: 42 additions & 0 deletions pkg/block/block_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,45 @@ func TestISCSI(t *testing.T) {
t.Fatalf("Got drive type %s, but expected ISCSI", diskInventory[0].DriveType)
}
}

func TestMapper(t *testing.T) {
if _, ok := os.LookupEnv("GHW_TESTING_SKIP_BLOCK"); ok {
t.Skip("Skipping block tests.")
}

baseDir, _ := ioutil.TempDir("", "test")
defer os.RemoveAll(baseDir)
ctx := context.New()
ctx.Chroot = baseDir
paths := linuxpath.New(ctx)

_ = os.MkdirAll(paths.SysBlock, 0755)
_ = os.MkdirAll(paths.RunUdevData, 0755)
// Emulate a mapper device with no members
_ = os.Mkdir(filepath.Join(paths.SysBlock, "dm-0"), 0755)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, "dm-0", "size"), []byte("419430400\n"), 0644)
_ = os.Mkdir(filepath.Join(paths.SysBlock, "dm-0", "queue"), 0755)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, "dm-0", "queue", "rotational"), []byte("0\n"), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, "dm-0", "queue", "physical_block_size"), []byte("512\n"), 0644)

diskInventory := disks(ctx, paths)
if diskInventory[0].DriveType != DRIVE_TYPE_MAPPER {
t.Fatalf("Got drive type %s, but expected Mapper", diskInventory[0].DriveType)
}
if len(diskInventory[0].Members) > 0 {
t.Fatalf("Got %d members but didn't expect any", len(diskInventory[0].Members))
}

// Add members (we create regular files here for brevity even though in reality they are symlinks)
_ = os.Mkdir(filepath.Join(paths.SysBlock, "dm-0", "slaves"), 0755)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, "dm-0", "slaves", "sda"), []byte(""), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, "dm-0", "slaves", "sdb"), []byte(""), 0644)

diskInventory = disks(ctx, paths)
if diskInventory[0].DriveType != DRIVE_TYPE_MAPPER {
t.Fatalf("Got drive type %s, but expected Mapper", diskInventory[0].DriveType)
}
if len(diskInventory[0].Members) != 2 {
t.Fatalf("Got %d members but expected 2", len(diskInventory[0].Members))
}
}

0 comments on commit ab4afe5

Please sign in to comment.