From 6614296e08cf77d8ce1b673f4c24b1de351d3637 Mon Sep 17 00:00:00 2001 From: Aidan Leuck Date: Mon, 25 Aug 2025 10:05:33 -0600 Subject: [PATCH] add test that we can identify multipath devices even with other dm devices Signed-off-by: Aidan Leuck --- ghw/ghw_test.go | 80 +++++++++++++++++++++++++++++++++++++++---- ghw/mocks/ghw_mock.go | 19 ++++++---- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/ghw/ghw_test.go b/ghw/ghw_test.go index 3ba9c4a..e3cc155 100644 --- a/ghw/ghw_test.go +++ b/ghw/ghw_test.go @@ -83,7 +83,7 @@ var _ = Describe("GHW functions tests", func() { FS: "ext4", MountPoint: "/boot", Size: 512, - UUID: "part1-uuid-456", + UUID: "part1-mpath-uuid-456", }, { Name: "dm-2", @@ -91,7 +91,7 @@ var _ = Describe("GHW functions tests", func() { FS: "xfs", MountPoint: "/data", Size: 1024, - UUID: "part2-uuid-789", + UUID: "part2-mpath-uuid-789", }, }, } @@ -127,7 +127,7 @@ var _ = Describe("GHW functions tests", func() { Expect(part1.FilesystemLabel).To(Equal("MPATH_BOOT")) Expect(part1.FS).To(Equal("ext4")) Expect(part1.MountPoint).To(Equal("/boot")) - Expect(part1.UUID).To(Equal("part1-uuid-456")) + Expect(part1.UUID).To(Equal("part1-mpath-uuid-456")) Expect(part1.Path).To(Equal("/dev/dm-1")) Expect(part1.Disk).To(Equal("/dev/dm-0")) @@ -137,7 +137,7 @@ var _ = Describe("GHW functions tests", func() { Expect(part2.FilesystemLabel).To(Equal("MPATH_DATA")) Expect(part2.FS).To(Equal("xfs")) Expect(part2.MountPoint).To(Equal("/data")) - Expect(part2.UUID).To(Equal("part2-uuid-789")) + Expect(part2.UUID).To(Equal("part2-mpath-uuid-789")) Expect(part2.Path).To(Equal("/dev/dm-2")) Expect(part2.Disk).To(Equal("/dev/dm-0")) }) @@ -173,7 +173,7 @@ var _ = Describe("GHW functions tests", func() { FS: "ext4", MountPoint: "/boot", Size: 256, - UUID: "dm-part1-uuid", + UUID: "part1-mpath-uuid", }, { Name: "dm-5", @@ -181,7 +181,7 @@ var _ = Describe("GHW functions tests", func() { FS: "xfs", MountPoint: "/data", Size: 512, - UUID: "dm-part2-uuid", + UUID: "part2-mpath-uuid", }, }, } @@ -259,7 +259,7 @@ var _ = Describe("GHW functions tests", func() { FS: "ext4", MountPoint: "/boot", Size: 512, - UUID: "part1-uuid-456", + UUID: "part1-mpath-uuid-456", }, }, } @@ -315,4 +315,70 @@ var _ = Describe("GHW functions tests", func() { }) }) + Describe("It can differentiate between multipath-disks and other device-mapper devices", func() { + It("Identifies only multipath devices", func() { + // Create multipath device + multipathDeviceDef := types.Disk{ + Name: "dm-0", + UUID: "mpath-uuid-123", + SizeBytes: 10 * 1024 * 1024, + Partitions: []*types.Partition{ + { + Name: "dm-1", + FilesystemLabel: "MPATH_BOOT", + FS: "ext4", + MountPoint: "/boot", + Size: 512, + UUID: "part1-mpath-uuid-456", + }, + }, + } + + // Create a device-mapper device that is not multipath + cryptsDisk := types.Disk{ + Name: "dm-2", + UUID: "CRYPT-LUKS1-fdsfsdfsdgxv-luks-34214546534dfd", + SizeBytes: 8 * 1024 * 1024, + Partitions: []*types.Partition{ + { + Name: "dm-3", + FilesystemLabel: "REGULAR_ROOT", + FS: "ext4", + MountPoint: "/", + Size: 2048, + UUID: "part1-CRYPT-LUKS1-fdsfsdfsdgxv-luks-34214546534dfd", + }, + }, + } + + // Add both disks + ghwMock.AddDisk(multipathDeviceDef) + ghwMock.AddDisk(cryptsDisk) + + // Create multipath structure (this will handle both disks appropriately) + ghwMock.CreateMultipathDevices() + + disks := ghw.GetDisks(ghw.NewPaths(ghwMock.Chroot), nil) + + // The LUKS device is identified as a regular disk, so we have 3 disks in total. + // This is because the LUKS device is not skipped like multipath partitions are and currently will not work + // with Kairos. + Expect(len(disks)).To(Equal(3)) + + // Make sure we can identify the multipath device + var foundMultipathDisk *types.Disk + for _, disk := range disks { + if disk.Name == "dm-0" { + foundMultipathDisk = disk + } + } + + Expect(foundMultipathDisk).ToNot(BeNil()) + + // Verify multipath device has its partition + Expect(len(foundMultipathDisk.Partitions)).To(Equal(1)) + Expect(foundMultipathDisk.Partitions[0].Name).To(Equal("dm-1")) + }) + }) + }) diff --git a/ghw/mocks/ghw_mock.go b/ghw/mocks/ghw_mock.go index f00817b..8a72d43 100644 --- a/ghw/mocks/ghw_mock.go +++ b/ghw/mocks/ghw_mock.go @@ -208,15 +208,15 @@ func (g *GhwMock) createMultipathDevicesWithMountFormat(useDmMount bool) { g.CreateDevices() // Now add multipath-specific structure for dm- devices - for indexDisk, disk := range g.disks { + for _, disk := range g.disks { if strings.HasPrefix(disk.Name, "dm-") { diskPath := filepath.Join(g.paths.SysBlock, disk.Name) // Create dm/name file dmDir := filepath.Join(diskPath, "dm") _ = os.MkdirAll(dmDir, 0755) - _ = os.WriteFile(filepath.Join(dmDir, "name"), []byte(fmt.Sprintf("mpath%d", indexDisk)), 0644) - _ = os.WriteFile(filepath.Join(dmDir, "uuid"), []byte(fmt.Sprintf("mpath-%s", disk.UUID)), 0644) + _ = os.WriteFile(filepath.Join(dmDir, "name"), []byte(fmt.Sprintf(disk.Name)), 0644) + _ = os.WriteFile(filepath.Join(dmDir, "uuid"), []byte(disk.UUID), 0644) // Create holders directory for partitions holdersDir := filepath.Join(diskPath, "holders") @@ -251,7 +251,12 @@ func (g *GhwMock) createMultipathPartitionWithMountFormat(parentDiskName string, _ = os.MkdirAll(partitionPath, 0755) // Create partition dev file (use unique device numbers) - partIndex := 100 + partNum // Ensure unique device numbers + udevDataIndex, err := strconv.Atoi((strings.TrimPrefix(partition.Name, "dm-"))) + if err != nil { + udevDataIndex = 0 // Fallback in case of error + } + + partIndex := 100 + partNum + udevDataIndex // Ensure unique device numbers _ = os.WriteFile(filepath.Join(partitionPath, "dev"), []byte(fmt.Sprintf("253:%d\n", partIndex)), 0644) _ = os.WriteFile(filepath.Join(partitionPath, "size"), []byte(fmt.Sprintf("%d\n", partition.Size)), 0644) @@ -259,7 +264,7 @@ func (g *GhwMock) createMultipathPartitionWithMountFormat(parentDiskName string, partDmDir := filepath.Join(partitionPath, "dm") _ = os.MkdirAll(partDmDir, 0755) _ = os.WriteFile(filepath.Join(partDmDir, "name"), []byte(fmt.Sprintf("%s%s", parentDiskName, partitionSuffix)), 0644) - _ = os.WriteFile(filepath.Join(partDmDir, "uuid"), []byte(fmt.Sprintf("part-mpath-%s", partition.UUID)), 0644) + _ = os.WriteFile(filepath.Join(partDmDir, "uuid"), []byte(partition.UUID), 0644) // Create slaves directory for partition pointing to parent partSlavesDir := filepath.Join(partitionPath, "slaves") @@ -273,7 +278,7 @@ func (g *GhwMock) createMultipathPartitionWithMountFormat(parentDiskName string, udevData := []string{ fmt.Sprintf("E:ID_FS_LABEL=%s\n", partition.FilesystemLabel), fmt.Sprintf("E:DM_NAME=%s%s\n", parentDiskName, partitionSuffix), - fmt.Sprintf("E:DM_UUID=mpath-%s\n", partitionSuffix), // This indicates it's a multipath partition + fmt.Sprintf("E:DM_UUID=%s\n", partition.UUID), // This indicates it's a multipath partition fmt.Sprintf("E:DM_PART=%d\n", partNum), // This indicates it's a multipath partition } if partition.FS != "" { @@ -338,7 +343,7 @@ func (g *GhwMock) AddMultipathPartition(parentDiskName string, partition *types. partDmDir := filepath.Join(partitionPath, "dm") _ = os.MkdirAll(partDmDir, 0755) _ = os.WriteFile(filepath.Join(partDmDir, "name"), []byte(fmt.Sprintf("%s%s", parentDiskName, partitionSuffix)), 0644) - _ = os.WriteFile(filepath.Join(partDmDir, "uuid"), []byte(fmt.Sprintf("part-mpath-%s", partition.UUID)), 0644) + _ = os.WriteFile(filepath.Join(partDmDir, "uuid"), []byte(partition.UUID), 0644) // Create slaves directory for partition pointing to parent partSlavesDir := filepath.Join(partitionPath, "slaves")