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
- [PATCH v3 00/11] virt-resize: add support for resizing MBR logical partitions
- [PATCH v4 00/11] virt-resize: add support for resizing MBR logical partitions
- [PATCH rebase v4 00/11] virt-resize: add support for resizing MBR logical partitions
- Re: virt-resize: support to MBR logical partitions and some question
- [PATCH V5 0/4] virt-resize: add support for resizing logical