make checks more robust and update mock with extra udev info

Signed-off-by: Aidan Leuck <aidan_leuck@selinc.com>
This commit is contained in:
Aidan Leuck
2025-08-08 09:11:18 -06:00
committed by Dimitris Karakasilis
parent 1cd4261f67
commit 3018f86c47
3 changed files with 61 additions and 7 deletions

View File

@@ -47,8 +47,41 @@ func NewPaths(withOptionalPrefix string) *Paths {
return p
}
func isMultipathDevice(entry os.DirEntry) bool {
return strings.HasPrefix(entry.Name(), "dm-")
func isMultipathDevice(paths *Paths, entry os.DirEntry, logger *types.KairosLogger) bool {
hasPrefix := strings.HasPrefix(entry.Name(), "dm-")
if !hasPrefix {
return false
}
// Check if the device has a "slaves" directory, which is a common indicator
_, err := os.Stat(filepath.Join(paths.SysBlock, entry.Name(), "slaves"))
if err != nil {
var msg string
if os.IsNotExist(err) {
msg = "No slaves directory, not a multipath device"
} else {
msg = "Error checking slaves directory"
}
logger.Logger.Debug().Str("devNo", entry.Name()).Msg(msg)
return false
}
// If the device has a "slaves" directory, we can check its udev info
// to confirm it's a multipath device.
// This is a more reliable check than just the name.
udevInfo, err := udevInfoPartition(paths, entry.Name(), logger)
if err != nil {
logger.Logger.Error().Err(err).Str("devNo", entry.Name()).Msg("Failed to get udev info")
return false
}
// Check if the udev info contains DM_NAME indicating it's a multipath device
_, ok := udevInfo["DM_NAME"]
if !ok {
logger.Logger.Debug().Str("devNo", entry.Name()).Msg("Not a multipath device")
}
return ok
}
func GetDisks(paths *Paths, logger *types.KairosLogger) []*types.Disk {
@@ -85,7 +118,7 @@ func GetDisks(paths *Paths, logger *types.KairosLogger) []*types.Disk {
UUID: diskUUID(paths, dname, logger),
}
if(isMultipathDevice(file)) {
if(isMultipathDevice(paths, file, logger)) {
partitionHandler = NewMultipathPartitionHandler(dname)
} else {
partitionHandler = NewDiskPartitionHandler(dname)
@@ -103,7 +136,7 @@ func GetDisks(paths *Paths, logger *types.KairosLogger) []*types.Disk {
func isMultipathPartition(entry os.DirEntry, paths *Paths, logger *types.KairosLogger) bool {
// Must be a dm device to be a multipath partition
if !isMultipathDevice(entry) {
if !isMultipathDevice(paths, entry, logger) {
return false
}

View File

@@ -67,7 +67,18 @@ func (g *GhwMock) CreateDevices() {
// Also write the size
_ = os.WriteFile(filepath.Join(g.paths.SysBlock, disk.Name, "size"), []byte(strconv.FormatUint(disk.SizeBytes, 10)), 0644)
// Create the udevdata for this disk
_ = os.WriteFile(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%d:0", indexDisk)), []byte(fmt.Sprintf("E:ID_PART_TABLE_UUID=%s\n", disk.UUID)), 0644)
var diskUdevData []string
diskUdevData = append(diskUdevData, fmt.Sprintf("E:ID_PART_TABLE_UUID=%s\n", disk.UUID))
// Add DM_NAME for dm devices (needed for isMultipathDevice detection)
if strings.HasPrefix(disk.Name, "dm-") {
diskUdevData = append(diskUdevData, fmt.Sprintf("E:DM_NAME=%s\n", disk.Name))
diskUdevData = append(diskUdevData, "E:DM_SUSPENDED=0\n")
diskUdevData = append(diskUdevData, "E:DM_UDEV_RULES=1\n")
diskUdevData = append(diskUdevData, "E:SUBSYSTEM=block\n")
}
_ = os.WriteFile(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%d:0", indexDisk)), []byte(strings.Join(diskUdevData, "")), 0644)
for indexPart, partition := range disk.Partitions {
// For each partition we create the /sys/block/DISK_NAME/PARTITION_NAME
_ = os.Mkdir(filepath.Join(diskPath, partition.Name), 0755)
@@ -249,6 +260,11 @@ func (g *GhwMock) createMultipathPartitionWithMountFormat(parentDiskName string,
_ = 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)
// Create slaves directory for partition pointing to parent
partSlavesDir := filepath.Join(partitionPath, "slaves")
_ = os.MkdirAll(partSlavesDir, 0755)
_ = os.WriteFile(filepath.Join(partSlavesDir, parentDiskName), []byte(""), 0644)
// Create holder symlink from parent to partition
_ = os.WriteFile(filepath.Join(holdersDir, partition.Name), []byte(""), 0644)
@@ -327,6 +343,11 @@ func (g *GhwMock) AddMultipathPartition(parentDiskName string, partition *types.
_ = 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)
// Create slaves directory for partition pointing to parent
partSlavesDir := filepath.Join(partitionPath, "slaves")
_ = os.MkdirAll(partSlavesDir, 0755)
_ = os.WriteFile(filepath.Join(partSlavesDir, parentDiskName), []byte(""), 0644)
// Create holder symlink from parent to partition
_ = os.WriteFile(filepath.Join(holdersDir, partition.Name), []byte(""), 0644)

View File

@@ -36,8 +36,8 @@ func (m *MultipathPartitionHandler) GetPartitions(paths *Paths, logger *types.Ka
partName := holder.Name()
// Only consider dm- devices as potential multipath partitions
if !isMultipathDevice(holder) {
logger.Logger.Debug().Str("path", holder.Name()).Msg("Is not a multipath device")
if !isMultipathDevice(paths, holder, logger) {
logger.Logger.Debug().Str("path", holder.Name()).Msg("Is not a multipath device")
continue
}