Skip to content

Commit

Permalink
Fix partition initialization bug.
Browse files Browse the repository at this point in the history
After creating a partition, the toolkit must wait for the partition
device to be created (under /dev). However, the naming scheme of
partitions is inconsistent, with both `/dev/<name>XX` and
`/dev/<name>pXX` being used, depending on the device driver. So, the
toolkit checks for both.

However, a problem occurs when the device name itself ends in a digit.
If the disk device path is say `/dev/loop1`, then `/dev/loop11` is also
a valid disk device path. For such disks, the `/dev/<name>pXX` form
must be used for partitions.

While the toolkit prioritizes `/dev/loop1p1` over `/dev/loop11`, if the
`/dev/loop1p1` device doesn't exist yet and `/dev/loop11` is in use,
then the toolkit may pick the wrong device path for the partition.

This change fixes this by ignoring the `/dev/<name>XX` variant if the
disk device path ends in a digit.
  • Loading branch information
cwize1 committed Oct 11, 2024
1 parent 7fe21f9 commit 89e9dc6
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions toolkit/tools/imagegen/diskutils/diskutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,13 +682,19 @@ func InitializeSinglePartition(diskDevPath string, partitionNumber int,
partitionNumberStr := strconv.Itoa(partitionNumber)

// There are two primary partition naming conventions:
// /dev/sdN<y> style or /dev/loopNp<x> style
// - /dev/sdN<y>
// - /dev/loopNp<x>
// Detect the exact one we are using.
// Make sure we check for /dev/loopNp<x> FIRST, since /dev/loop1 would generate /dev/loop11 as a partition
// device which may be a valid device. We want to select /dev/loop1p1 first.
testPartDevPaths := []string{
fmt.Sprintf("%sp%s", diskDevPath, partitionNumberStr),
fmt.Sprintf("%s%s", diskDevPath, partitionNumberStr),
}

// If disk path ends in a digit, then the 'p<x>' style must be used.
// So, don't check the other style to avoid ambiguities. For example, /dev/loop1 vs. /dev/loop11.
// The is particularly relevant on Ubuntu, due to snap's use of loopback devices.
if !isDigit(diskDevPath[len(diskDevPath)-1]) {
devPath := fmt.Sprintf("%s%s", diskDevPath, partitionNumberStr)
testPartDevPaths = append(testPartDevPaths, devPath)
}

err = retry.Run(func() error {
Expand Down Expand Up @@ -759,6 +765,10 @@ func InitializeSinglePartition(diskDevPath string, partitionNumber int,
return
}

func isDigit(c byte) bool {
return c >= '0' && c <= '9'
}

func setGptPartitionType(partition configuration.Partition, timeoutInSeconds, diskDevPath, partitionNumberStr string) (err error) {
if supports, _ := PartedSupportsTypeCommand(); !supports {
logger.Log.Warn("parted version <3.6 does not support the 'type' session command - skipping this operation")
Expand Down

0 comments on commit 89e9dc6

Please sign in to comment.