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.drobys...@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 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs