Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly detect dm devices #301

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
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"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

LGTM but let's hear from @jaypipes because of the API-level change

// 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) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

we will probably need to review this flow more deeply, but that's totally material for another PR. This change LGTM for this PR

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))
}
}