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

Add WithLoopDevices to report loop devices #310

Merged
merged 6 commits into from
Apr 4, 2022
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
6 changes: 6 additions & 0 deletions pkg/block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
DRIVE_TYPE_FDD // Floppy disk drive
DRIVE_TYPE_ODD // Optical disk drive
DRIVE_TYPE_SSD // Solid-state drive
DRIVE_TYPE_VIRTUAL // virtual drive i.e. loop devices
)

var (
Expand All @@ -38,6 +39,7 @@ var (
DRIVE_TYPE_FDD: "FDD",
DRIVE_TYPE_ODD: "ODD",
DRIVE_TYPE_SSD: "SSD",
DRIVE_TYPE_VIRTUAL: "virtual",
}

// NOTE(fromani): the keys are all lowercase and do not match
Expand All @@ -51,6 +53,7 @@ var (
"fdd": DRIVE_TYPE_FDD,
"odd": DRIVE_TYPE_ODD,
"ssd": DRIVE_TYPE_SSD,
"virtual": DRIVE_TYPE_VIRTUAL,
}
)

Expand Down Expand Up @@ -93,6 +96,7 @@ const (
STORAGE_CONTROLLER_NVME // Non-volatile Memory Express
STORAGE_CONTROLLER_VIRTIO // Virtualized storage controller/driver
STORAGE_CONTROLLER_MMC // Multi-media controller (used for mobile phone storage devices)
STORAGE_CONTROLLER_LOOP // loop device
)

var (
Expand All @@ -103,6 +107,7 @@ var (
STORAGE_CONTROLLER_NVME: "NVMe",
STORAGE_CONTROLLER_VIRTIO: "virtio",
STORAGE_CONTROLLER_MMC: "MMC",
STORAGE_CONTROLLER_LOOP: "loop",
}

// NOTE(fromani): the keys are all lowercase and do not match
Expand All @@ -117,6 +122,7 @@ var (
"nvme": STORAGE_CONTROLLER_NVME,
"virtio": STORAGE_CONTROLLER_VIRTIO,
"mmc": STORAGE_CONTROLLER_MMC,
"loop": STORAGE_CONTROLLER_LOOP,
}
)

Expand Down
10 changes: 7 additions & 3 deletions pkg/block/block_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,6 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
}
for _, file := range files {
dname := file.Name()
if strings.HasPrefix(dname, "loop") {
continue
}

driveType, storageController := diskTypes(dname)
// TODO(jaypipes): Move this into diskTypes() once abstracting
Expand All @@ -329,6 +326,10 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk {
wwn := diskWWN(paths, dname)
removable := diskIsRemovable(paths, dname)

if storageController == STORAGE_CONTROLLER_LOOP && size == 0 {
// We don't care about unused loop devices...
continue
}
d := &Disk{
Name: dname,
SizeBytes: size,
Expand Down Expand Up @@ -390,6 +391,9 @@ func diskTypes(dname string) (
} else if strings.HasPrefix(dname, "mmc") {
driveType = DRIVE_TYPE_SSD
storageController = STORAGE_CONTROLLER_MMC
} else if strings.HasPrefix(dname, "loop") {
driveType = DRIVE_TYPE_VIRTUAL
storageController = STORAGE_CONTROLLER_LOOP
}

return driveType, storageController
Expand Down
58 changes: 58 additions & 0 deletions pkg/block/block_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/jaypipes/ghw/pkg/context"
"github.com/jaypipes/ghw/pkg/linuxpath"
"github.com/jaypipes/ghw/pkg/option"
"github.com/jaypipes/ghw/pkg/util"
)

Expand Down Expand Up @@ -168,6 +169,13 @@ func TestDiskTypes(t *testing.T) {
storageController: STORAGE_CONTROLLER_UNKNOWN,
},
},
{
line: "loop0",
expected: entry{
driveType: DRIVE_TYPE_VIRTUAL,
storageController: STORAGE_CONTROLLER_LOOP,
},
},
}

for _, test := range tests {
Expand Down Expand Up @@ -248,3 +256,53 @@ func TestDiskTypeUdev(t *testing.T) {
t.Fatalf("Got partition type %s, but expected %s", pt, util.UNKNOWN)
}
}

// TestLoopDevicesWithOption tests to see if we find loop devices when the option is activated
func TestLoopDevicesWithOption(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(option.WithNullAlerter(), option.WithDisableTools())
ctx.Chroot = baseDir
paths := linuxpath.New(ctx)
fsType := "ext4"
expectedLoopName := "loop0"
loopNotUsed := "loop1"
loopPartitionName := "loop0p1"

_ = os.MkdirAll(paths.SysBlock, 0755)
_ = os.MkdirAll(paths.RunUdevData, 0755)

// Emulate a loop device with one partition and another loop deviced not used
_ = os.Mkdir(filepath.Join(paths.SysBlock, expectedLoopName), 0755)
_ = os.Mkdir(filepath.Join(paths.SysBlock, loopNotUsed), 0755)
_ = os.Mkdir(filepath.Join(paths.SysBlock, expectedLoopName, "queue"), 0755)
_ = os.Mkdir(filepath.Join(paths.SysBlock, loopNotUsed, "queue"), 0755)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, expectedLoopName, "queue", "rotational"), []byte("1\n"), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, expectedLoopName, "size"), []byte("62810112\n"), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, loopNotUsed, "size"), []byte("0\n"), 0644)
_ = os.Mkdir(filepath.Join(paths.SysBlock, expectedLoopName, loopPartitionName), 0755)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, expectedLoopName, loopPartitionName, "dev"), []byte("259:0\n"), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.SysBlock, expectedLoopName, loopPartitionName, "size"), []byte("102400\n"), 0644)
_ = ioutil.WriteFile(filepath.Join(paths.RunUdevData, "b259:0"), []byte(fmt.Sprintf("E:ID_FS_TYPE=%s\n", fsType)), 0644)
d := disks(ctx, paths)
// There should be one disk, the other should be ignored due to 0 size
if len(d) != 1 {
t.Fatalf("expected one disk device but the function reported %d", len(d))
}
foundDisk := d[0]
// Should be the one we faked
if foundDisk.Name != expectedLoopName {
t.Fatalf("got loop device %s but expected %s", foundDisk.Name, expectedLoopName)
}
// Should have only one partition
if len(foundDisk.Partitions) != 1 {
t.Fatalf("expected one partition but the function reported %d", len(foundDisk.Partitions))
}
// Name should match
if foundDisk.Partitions[0].Name != loopPartitionName {
t.Fatalf("got partition %s but expected %s", foundDisk.Partitions[0], loopPartitionName)
}
}
10 changes: 9 additions & 1 deletion pkg/block/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,15 @@ func TestBlock(t *testing.T) {
t.Fatalf("Expected >0 disks. Got %d", len(disks))
}

d0 := disks[0]
var d0 *block.Disk
// Skip loop devices on generic tests as we don't know what the underlying system is going to have
// And loop devices don't have Serial Numbers for example.
for _, d := range disks {
if d.StorageController != block.STORAGE_CONTROLLER_LOOP {
d0 = d
break
}
}
Comment on lines +45 to +52
Copy link
Owner

Choose a reason for hiding this comment

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

👍

if d0.Name == "" {
t.Fatalf("Expected disk name, but got \"\"")
}
Expand Down