From b730bc0c4685887232daed8fafa491b28f38c300 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 19 Jun 2013 19:03:21 +0100 Subject: [PATCH] virt-resize: Take into account large start offset of the first partition when calculating overhead (RHBZ#974904). Since we don't usually move the first partition, if the first partition has an unusually large offset from the start of the disk, then the unpartitioned space in front of that partition counts as partitioning overhead. However the previous surplus calculation was not taking that into account. This was a problem for certain Ubuntu images which are partitioned with an 8 MB gap before the first partition. Thanks: David Hart. --- resize/resize.ml | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 8ab36762e..f3359f5ee 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -647,15 +647,34 @@ let () = * a surplus, if it is < 0 then it's a deficit. *) let calculate_surplus () = - (* We need some overhead for partitioning. Worst case would be for - * EFI partitioning + massive per-partition alignment. - *) - let nr_partitions = List.length partitions in - let overhead = (Int64.of_int sectsize) *^ ( - 2L *^ 64L +^ (* GPT start and end *) - (alignment *^ (Int64.of_int (nr_partitions + 1))) (* Maximum alignment *) - ) +^ - (Int64.of_int (max_bootloader - 64 * 512)) in (* Bootloader *) + (* We need some overhead for partitioning. *) + let overhead = + let maxl64 = List.fold_left max 0L in + + let nr_partitions = List.length partitions in + + let gpt_start_sects = 64L in + let gpt_end_sects = gpt_start_sects in + + let first_part_start_sects = + match partitions with + | { p_part = { G.part_start = start }} :: _ -> + start /^ Int64.of_int sectsize + | [] -> 0L in + + let max_bootloader_sects = Int64.of_int max_bootloader /^ 512L in + + (* Size of the unpartitioned space before the first partition. *) + let start_overhead_sects = + maxl64 [gpt_start_sects; max_bootloader_sects; first_part_start_sects] in + + (* Maximum space lost because of alignment of partitions. *) + let alignment_sects = alignment *^ Int64.of_int (nr_partitions + 1) in + + (* Add up the total max. overhead. *) + let overhead_sects = + start_overhead_sects +^ alignment_sects +^ gpt_end_sects in + Int64.of_int sectsize *^ overhead_sects in let required = List.fold_left ( fun total p ->