psss / rpms / libguestfs

Forked from rpms/libguestfs 5 years ago
Clone
Blob Blame History Raw
From daf51b61dc081bfea6c73d0fa2c753a390443f43 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 27 Nov 2015 10:25:17 +0000
Subject: [PATCH 4/5] resize: Work around regression in sfdisk (RHBZ#1285847).

'sfdisk --part-type' used to merely set the MBR ID byte in the
partition.  However since sfdisk was rewritten, it now "helpfully"
corrupts the first sector of the partition if you change the type byte
from an ordinary partition to an extended partition.

So we need to change the order in which we sets the partition type
byte, to do it before copying the partition content.

This fixes a major regression in the way that virt-resize handles any
guest with logical partitions (specifically Ubuntu guests).

(cherry picked from commit abe63eeaf2b1056a7c5d941f4aaecb5a050c3fee)
---
 resize/resize.ml | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/resize/resize.ml b/resize/resize.ml
index 5c881a9..2196316 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -1100,6 +1100,28 @@ read the man page virt-resize(1).
       g#part_add "/dev/sdb" "primary" p.p_target_start p.p_target_end
   ) partitions;
 
+  (* Set bootable and MBR IDs.  Do this *before* copying over the data,
+   * because the rewritten sfdisk "helpfully" overwrites the partition
+   * table in the first sector of an extended partition if a partition
+   * is changed from primary to extended.  Thus we need to set the
+   * MBR ID before doing the copy so sfdisk doesn't corrupt things.
+   *)
+  let set_partition_bootable_and_id p =
+      if p.p_bootable then
+        g#part_set_bootable "/dev/sdb" p.p_target_partnum true;
+
+      may (g#part_set_name "/dev/sdb" p.p_target_partnum) p.p_label;
+      may (g#part_set_gpt_guid "/dev/sdb" p.p_target_partnum) p.p_guid;
+
+      match parttype, p.p_id with
+      | GPT, GPT_Type gpt_type ->
+        g#part_set_gpt_type "/dev/sdb" p.p_target_partnum gpt_type
+      | MBR, MBR_ID mbr_id ->
+        g#part_set_mbr_id "/dev/sdb" p.p_target_partnum mbr_id
+      | GPT, (No_ID|MBR_ID _) | MBR, (No_ID|GPT_Type _) -> ()
+  in
+  List.iter set_partition_bootable_and_id partitions;
+
   (* Copy over the data. *)
   let copy_partition p =
       match p.p_operation with
@@ -1143,26 +1165,6 @@ read the man page virt-resize(1).
   in
   List.iter copy_partition 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
-   * partition if necessary.
-   *)
-  let set_partition_bootable_and_id p =
-      if p.p_bootable then
-        g#part_set_bootable "/dev/sdb" p.p_target_partnum true;
-
-      may (g#part_set_name "/dev/sdb" p.p_target_partnum) p.p_label;
-      may (g#part_set_gpt_guid "/dev/sdb" p.p_target_partnum) p.p_guid;
-
-      match parttype, p.p_id with
-      | GPT, GPT_Type gpt_type ->
-        g#part_set_gpt_type "/dev/sdb" p.p_target_partnum gpt_type
-      | MBR, MBR_ID mbr_id ->
-        g#part_set_mbr_id "/dev/sdb" p.p_target_partnum mbr_id
-      | GPT, (No_ID|MBR_ID _) | MBR, (No_ID|GPT_Type _) -> ()
-  in
-  List.iter set_partition_bootable_and_id partitions;
-
   (* Fix the bootloader if we aligned the first partition. *)
   if align_first_partition_and_fix_bootloader then (
     (* See can_fix_boot_loader above. *)
-- 
2.5.0