Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 00/11] virt-resize: add support for resizing MBR logical partitions
In current virt-resize, only primary partitions(including extended partition) are supported. They are collected in an array for resize operations. Logical partitions are not supported. This series add support for resizing logical partitions. v2: 1) Add 3 variables to describe relationship of logical and extended partitions: - partitions flat list of primary partitions (as now, the global 'partitions'). extended partitions is essentially primary partition - logical_partitions flat list of logical partitions - extended_partition one MBR extended partition 2) reserve enough size when resizing logical partitions Original patches by Hu Tao at: https://www.redhat.com/archives/libguestfs/2014-October/msg00238.html Chen Hanxiao (11): resize: move loop check from find_partitions resize: add logical_partitions and extended_partition resize: updated find_partition to support logical partition resize: add support for logical partitions for calculate_surplus resize: handle resize of logical partitions resize: add support for logical partitions of calculate_target_partitions resize: calculate_target_partitions for logical partitions resize: parted and copy logical partitions resize: more misc ops on logical partition resize: add support resize extended partition resize: test: add support for resizing extended and logical partitions resize/resize.ml | 189 ++++++++++++++++++++++++++++++++++----------- resize/test-virt-resize.pl | 32 ++------ 2 files changed, 149 insertions(+), 72 deletions(-) -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 01/11] resize: move loop check from find_partitions
As logical partitions laid inside extended partition, overlap check will not work. make loop as a individual function, which could do a seperate check on logical/extended partitions. Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 602a583..4c97405 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -521,20 +521,20 @@ read the man page virt-resize(1). | _ -> () ) partitions; - (* Check partitions don't overlap. *) - let rec loop end_of_prev = function - | [] -> () - | { p_name = name; p_part = { G.part_start = part_start } } :: _ - when end_of_prev > part_start -> - error (f_"%s: this partition overlaps the previous one") name - | { p_part = { G.part_end = part_end } } :: parts -> loop part_end parts - in - loop 0L partitions; - partitions in let partitions = find_partitions () in + (* Check partitions don't overlap. *) + let rec loop end_of_prev = function + | [] -> () + | { p_name = name; p_part = { G.part_start = part_start } } :: _ + when end_of_prev > part_start -> + error (f_"%s: this partition overlaps the previous one") name + | { p_part = { G.part_end = part_end } } :: parts -> loop part_end parts + in + loop 0L partitions; + if verbose () then ( printf "%d partitions found\n" (List.length partitions); List.iter (debug_partition ~sectsize) partitions -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 02/11] resize: add logical_partitions and extended_partition
For MBR, logical partitions laid inside extended partition. Add 3 variables to describe this: - partitions flat list of primary partitions (as now, the global 'partitions'). extended partitions is essentially primary partition - logical_partitions flat list of logical partitions - extended_partition one MBR extended partition Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 4c97405..d7a8ce1 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -26,19 +26,16 @@ module G = Guestfs (* Minimum surplus before we create an extra partition. *) let min_extra_partition = 10L *^ 1024L *^ 1024L +(* mbr extended partition *) +let extended_partition_list = [] + (* Command line argument parsing. *) type align_first_t = [ `Never | `Always | `Auto ] (* Source partition type. *) type parttype = MBR | GPT -(* Data structure describing the source disk's partition layout. - * - * NOTE: For MBR, only primary/extended partitions are tracked here. - * Logical partitions are contained within an extended partition, and - * we don't track them (they are just copied within the extended - * partition). For the same reason we cannot resize logical partitions. - *) +(* Data structure describing the source disk's partition layout. *) type partition = { p_name : string; (* Device name, like /dev/sda1. *) p_part : G.partition; (* SOURCE partition data from libguestfs. *) @@ -496,12 +493,6 @@ read the man page virt-resize(1). p_target_start = 0L; p_target_end = 0L } ) parts in - (* Filter out logical partitions. See note above. *) - let partitions - (* for GPT, all partitions are regarded as Primary Partition, - * e.g. there is no Extended Partition or Logical Partition. *) - List.filter (fun p -> parttype <> MBR || p.p_mbr_p_type <> LogicalPartition) partitions in - (* Check content isn't larger than partitions. If it is then * something has gone wrong and we shouldn't continue. Old * virt-resize didn't do these checks. @@ -533,11 +524,29 @@ read the man page virt-resize(1). error (f_"%s: this partition overlaps the previous one") name | { p_part = { G.part_end = part_end } } :: parts -> loop part_end parts in + + let extended_partition_list = List.append + extended_partition_list + (List.filter (fun p -> parttype = MBR && p.p_mbr_p_type = ExtendedPartition) partitions) in + let extended_partition = if (List.length extended_partition_list) > 0 then + List.hd extended_partition_list else List.hd partitions in + let logical_partitions + List.filter (fun p -> parttype = MBR && p.p_mbr_p_type = LogicalPartition) partitions in + (* Filter out logical partitions. See note above. *) + let partitions + (* for GPT, all partitions are regarded as Primary Partition, + * e.g. there is no Extended Partition or Logical Partition. *) + List.filter (fun p -> parttype <> MBR || p.p_mbr_p_type <> LogicalPartition) partitions in + loop 0L partitions; + loop 0L logical_partitions; if verbose () then ( printf "%d partitions found\n" (List.length partitions); - List.iter (debug_partition ~sectsize) partitions + List.iter (debug_partition ~sectsize) partitions; + List.iter (debug_partition ~sectsize) logical_partitions; + if (List.length extended_partition_list) > 0 then + printf "%s is extended partition\n" extended_partition.p_name ); (* Build a data structure describing LVs on the source disk. *) -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 03/11] resize: updated find_partition to support logical partition
As we splited the original partitions list to partitions and logical_partitions. Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resize/resize.ml b/resize/resize.ml index d7a8ce1..92f7304 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -616,6 +616,8 @@ read the man page virt-resize(1). let hash = Hashtbl.create 13 in List.iter (fun ({ p_name = name } as p) -> Hashtbl.add hash name p) partitions; + List.iter (fun ({ p_name = name } as p) -> Hashtbl.add hash name p) + logical_partitions; fun ~option name -> let name if String.length name < 5 || String.sub name 0 5 <> "/dev/" then -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 04/11] resize: add support for logical partitions for calculate_surplus
Add support for logical partitions. - count number of logical_partition (we've split partitions list) - don't count size of extended partition For it'll duplicate with logical partition, we'll count it later - we need at leat 1 gap between logical partitions. so --aligment=1 will be increased by 1 Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 92f7304..a0ed713 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -741,8 +741,10 @@ read the man page virt-resize(1). (* We need some overhead for partitioning. *) let overhead let maxl64 = List.fold_left max 0L in + (* We need at least 1 sector gap between logical partitions *) + let alignment = if alignment = 1L then 2L else alignment in - let nr_partitions = List.length partitions in + let nr_partitions = List.length partitions + List.length logical_partitions in let gpt_start_sects = 64L in let gpt_end_sects = gpt_start_sects in @@ -770,12 +772,23 @@ read the man page virt-resize(1). let required = List.fold_left ( fun total p -> let newsize + (* size of extended partition is calculated seperately *) + if p.p_type = ContentExtendedPartition then 0L else + match p.p_operation with + | OpCopy | OpIgnore -> p.p_part.G.part_size + | OpDelete -> 0L + | OpResize newsize -> newsize in + total +^ newsize + ) 0L partitions in + let required = required +^ List.fold_left ( + fun total p -> + let newsize match p.p_operation with | OpCopy | OpIgnore -> p.p_part.G.part_size | OpDelete -> 0L | OpResize newsize -> newsize in total +^ newsize - ) 0L partitions in + ) 0L logical_partitions in let surplus = outsize -^ (required +^ overhead) in -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 05/11] resize: handle resize of logical partitions
This will re-calculate the size of logical partitions. and take logical partitions' aligment into account. Then update extended partition's OpResize. Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/resize/resize.ml b/resize/resize.ml index a0ed713..c54ed2e 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -834,6 +834,30 @@ read the man page virt-resize(1). ) ); + (* handle resizing of logical partitions *) + List.iter ( + fun p -> + if p.p_type = ContentExtendedPartition then ( + let alignment = if alignment = 1L then 2L else alignment in + let size = roundup64 p.p_part.G.part_size sectsize in + let logical_sizes = List.fold_left ( + fun total p -> + match p.p_operation with + | OpDelete -> total +^ 0L + (* the start of logical partitions is aligned *) + | OpCopy | OpIgnore -> total +^ (roundup64 p.p_part.G.part_size (alignment *^ sectsize)) + | OpResize newsize -> total +^ roundup64 newsize (alignment *^ sectsize) + ) 0L logical_partitions in + + (* the first logical partition is aligned *) + let logical_sizes = logical_sizes +^ alignment *^ sectsize in + if logical_sizes > size then + p.p_operation <- OpResize logical_sizes + (* don't touch the extended partition if logical sizes less + * than the original size *) + ) + ) partitions; + (* Calculate the final surplus. * At this point, this number must be >= 0. *) @@ -892,6 +916,7 @@ read the man page virt-resize(1). wrap (text ^ "\n\n") in List.iter print_summary partitions; + List.iter print_summary logical_partitions; List.iter ( fun ({ lv_name = name } as lv) -> -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 06/11] resize: add support for logical partitions of calculate_target_partitions
This patch add support for logical partitions. 1) OpResize newsize: two additional parameter for resizing logical partitions: - gap_start For logical partitions, we had to reserce at least 1 gap between each other. Also, we may had an extra aligment between 1st logical partition and extended partition. We need to remove gap_start from 'OpResize newsize' - nr_logical number of logical partitions. We had to remove all size of gap between each logical partitions. each gap is in (1, alignment). So size = (nr_logical - 1) * alignment removed from size will be enough. 2) OpIgnore | OpCopy: If in logical partition, add an extra aligment of 1 sector. Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index c54ed2e..6a3d286 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -1083,13 +1083,17 @@ read the man page virt-resize(1). * the final list just contains partitions that need to be created * on the target. *) - let rec calculate_target_partitions partnum start ~create_surplus = function + let rec calculate_target_partitions partnum start ~create_surplus ?(nr_logical=0) ?(gap_start=0L) = function | p :: ps -> (match p.p_operation with | OpDelete -> calculate_target_partitions partnum start ~create_surplus ps (* skip p *) | OpIgnore | OpCopy -> (* same size *) + (* add an extra gap for logical partitions *) + let alg = if p.p_mbr_p_type = LogicalPartition then 1L else 0L in + let start = roundup64 (start +^ alg) 2L in + (* Size in sectors. *) let size = div_roundup64 p.p_part.G.part_size sectsize in (* Start of next partition + alignment. *) @@ -1102,13 +1106,24 @@ read the man page virt-resize(1). { p with p_target_start = start; p_target_end = end_ -^ 1L; p_target_partnum = partnum } :: - calculate_target_partitions (partnum+1) next ~create_surplus ps + calculate_target_partitions (partnum+1) next ~create_surplus ~nr_logical ~gap_start ps | OpResize newsize -> (* resized partition *) + (* add an extra gap for logical partitions *) + let alg = if p.p_mbr_p_type = LogicalPartition then 1L else 0L in + + let start = roundup64 start 2L in (* New size in sectors. *) let size = div_roundup64 newsize sectsize in + (* remove gap_start from size *) + let size = size -^ gap_start in + (* remove max aligment between logical partitions *) + let size = size -^ ((Int64.of_int nr_logical) -^ 1L) *^ alignment in (* Start of next partition + alignment. *) let next = start +^ size in + (* We will reserve a 1-sector gap between logical partitions + * by decreasing current partition by 1 sector, see below. *) + let next = next -^ alg in let next = roundup64 next alignment in if verbose () then -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 07/11] resize: calculate_target_partitions for logical partitions
Pass gap_start and nr_logical to calculate_target_partitions when calculating logical partitions. Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/resize/resize.ml b/resize/resize.ml index 6a3d286..89bcb30 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -1175,9 +1175,24 @@ read the man page virt-resize(1). calculate_target_partitions 1 start ~create_surplus:true partitions in + let logical_partitions + let start = List.fold_left ( + fun total p -> + match p.p_type with + | ContentExtendedPartition -> total +^ p.p_target_start + | _ -> total +^ 0L + ) 0L partitions in + + let gap_start = (roundup64 (start +^ 1L) alignment) -^ start in + let nr_logical = List.length logical_partitions in + (* align logical partitions, too *) + let start = roundup64 (start +^ 1L) alignment in + calculate_target_partitions 5 start ~create_surplus:false ~nr_logical ~gap_start logical_partitions in + if verbose () then ( printf "After calculate target partitions:\n"; - List.iter (debug_partition ~sectsize) partitions + List.iter (debug_partition ~sectsize) partitions; + List.iter (debug_partition ~sectsize) logical_partitions ); let mbr_part_type x -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 08/11] resize: parted and copy logical partitions
Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 89bcb30..db7e0b3 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -1210,6 +1210,11 @@ read the man page virt-resize(1). g#part_add "/dev/sdb" (mbr_part_type p) p.p_target_start p.p_target_end ) partitions; + List.iter ( + fun p -> + g#part_add "/dev/sdb" "logical" p.p_target_start p.p_target_end + ) logical_partitions; + (* Copy over the data. *) let copy_partition p match p.p_operation with @@ -1234,24 +1239,12 @@ read the man page virt-resize(1). | ContentUnknown | ContentPV _ | ContentFS _ -> g#copy_device_to_device ~size:copysize ~sparse source target - | ContentExtendedPartition -> - (* You can't just copy an extended partition by name, eg. - * source = "/dev/sda2", because the device name only covers - * the first 1K of the partition. Instead, copy the - * source bytes from the parent disk (/dev/sda). - * - * You can't write directly to the extended partition, - * because the size of it reported by Linux is always 1024 - * bytes. Instead, write to the offset of the extended - * partition in the destination disk (/dev/sdb). - *) - let srcoffset = p.p_part.G.part_start in - let destoffset = p.p_target_start *^ 512L in - g#copy_device_to_device ~srcoffset ~destoffset ~size:copysize "/dev/sda" "/dev/sdb" + | ContentExtendedPartition -> () ) | OpIgnore | OpDelete -> () in List.iter copy_partition partitions; + List.iter copy_partition logical_partitions; (* Set bootable and MBR IDs. Do this *after* copying over the data, * so that we can magically change the primary partition to an extended -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 09/11] resize: more misc ops on logical partition
Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resize/resize.ml b/resize/resize.ml index db7e0b3..37b946e 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -1274,6 +1274,7 @@ read the man page virt-resize(1). | GPT, (No_ID|MBR_ID _) | MBR, (No_ID|GPT_Type _) -> () in List.iter set_partition_bootable_and_id partitions; + List.iter set_partition_bootable_and_id logical_partitions; (* Fix the bootloader if we aligned the first partition. *) if align_first_partition_and_fix_bootloader then ( @@ -1325,6 +1326,13 @@ read the man page virt-resize(1). can_expand_content p.p_type | { p_operation = (OpCopy | OpIgnore | OpDelete) } -> false ) partitions + || + List.exists ( + function + | ({ p_operation = OpResize _ } as p) -> + can_expand_content p.p_type + | { p_operation = (OpCopy | OpIgnore | OpDelete) } -> false + ) logical_partitions || List.exists ( function | ({ lv_operation = LVOpExpand } as lv) -> @@ -1386,6 +1394,7 @@ read the man page virt-resize(1). -> () in List.iter expand_partition_content partitions; + List.iter expand_partition_content logical_partitions; (* Expand logical volume content as required. *) List.iter ( -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 10/11] resize: add support resize extended partition
Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/resize.ml | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/resize/resize.ml b/resize/resize.ml index 37b946e..8cdc5b1 100644 --- a/resize/resize.ml +++ b/resize/resize.ml @@ -769,6 +769,29 @@ read the man page virt-resize(1). start_overhead_sects +^ alignment_sects +^ gpt_end_sects in sectsize *^ overhead_sects in + let required_logical = List.fold_left ( + fun total p -> + let newsize + match p.p_operation with + | OpCopy | OpIgnore -> roundup64 p.p_part.G.part_size (alignment *^ sectsize) + | OpDelete -> 0L + | OpResize newsize -> roundup64 newsize (alignment *^ sectsize) in + total +^ newsize + ) 0L logical_partitions in + + let required_extended = List.fold_left ( + fun total p -> + let newsize + match p.p_type with + | ContentExtendedPartition -> + (* resizing extended partition by --resize or --expand is supported *) + (match p.p_operation with + | OpResize newsize -> newsize + | _ -> p.p_part.G.part_size) + | _ -> 0L in + total +^ newsize + ) 0L partitions in + let required = List.fold_left ( fun total p -> let newsize @@ -780,15 +803,8 @@ read the man page virt-resize(1). | OpResize newsize -> newsize in total +^ newsize ) 0L partitions in - let required = required +^ List.fold_left ( - fun total p -> - let newsize - match p.p_operation with - | OpCopy | OpIgnore -> p.p_part.G.part_size - | OpDelete -> 0L - | OpResize newsize -> newsize in - total +^ newsize - ) 0L logical_partitions in + let required = required +^ if required_extended > required_logical + then required_extended else required_logical in let surplus = outsize -^ (required +^ overhead) in @@ -840,6 +856,8 @@ read the man page virt-resize(1). if p.p_type = ContentExtendedPartition then ( let alignment = if alignment = 1L then 2L else alignment in let size = roundup64 p.p_part.G.part_size sectsize in + (* resizing extended partition by --resize or --expand is supported *) + let size = match p.p_operation with OpResize s -> s | _ -> size in let logical_sizes = List.fold_left ( fun total p -> match p.p_operation with -- 2.1.0
Chen Hanxiao
2015-May-20 10:51 UTC
[Libguestfs] [PATCH v2 11/11] resize: test: add support for resizing extended and logical partitions
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> --- resize/test-virt-resize.pl | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/resize/test-virt-resize.pl b/resize/test-virt-resize.pl index be9c9b4..85ed1b2 100755 --- a/resize/test-virt-resize.pl +++ b/resize/test-virt-resize.pl @@ -75,13 +75,6 @@ if (rand () <= 0.5) { # an extended partition (#4) and zero or more logical partitions. my $nr_parts = 1 + int (rand (7)); -# XXX Temporarily restriction XXX -# Currently virt-resize is broken when dealing with any extended -# partition, so don't test this for the moment. -if ($part_type eq "mbr" && $nr_parts >= 4) { - $nr_parts = 3; -} - # expand (1) or shrink (0) my $expand = 0; if (rand () >= 0.2) { @@ -120,31 +113,16 @@ my $i; for ($i = 1; $i <= $nr_parts; ++$i) { $parts[$i] = { name => "sda".$i, resize => 0 }; - if ($part_type eq "mbr") { - if ($i < 4) { - if (rand () < 0.5) { - $parts[$i]->{resize} = 1; - } - } elsif ($i == 4) { + if ($part_type eq "mbr" && $i == 4) { $parts[$i]->{content} = "extended"; - } - } else { - if (rand () < 0.5) { - $parts[$i]->{resize} = 1; - } + } + if (rand () < 0.5) { + $parts[$i]->{resize} = 1; } } # Pick a partition at random to expand or shrink. -if ($part_type eq "mbr") { - # virt-resize cannot shrink extended or logical partitions, so we - # set $max so that these cannot be chosen: - my $max = 3; - $max = $nr_parts if $max > $nr_parts; - $i = 1 + int (rand ($max)); -} else { - $i = 1 + int (rand ($nr_parts)); -} +$i = 1 + int (rand ($nr_parts)); $parts[$i]->{resize} = 0; $parts[$i]->{expand_shrink} = 1; -- 2.1.0
Chen, Hanxiao
2015-May-27 02:45 UTC
Re: [Libguestfs] [PATCH v2 00/11] virt-resize: add support for resizing MBR logical partitions
> -----Original Message----- > From: libguestfs-bounces@redhat.com [mailto:libguestfs-bounces@redhat.com] On > Behalf Of Chen Hanxiao > Sent: Wednesday, May 20, 2015 6:51 PM > To: libguestfs@redhat.com > Subject: [Libguestfs] [PATCH v2 00/11] virt-resize: add support for resizing MBR > logical partitions > > In current virt-resize, only primary partitions(including > extended partition) are supported. They are collected in an > array for resize operations. Logical partitions are not > supported. > > This series add support for resizing logical partitions. > > v2: > 1) Add 3 variables to describe relationship of logical and extended partitions: > - partitions > flat list of primary partitions (as now, the global 'partitions'). > extended partitions is essentially primary partition > - logical_partitions > flat list of logical partitions > - extended_partition > one MBR extended partition > > 2) reserve enough size when resizing logical partitions > > Original patches by Hu Tao at: > https://www.redhat.com/archives/libguestfs/2014-October/msg00238.html > > Chen Hanxiao (11): > resize: move loop check from find_partitions > resize: add logical_partitions and extended_partition > resize: updated find_partition to support logical partition > resize: add support for logical partitions for calculate_surplus > resize: handle resize of logical partitions > resize: add support for logical partitions of > calculate_target_partitions > resize: calculate_target_partitions for logical partitions > resize: parted and copy logical partitions > resize: more misc ops on logical partition > resize: add support resize extended partition > resize: test: add support for resizing extended and logical partitions > > resize/resize.ml | 189 ++++++++++++++++++++++++++++++++++----------- > resize/test-virt-resize.pl | 32 ++------ > 2 files changed, 149 insertions(+), 72 deletions(-) >Hi, Rich Any comments on this series? Regards, - Chen
Richard W.M. Jones
2015-May-28 11:06 UTC
Re: [Libguestfs] [PATCH v2 02/11] resize: add logical_partitions and extended_partition
On Wed, May 20, 2015 at 06:51:28AM -0400, Chen Hanxiao wrote:> For MBR, logical partitions laid inside extended partition. > Add 3 variables to describe this: > - partitions > flat list of primary partitions (as now, the global 'partitions'). > extended partitions is essentially primary partition > > - logical_partitions > flat list of logical partitions > > - extended_partition > one MBR extended partition > > Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> > --- > resize/resize.ml | 37 +++++++++++++++++++++++-------------- > 1 file changed, 23 insertions(+), 14 deletions(-) > > diff --git a/resize/resize.ml b/resize/resize.ml > index 4c97405..d7a8ce1 100644 > --- a/resize/resize.ml > +++ b/resize/resize.ml > @@ -26,19 +26,16 @@ module G = Guestfs > (* Minimum surplus before we create an extra partition. *) > let min_extra_partition = 10L *^ 1024L *^ 1024L > > +(* mbr extended partition *) > +let extended_partition_list = []This assignment doesn't really do anything. 'let' bindings in OCaml don't create global variables. This just makes 'extended_partition_list' be a name for the empty list, ... [...]> + let extended_partition_list = List.append > + extended_partition_list... up to here, where you create a second name, also 'extended_partition_list', completely independent from the one above, which for no reason appends to the empty list. What *doesn't* happen is 'extended_partition_list' that you created at the top is modified.> + let extended_partition = if (List.length extended_partition_list) > 0 then > + List.hd extended_partition_list else List.hd partitions inYou could write this more naturally as: let extended_partition match extended_partition_list with | h :: _ -> h | [] -> List.hd partitions in Rewriting it like this also makes the bug in this code clearer: why is extended_partition initialized to the first partition, if there are no extended partitions? I think you probably meant to write: let extended_partition match extended_partition_list with | h :: _ -> Some h | [] -> None in> + let logical_partitions > + List.filter (fun p -> parttype = MBR && p.p_mbr_p_type = LogicalPartition) partitions in > + (* Filter out logical partitions. See note above. *) > + let partitions > + (* for GPT, all partitions are regarded as Primary Partition, > + * e.g. there is no Extended Partition or Logical Partition. *) > + List.filter (fun p -> parttype <> MBR || p.p_mbr_p_type <> LogicalPartition) partitions inAlthough this is code is correct, it is clearer and shorter to write the test using a separate function, so it would become: let is_logical_partition p parttype = MBR && p.p_mbr_p_type = LogicalPartition in let logical_partitions = List.filter is_logical_partition partitions in let partitions List.filter (fun p -> not (is_logical_partition p)) partitions in Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Richard W.M. Jones
2015-May-28 11:07 UTC
Re: [Libguestfs] [PATCH v2 03/11] resize: updated find_partition to support logical partition
On Wed, May 20, 2015 at 06:51:29AM -0400, Chen Hanxiao wrote:> As we splited the original partitions list to > partitions and logical_partitions. > > Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> > --- > resize/resize.ml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/resize/resize.ml b/resize/resize.ml > index d7a8ce1..92f7304 100644 > --- a/resize/resize.ml > +++ b/resize/resize.ml > @@ -616,6 +616,8 @@ read the man page virt-resize(1). > let hash = Hashtbl.create 13 in > List.iter (fun ({ p_name = name } as p) -> Hashtbl.add hash name p) > partitions; > + List.iter (fun ({ p_name = name } as p) -> Hashtbl.add hash name p) > + logical_partitions; > fun ~option name -> > let name > if String.length name < 5 || String.sub name 0 5 <> "/dev/" thenIf we're going to group these patches together, this should be merged into the previous patch. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Richard W.M. Jones
2015-May-28 11:11 UTC
Re: [Libguestfs] [PATCH v2 04/11] resize: add support for logical partitions for calculate_surplus
On Wed, May 20, 2015 at 06:51:30AM -0400, Chen Hanxiao wrote:> Add support for logical partitions. > - count number of logical_partition (we've split partitions list) > - don't count size of extended partition > For it'll duplicate with logical partition, we'll count it later > - we need at leat 1 gap between logical partitions. > so --aligment=1 will be increased by 1 > > Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com> > --- > resize/resize.ml | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > > diff --git a/resize/resize.ml b/resize/resize.ml > index 92f7304..a0ed713 100644 > --- a/resize/resize.ml > +++ b/resize/resize.ml > @@ -741,8 +741,10 @@ read the man page virt-resize(1). > (* We need some overhead for partitioning. *) > let overhead > let maxl64 = List.fold_left max 0L in > + (* We need at least 1 sector gap between logical partitions *) > + let alignment = if alignment = 1L then 2L else alignment in > > - let nr_partitions = List.length partitions in > + let nr_partitions = List.length partitions + List.length logical_partitions inI don't understand this at all. Why do logical partitions count towards the surplus? I don't think they do. Rich.> let gpt_start_sects = 64L in > let gpt_end_sects = gpt_start_sects in > @@ -770,12 +772,23 @@ read the man page virt-resize(1). > let required = List.fold_left ( > fun total p -> > let newsize > + (* size of extended partition is calculated seperately *) > + if p.p_type = ContentExtendedPartition then 0L else > + match p.p_operation with > + | OpCopy | OpIgnore -> p.p_part.G.part_size > + | OpDelete -> 0L > + | OpResize newsize -> newsize in > + total +^ newsize > + ) 0L partitions in > + let required = required +^ List.fold_left ( > + fun total p -> > + let newsize > match p.p_operation with > | OpCopy | OpIgnore -> p.p_part.G.part_size > | OpDelete -> 0L > | OpResize newsize -> newsize in > total +^ newsize > - ) 0L partitions in > + ) 0L logical_partitions in > > let surplus = outsize -^ (required +^ overhead) in > > -- > 2.1.0 > > _______________________________________________ > Libguestfs mailing list > Libguestfs@redhat.com > https://www.redhat.com/mailman/listinfo/libguestfs-- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Reasonably Related Threads
- Re: [PATCH v2 04/11] resize: add support for logical partitions for calculate_surplus
- [PATCH v3 7/7] resize: add support to resize logical partitions
- [PATCH V5 2/4] resize: add support to resize logical partitions
- [PATCH V5 3/4] resize: support resize extended partition
- [RFC PATCH v4 7/7] resize: support resize extended partition