repart: Keep new partitions after existing same-type partitions

When a partition is deleted from a table containing multiple partitions
of the same type, filling the resulting partition-number gap can place
a new partition before an existing partition matched to an earlier
definition. This changes definition matching on the next invocation and
breaks idempotency.

Keep new partitions after existing partitions of the same type. If no
partition table slot is available after them, fall back to the first
unused slot.

Which existing partition is matched to which definition is still
determined by partition type and partition number order, as documented,
and is unchanged by this.

Fixes #43449
This commit is contained in:
quanyeyang
2026-08-26 19:43:03 +01:00
committed by Luca Boccassi
parent 9bb06d5cd6
commit a9ff124143
3 changed files with 112 additions and 9 deletions
+75
View File
@@ -3161,6 +3161,81 @@ EOF
assert_in "$imgs/leftover2.img3 : start= 26624, size= 24536, type=$esp_guid," "$output"
}
testcase_partition_number_gap() {
local defs imgs image output before after
defs="$(mktemp --directory "/tmp/test-repart.defs.XXXXXXXXXX")"
imgs="$(mktemp --directory "/var/tmp/test-repart.imgs.XXXXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf '$defs' '$imgs'" RETURN
chmod 0755 "$defs"
image="$imgs/gap.img"
tee "$defs/10-a.conf" <<EOF
[Partition]
Type=linux-generic
Label=a
SizeMinBytes=20M
SizeMaxBytes=20M
EOF
tee "$defs/20-b.conf" <<EOF
[Partition]
Type=linux-generic
Label=b
SizeMinBytes=10M
SizeMaxBytes=10M
EOF
# Initially create two partitions with consecutive partition numbers.
systemd-repart --offline="$OFFLINE" \
--definitions="$defs" \
--seed="$seed" \
--empty=create \
--size=64M \
--dry-run=no \
"$image"
output="$(sfdisk -d "$image")"
assert_in "${image}1 :" "$output"
assert_in "${image}2 :" "$output"
# Remove the first partition, leaving partition number 1 unused while
# partition number 2 remains occupied.
sfdisk --delete "$image" 1
output="$(sfdisk -d "$image")"
assert_not_in "${image}1 :" "$output"
assert_in "${image}2 :" "$output"
# Repart should append the new partition after the highest existing
# partition of the same type instead of filling the lower-numbered gap.
systemd-repart --offline="$OFFLINE" \
--definitions="$defs" \
--seed="$seed" \
--dry-run=no \
"$image"
output="$(sfdisk -d "$image")"
assert_not_in "${image}1 :" "$output"
assert_in "${image}2 : start= 43008, size= 40960, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4," "$output"
assert_in "${image}3 : start= 2048, size= 20480, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4," "$output"
# A subsequent invocation should not rematch the definitions and modify
# the partition table again.
before="$output"
systemd-repart --offline="$OFFLINE" \
--definitions="$defs" \
--seed="$seed" \
--dry-run=no \
"$image"
after="$(sfdisk -d "$image")"
assert_eq "$after" "$before"
}
OFFLINE="yes"
run_testcases