If the guest uses BIOS firmware but GPT partitioned disk, and in
addition has "bios, esp" flag enabled on its "/boot" partition, then
inspection wrongly detects UEFI firmware and v2v ends up with the error:
"error: no bootloader detected".
Let's fix this by checking for the presence of BIOS boot partition (0xef02
type for gdisk, "bios_grub" flag for parted), which is used to store a
bootloader code in BIOS+GPT configurations. If such a partition is
present, then it's likely a BIOS+GPT setup.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev(a)virtuozzo.com>
---
convert/inspect_source.ml | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/convert/inspect_source.ml b/convert/inspect_source.ml
index 056d0bca..6650e136 100644
--- a/convert/inspect_source.ml
+++ b/convert/inspect_source.ml
@@ -219,6 +219,9 @@ and list_applications g root = function
(* See if this guest could use UEFI to boot. It should use GPT and
* it should have an EFI System Partition (ESP).
*
+ * If it has a BIOS boot partition (BIOS+GPT setup), then [BIOS] is
+ * returned.
+ *
* If it has ESP(s), then [UEFI devs] is returned where [devs] is the
* list of at least one ESP.
*
@@ -226,9 +229,13 @@ and list_applications g root = function
*)
and get_firmware_bootable_device g =
let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
+ and bios_boot_guid = "21686148-6449-6E6F-744E-656564454649"
and is_uefi_ESP dev part =
let partnum = g#part_to_partnum part in
g#part_get_gpt_type dev partnum = uefi_ESP_guid
+ and is_bios_boot dev part =
+ let partnum = g#part_to_partnum part in
+ g#part_get_gpt_type dev partnum = bios_boot_guid
and parttype_is_gpt dev =
try g#part_get_parttype dev = "gpt"
with G.Error msg as exn ->
@@ -239,14 +246,26 @@ and get_firmware_bootable_device g =
and is_uefi_bootable_part part =
let dev = g#part_to_dev part in
parttype_is_gpt dev && is_uefi_ESP dev part
+ and is_bios_gpt_part part =
+ let dev = g#part_to_dev part in
+ parttype_is_gpt dev && is_bios_boot dev part
in
let partitions = Array.to_list (g#list_partitions ()) in
- let partitions = List.filter is_uefi_bootable_part partitions in
+ let esp_partitions = List.filter is_uefi_bootable_part partitions in
- match partitions with
- | [] -> I_BIOS
- | partitions -> I_UEFI partitions
+ (* If there's a BIOS boot partition present (0xef02 type for gdisk,
+ * "bios_grub" flag for parted), then this is likely a BIOS+GPT setup.
+ * Note that if a source VM is using UEFI firmware and has a secondary
+ * non-bootable disk attached which contains such a partition, the
+ * firmware detection will detect I_BIOS wrongly. But this can only be
+ * done manually, and we assume that there's no point doing it on purpose.
+ *)
+ if List.exists is_bios_gpt_part partitions then I_BIOS
+ else
+ match esp_partitions with
+ | [] -> I_BIOS
+ | esp_partitions -> I_UEFI esp_partitions
(* If some inspection fields are "unknown", then that indicates a
* failure in inspection, and we shouldn't continue. For an example
--
2.31.1