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:
committed by
Luca Boccassi
parent
9bb06d5cd6
commit
a9ff124143
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user