mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0204-v2v-Add-a-check-before-copying-that-UEFI-is-supporte.patch

ffd6ed
From 6ea4891f843196d822af07b91155f86cee87736a Mon Sep 17 00:00:00 2001
ffd6ed
From: "Richard W.M. Jones" <rjones@redhat.com>
ffd6ed
Date: Mon, 6 Jul 2015 12:37:23 +0100
ffd6ed
Subject: [PATCH] v2v: Add a check before copying that UEFI is supported
ffd6ed
 (RHBZ#1184690).
ffd6ed
ffd6ed
If UEFI is required by the guest, but not supported by the host, then
ffd6ed
you wouldn't see an error message until after copying.
ffd6ed
ffd6ed
Add an additional method to the output object so we can check this
ffd6ed
before copying, to avoid a long wait.
ffd6ed
ffd6ed
Thanks: Junqin Zhou
ffd6ed
https://bugzilla.redhat.com/show_bug.cgi?id=1184690#c22
ffd6ed
(cherry picked from commit b04f39bf10e4f760d880d1077e6ffb68d028c0ae)
ffd6ed
---
ffd6ed
 v2v/output_libvirt.ml | 12 ++++++++++++
ffd6ed
 v2v/output_qemu.ml    |  9 +++++++++
ffd6ed
 v2v/types.ml          |  1 +
ffd6ed
 v2v/types.mli         |  4 ++++
ffd6ed
 v2v/v2v.ml            | 40 ++++++++++++++++++++++------------------
ffd6ed
 5 files changed, 48 insertions(+), 18 deletions(-)
ffd6ed
ffd6ed
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
ffd6ed
index 40280dd..de4aeb4 100644
ffd6ed
--- a/v2v/output_libvirt.ml
ffd6ed
+++ b/v2v/output_libvirt.ml
ffd6ed
@@ -376,6 +376,18 @@ class output_libvirt verbose oc output_pool = object
ffd6ed
         { t with target_file = target_file }
ffd6ed
     ) targets
ffd6ed
 
ffd6ed
+  method check_target_firmware guestcaps target_firmware =
ffd6ed
+    match target_firmware with
ffd6ed
+    | TargetBIOS -> ()
ffd6ed
+    | TargetUEFI ->
ffd6ed
+       (* This will fail with an error if the target firmware is
ffd6ed
+        * not installed on the host.
ffd6ed
+        * XXX Can remove this method when libvirt supports
ffd6ed
+        * <loader type="efi"/> since then it will be up to
ffd6ed
+        * libvirt to check this.
ffd6ed
+        *)
ffd6ed
+       ignore (find_uefi_firmware guestcaps.gcaps_arch)
ffd6ed
+
ffd6ed
   method create_metadata source targets guestcaps _ target_firmware =
ffd6ed
     (* We copied directly into the final pool directory.  However we
ffd6ed
      * have to tell libvirt.
ffd6ed
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
ffd6ed
index c593030..c5e38f2 100644
ffd6ed
--- a/v2v/output_qemu.ml
ffd6ed
+++ b/v2v/output_qemu.ml
ffd6ed
@@ -40,6 +40,15 @@ object
ffd6ed
         { t with target_file = target_file }
ffd6ed
     ) targets
ffd6ed
 
ffd6ed
+  method check_target_firmware guestcaps target_firmware =
ffd6ed
+    match target_firmware with
ffd6ed
+    | TargetBIOS -> ()
ffd6ed
+    | TargetUEFI ->
ffd6ed
+       (* This will fail with an error if the target firmware is
ffd6ed
+        * not installed on the host.
ffd6ed
+        *)
ffd6ed
+       ignore (find_uefi_firmware guestcaps.gcaps_arch)
ffd6ed
+
ffd6ed
   method create_metadata source targets guestcaps inspect target_firmware =
ffd6ed
     let name = source.s_name in
ffd6ed
     let file = dir // name ^ ".sh" in
ffd6ed
diff --git a/v2v/types.ml b/v2v/types.ml
ffd6ed
index 41d2686..7b33965 100644
ffd6ed
--- a/v2v/types.ml
ffd6ed
+++ b/v2v/types.ml
ffd6ed
@@ -312,6 +312,7 @@ class virtual output verbose = object
ffd6ed
   method virtual as_options : string
ffd6ed
   method virtual prepare_targets : source -> target list -> target list
ffd6ed
   method virtual supported_firmware : target_firmware list
ffd6ed
+  method check_target_firmware (_ : guestcaps) (_ : target_firmware) = ()
ffd6ed
   method check_target_free_space (_ : source) (_ : target list) = ()
