diff --git a/src/repart/repart.c b/src/repart/repart.c index 838786e153..271056a06a 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -3287,10 +3287,12 @@ static int determine_current_padding( struct fdisk_partition *p, uint64_t secsz, uint64_t grainsz, - uint64_t *ret) { + uint64_t *ret, + bool *ret_is_last_partition) { size_t n_partitions; uint64_t offset, next = UINT64_MAX; + bool is_last_partition = false; assert(c); assert(t); @@ -3330,6 +3332,8 @@ static int determine_current_padding( } if (next == UINT64_MAX) { + is_last_partition = true; + /* No later partition? In that case check the end of the usable area */ next = sym_fdisk_get_last_lba(c); assert(next < UINT64_MAX); @@ -3346,6 +3350,9 @@ static int determine_current_padding( offset = round_up_size(offset, grainsz); next = round_down_size(next, grainsz); + if (ret_is_last_partition) + *ret_is_last_partition = is_last_partition; + *ret = LESS_BY(next, offset); /* Saturated subtraction, rounding might have fucked things up */ return 0; } @@ -3395,6 +3402,7 @@ static int context_copy_from_one(Context *context, const char *src) { uint64_t sz, start, padding; sd_id128_t ptid, id; GptPartitionType type; + bool is_last_partition; p = sym_fdisk_table_get_partition(t, i); if (!p) @@ -3456,11 +3464,12 @@ static int context_copy_from_one(Context *context, const char *src) { /* Pass grain size of 1 to disable rounding by grain as we don't know the grain size * of the old image. We'll round paddings to the grain size of the new image later. */ - r = determine_current_padding(c, t, p, secsz, /* grainsz= */ 1, &padding); + r = determine_current_padding(c, t, p, secsz, /* grainsz= */ 1, &padding, &is_last_partition); if (r < 0) return r; - np->padding_min = np->padding_max = padding; + if (!is_last_partition) + np->padding_min = np->padding_max = padding; np->copy_blocks_path = strdup(src); if (!np->copy_blocks_path) @@ -4056,7 +4065,14 @@ static int context_load_partition_table(Context *context) { pp->current_partition = p; sym_fdisk_ref_partition(p); - r = determine_current_padding(c, t, p, secsz, grainsz, &pp->current_padding); + r = determine_current_padding( + c, + t, + p, + secsz, + grainsz, + &pp->current_padding, + /* ret_is_last_partition= */ NULL); if (r < 0) return r; @@ -4089,7 +4105,14 @@ static int context_load_partition_table(Context *context) { np->current_partition = p; sym_fdisk_ref_partition(p); - r = determine_current_padding(c, t, p, secsz, grainsz, &np->current_padding); + r = determine_current_padding( + c, + t, + p, + secsz, + grainsz, + &np->current_padding, + /* ret_is_last_partition= */ NULL); if (r < 0) return r; diff --git a/test/units/TEST-58-REPART.sh b/test/units/TEST-58-REPART.sh index 7bd18312df..863023454e 100755 --- a/test/units/TEST-58-REPART.sh +++ b/test/units/TEST-58-REPART.sh @@ -527,6 +527,47 @@ EOF assert_in "$imgs/copy_to2 : start= 32768, size= 16384, type=${xbootldr_guid}," "$output" } +testcase_copy_from_no_padding_at_beginning_and_end() { + local defs imgs output + + 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" + + tee "$defs/03-esp.conf" <