Skip to content
Merged
71 changes: 63 additions & 8 deletions toolkit/tools/imagegen/diskutils/diskutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -902,20 +902,75 @@ func SystemBlockDevices() (systemDevices []SystemBlockDevice, err error) {
return
}

systemDevices = make([]SystemBlockDevice, len(blockDevices.Devices))
// Process each device to build the filtered list
systemDevices = make([]SystemBlockDevice, 0, len(blockDevices.Devices))
for _, device := range blockDevices.Devices {
devicePath := fmt.Sprintf("/dev/%s", device.Name)
rawSize, err := strconv.ParseUint(device.Size.String(), 10, 64)
if err != nil {
return nil, fmt.Errorf("failed to parse size for %s: %v", devicePath, err)
}

for i, disk := range blockDevices.Devices {
systemDevices[i].DevicePath = fmt.Sprintf("/dev/%s", disk.Name)
isRemovable := isRemovableDevice(devicePath)
isReadOnly := isReadOnlyISO(devicePath)
isRemovableInstaller := isRemovable && isReadOnly

systemDevices[i].RawDiskSize, err = strconv.ParseUint(disk.Size.String(), 10, 64)
if err != nil {
return
logger.Log.Debugf("Device: %s, Size: %d, Model: %s, IsRemovableInstaller: %v (IsRemovable: %v, IsReadOnly: %v)",
devicePath, rawSize, strings.TrimSpace(device.Model), isRemovableInstaller, isRemovable, isReadOnly)

if !isRemovableInstaller {
systemDevices = append(systemDevices, SystemBlockDevice{
DevicePath: devicePath,
RawDiskSize: rawSize,
Model: strings.TrimSpace(device.Model),
})
} else {
logger.Log.Debugf("Excluded removable installer device: %s", devicePath)
}
}

logger.Log.Debugf("Final device list: %v", systemDevices)
return systemDevices, nil
}

systemDevices[i].Model = strings.TrimSpace(disk.Model)
// isRemovableDevice determines if a device is removable (e.g., USB or similar media).
func isRemovableDevice(devicePath string) bool {
deviceName := devicePath[5:] // Extract 'sda', 'sdb', 'nvme0n1', etc. from '/dev/'
removableFile := fmt.Sprintf("/sys/block/%s/removable", deviceName)
if exists, err := file.PathExists(removableFile); err == nil && exists {
if content, err := os.ReadFile(removableFile); err == nil {
if strings.TrimSpace(string(content)) == "1" {
logger.Log.Debugf("isRemovableDevice(%s) returning true", devicePath)
return true
}
}
}
logger.Log.Debugf("isRemovableDevice(%s) returning false", devicePath)
return false
}

return
// isReadOnlyISO checks if a device is mounted read-only (ISO on USB/CD).
func isReadOnlyISO(devicePath string) bool {
mounts, err := os.ReadFile("/proc/mounts")
if err != nil {
logger.Log.Debugf("Failed to read /proc/mounts: %v", err)
logger.Log.Debugf("isReadOnlyISO(%s) returning false", devicePath)
return false
}
for _, line := range strings.Split(string(mounts), "\n") {
fields := strings.Fields(line)
if len(fields) >= 4 && fields[0] == devicePath {
options := strings.Split(fields[3], ",")
for _, opt := range options {
if opt == "ro" {
logger.Log.Debugf("isReadOnlyISO(%s) returning true", devicePath)
return true
}
}
}
}
logger.Log.Debugf("isReadOnlyISO(%s) returning false", devicePath)
return false
}

func GetDiskPartitions(diskDevPath string) ([]PartitionInfo, error) {
Expand Down
Loading