ffd6ed
   method disk_create = (new Guestfs.guestfs ())#disk_create
ffd6ed
   method virtual create_metadata : source -> target list -> guestcaps -> inspect -> target_firmware -> unit
ffd6ed
diff --git a/v2v/types.mli b/v2v/types.mli
ffd6ed
index da398d3..e7e99eb 100644
ffd6ed
--- a/v2v/types.mli
ffd6ed
+++ b/v2v/types.mli
ffd6ed
@@ -202,6 +202,10 @@ class virtual output : bool -> object
ffd6ed
   method virtual supported_firmware : target_firmware list
ffd6ed
   (** Does this output method support UEFI?  Allows us to abort early if
ffd6ed
       conversion is impossible. *)
ffd6ed
+  method check_target_firmware : guestcaps -> target_firmware -> unit
ffd6ed
+  (** Called before conversion once the guest's target firmware is known.
ffd6ed
+      Can be used as an additional check that the target firmware is
ffd6ed
+      supported on the host. *)
ffd6ed
   method check_target_free_space : source -> target list -> unit
ffd6ed
   (** Called before conversion.  Can be used to check there is enough space
ffd6ed
       on the target, using the [target.target_estimated_size] field. *)
ffd6ed
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
ffd6ed
index d509a4c..c18039f 100644
ffd6ed
--- a/v2v/v2v.ml
ffd6ed
+++ b/v2v/v2v.ml
ffd6ed
@@ -217,24 +217,6 @@ let rec main () =
ffd6ed
   msg (f_"Inspecting the overlay");
ffd6ed
   let inspect = inspect_source ~verbose g root_choice in
ffd6ed
 
ffd6ed
-  (* Does the guest require UEFI on the target? *)
ffd6ed
-  let target_firmware =
ffd6ed
-    match source.s_firmware with
ffd6ed
-    | BIOS -> TargetBIOS
ffd6ed
-    | UEFI -> TargetUEFI
ffd6ed
-    | UnknownFirmware ->
ffd6ed
-       if inspect.i_uefi then TargetUEFI else TargetBIOS in
ffd6ed
-  let supported_firmware = output#supported_firmware in
ffd6ed
-  if not (List.mem target_firmware supported_firmware) then
ffd6ed
-    error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)")
ffd6ed
-          (string_of_target_firmware target_firmware)
ffd6ed
-          (String.concat " "
ffd6ed
-            (List.map string_of_target_firmware supported_firmware));
ffd6ed
-  (match target_firmware with
ffd6ed
-   | TargetBIOS -> ()
ffd6ed
-   | TargetUEFI ->
ffd6ed
-       info ~prog (f_"This guest requires UEFI on the target to boot."));
ffd6ed
-
ffd6ed
   (* The guest free disk space check and the target free space
ffd6ed
    * estimation both require statvfs information from mountpoints, so
ffd6ed
    * get that information first.
ffd6ed
@@ -308,6 +290,28 @@ let rec main () =
ffd6ed
   g#shutdown ();
ffd6ed
   g#close ();
ffd6ed
 
ffd6ed
+  (* Does the guest require UEFI on the target? *)
ffd6ed
+  msg (f_"Checking if the guest needs BIOS or UEFI to boot");
ffd6ed
+  let target_firmware =
ffd6ed
+    match source.s_firmware with
ffd6ed
+    | BIOS -> TargetBIOS
ffd6ed
+    | UEFI -> TargetUEFI
ffd6ed
+    | UnknownFirmware ->
ffd6ed
+       if inspect.i_uefi then TargetUEFI else TargetBIOS in
ffd6ed
+  let supported_firmware = output#supported_firmware in
ffd6ed
+  if not (List.mem target_firmware supported_firmware) then
ffd6ed
+    error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)")
ffd6ed
+          (string_of_target_firmware target_firmware)
ffd6ed
+          (String.concat " "
ffd6ed
+            (List.map string_of_target_firmware supported_firmware));
ffd6ed
+
ffd6ed
+  output#check_target_firmware guestcaps target_firmware;
ffd6ed
+
ffd6ed
+  (match target_firmware with
ffd6ed
+   | TargetBIOS -> ()
ffd6ed
+   | TargetUEFI ->
ffd6ed
+       info ~prog (f_"This guest requires UEFI on the target to boot."));
ffd6ed
+
ffd6ed
   (* Force a GC here, to ensure that we're using the minimum resources
ffd6ed
    * as we go into the copy stage.  The particular reason is that
ffd6ed
    * Windows conversion may have opened a second libguestfs handle
ffd6ed
-- 
ffd6ed
1.8.3.1
ffd6ed