v2v: fill the list of the EFI system partitions

Store the list of EFI system partitions on the inspect object in order  to be
able to tune their contents later in the process.

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
This commit is contained in:
Pavel Butsykin
2016-06-11 13:29:41 +03:00
committed by Richard W.M. Jones
parent 3719d75098
commit 82df768514
6 changed files with 52 additions and 23 deletions

View File

@@ -97,10 +97,9 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps =
"/boot/grub/grub.conf", `Grub1;
] in
let locations =
if inspect.i_uefi then
("/boot/efi/EFI/redhat/grub.cfg", `Grub2) :: locations
else
locations in
match inspect.i_firmware with
| I_UEFI _ -> ("/boot/efi/EFI/redhat/grub.cfg", `Grub2) :: locations
| I_BIOS -> locations in
try
List.find (
fun (grub_config, _) -> g#is_file ~followsymlinks:true grub_config

View File

@@ -65,11 +65,6 @@ let rec inspect_source root_choice g =
StringMap.add name (app :: vs) map
) StringMap.empty apps in
(* See if this guest could use UEFI to boot. It should use GPT and
* it should have an EFI System Partition (ESP).
*)
let uefi = has_uefi_bootable_device g in
let inspect = {
i_root = root;
i_type = g#inspect_get_type root;
@@ -84,7 +79,7 @@ let rec inspect_source root_choice g =
i_mountpoints = mps;
i_apps = apps;
i_apps_map = apps_map;
i_uefi = uefi
i_firmware = get_firmware_bootable_device g;
} in
debug "%s" (string_of_inspect inspect);
@@ -153,10 +148,20 @@ and reject_if_not_installed_image g root =
if fmt <> "installed" then
error (f_"libguestfs thinks this is not an installed operating system (it might be, for example, an installer disk or live CD). If this is wrong, it is probably a bug in libguestfs. root=%s fmt=%s") root fmt
and has_uefi_bootable_device g =
(* 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 ESP(s), then [UEFI devs] is returned where [devs] is the
* list of at least one ESP.
*
* Otherwise, [BIOS] is returned.
*)
and get_firmware_bootable_device g =
let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
and is_uefi_ESP dev { G.part_num = partnum } =
g#part_get_gpt_type dev (Int32.to_int partnum) = uefi_ESP_guid
and part_dev_name dev { G.part_num = partnum } =
sprintf "%s%d" dev (Int32.to_int partnum)
and parttype_is_gpt dev =
try g#part_get_parttype dev = "gpt"
with G.Error msg as exn ->
@@ -164,14 +169,24 @@ and has_uefi_bootable_device g =
if g#last_errno () <> G.Errno.errno_EINVAL then raise exn;
debug "%s (ignored)" msg;
false
and is_uefi_bootable_device dev =
parttype_is_gpt dev && (
let partitions = Array.to_list (g#part_list dev) in
List.exists (is_uefi_ESP dev) partitions
)
and is_uefi_bootable_part dev part =
parttype_is_gpt dev && is_uefi_ESP dev part
in
let devices = Array.to_list (g#list_devices ()) in
List.exists is_uefi_bootable_device devices
let uefi_list = ref [] in
List.iter (
fun dev ->
Array.iter (
fun part ->
if is_uefi_bootable_part dev part then
uefi_list := part_dev_name dev part :: !uefi_list
) (g#part_list dev)
) devices;
match !uefi_list with
| [] -> I_BIOS
| devices -> I_UEFI devices
(* If some inspection fields are "unknown", then that indicates a
* failure in inspection, and we shouldn't continue. For an example

View File

@@ -301,6 +301,10 @@ let string_of_target_firmware = function
| TargetBIOS -> "bios"
| TargetUEFI -> "uefi"
type i_firmware =
| I_BIOS
| I_UEFI of string list
type inspect = {
i_root : string;
i_type : string;
@@ -315,7 +319,7 @@ type inspect = {
i_mountpoints : (string * string) list;
i_apps : Guestfs.application2 list;
i_apps_map : Guestfs.application2 list StringMap.t;
i_uefi : bool;
i_firmware : i_firmware;
}
let string_of_inspect inspect =
@@ -330,7 +334,7 @@ i_package_format = %s
i_package_management = %s
i_product_name = %s
i_product_variant = %s
i_uefi = %b
i_firmware = %s
" inspect.i_root
inspect.i_type
inspect.i_distro
@@ -341,7 +345,9 @@ i_uefi = %b
inspect.i_package_management
inspect.i_product_name
inspect.i_product_variant
inspect.i_uefi
(match inspect.i_firmware with
| I_BIOS -> "BIOS"
| I_UEFI devices -> sprintf "UEFI [%s]" (String.concat ", " devices))
type mpstat = {
mp_dev : string;

View File

@@ -204,6 +204,10 @@ type target_firmware = TargetBIOS | TargetUEFI
val string_of_target_firmware : target_firmware -> string
type i_firmware =
| I_BIOS
| I_UEFI of string list
type inspect = {
i_root : string; (** Root device. *)
i_type : string; (** Usual inspection fields. *)
@@ -221,7 +225,9 @@ type inspect = {
(** This is a map from the app name to the application object.
Since RPM allows multiple packages with the same name to be
installed, the value is a list. *)
i_uefi : bool; (** True if the guest could boot with UEFI. *)
i_firmware : i_firmware;
(** The list of EFI system partitions for the guest with UEFI,
otherwise the BIOS identifier. *)
}
(** Inspection information. *)

View File

@@ -555,7 +555,10 @@ and get_target_firmware inspect guestcaps source output =
| BIOS -> TargetBIOS
| UEFI -> TargetUEFI
| UnknownFirmware ->
if inspect.i_uefi then TargetUEFI else TargetBIOS in
match inspect.i_firmware with
| I_BIOS -> TargetBIOS
| I_UEFI devs -> TargetUEFI
in
let supported_firmware = output#supported_firmware in
if not (List.mem target_firmware supported_firmware) then
error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)")

View File

@@ -30,7 +30,7 @@ let inspect_defaults = {
i_major_version = 0; i_minor_version = 0;
i_root = ""; i_package_format = ""; i_package_management = "";
i_product_name = ""; i_product_variant = ""; i_mountpoints = [];
i_apps = []; i_apps_map = StringMap.empty; i_uefi = false
i_apps = []; i_apps_map = StringMap.empty; i_firmware = I_BIOS
}
let test_get_ostype ctx =