324 lines
12 KiB
Diff
324 lines
12 KiB
Diff
From 81f35e441d06bff2bf60bff6354d53de137847d9 Mon Sep 17 00:00:00 2001
|
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
Date: Tue, 19 Jun 2018 10:44:57 +0100
|
|
Subject: [PATCH] v2v: Model machine type explicitly.
|
|
|
|
QEMU for x86 supports two machine types, "pc" (emulating the ancient
|
|
Intel i440FX chipset originally used by the Pentium Pro), and "q35"
|
|
(https://wiki.qemu.org/Features/Q35).
|
|
|
|
Currently virt-v2v does not set any machine type, so libvirt or the
|
|
target hypervisor will choose some default, probably i440fx. The
|
|
latest advice from the QEMU and libvirt communities is not to rely on
|
|
the default machine type but to specify what we need explicitly, but
|
|
it may also be that the libvirt configuration file has been changed to
|
|
set the default machine type to Q35 (either by the distro or the end
|
|
user).
|
|
|
|
None of this matters for reasonably new guests since they can boot
|
|
with either chipset. However there are some very old guests (notably
|
|
Windows XP) which cannot handle Q35.
|
|
|
|
This commit changes virt-v2v so it always tries to specify the machine
|
|
type explicitly (assuming the target supports that, and not all of
|
|
them do). For x86_64 guests this patch always selects i440fx (pc).
|
|
In future we hope to get the correct machine type for the guest from
|
|
libosinfo but this is not available yet.
|
|
|
|
For non-x86 architectures we select the "virt" model which will
|
|
probably only work for AArch64. More work is needed for POWER.
|
|
|
|
For secure boot we still have to force the machine type to Q35. In a
|
|
future version this forcing can be removed since any guest which is
|
|
using secure boot will be new enough that it'll be using Q35 anyway
|
|
(on x86).
|
|
|
|
(cherry picked from commit 55879b2f2c5b205352f48f999e20efd9b455ea43)
|
|
---
|
|
v2v/convert_linux.ml | 7 +++++++
|
|
v2v/convert_windows.ml | 7 +++++++
|
|
v2v/create_libvirt_xml.ml | 37 +++++++++++++++++++++++++------------
|
|
v2v/create_ovf.ml | 2 ++
|
|
v2v/output_glance.ml | 5 +++++
|
|
v2v/output_qemu.ml | 30 +++++++++++++++++++-----------
|
|
v2v/test-v2v-i-ova.xml | 2 +-
|
|
v2v/types.ml | 8 ++++++++
|
|
v2v/types.mli | 6 ++++--
|
|
9 files changed, 78 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
|
|
index 4a7447fe1..fd6b71ba4 100644
|
|
--- a/v2v/convert_linux.ml
|
|
+++ b/v2v/convert_linux.ml
|
|
@@ -122,6 +122,12 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
|
|
SELinux_relabel.relabel g;
|
|
|
|
+ (* XXX Look up this information in libosinfo in future. *)
|
|
+ let machine =
|
|
+ match inspect.i_arch with
|
|
+ | "i386"|"x86_64" -> I440FX
|
|
+ | _ -> Virt in
|
|
+
|
|
(* Return guest capabilities from the convert () function. *)
|
|
let guestcaps = {
|
|
gcaps_block_bus = block_type;
|
|
@@ -130,6 +136,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
gcaps_virtio_rng = kernel.ki_supports_virtio_rng;
|
|
gcaps_virtio_balloon = kernel.ki_supports_virtio_balloon;
|
|
gcaps_isa_pvpanic = kernel.ki_supports_isa_pvpanic;
|
|
+ gcaps_machine = machine;
|
|
gcaps_arch = Utils.kvm_arch inspect.i_arch;
|
|
gcaps_acpi = acpi;
|
|
} in
|
|
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
|
index 163319545..1e058136e 100644
|
|
--- a/v2v/convert_windows.ml
|
|
+++ b/v2v/convert_windows.ml
|
|
@@ -212,6 +212,12 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
warning (f_"this guest has Anti-Virus (AV) software and a new virtio block device driver was installed. In some circumstances, AV may prevent new drivers from working (resulting in a 7B boot error). If this happens, try disabling AV before doing the conversion.");
|
|
);
|
|
|
|
+ (* XXX Look up this information in libosinfo in future. *)
|
|
+ let machine =
|
|
+ match inspect.i_arch with
|
|
+ | "i386"|"x86_64" -> I440FX
|
|
+ | _ -> Virt in
|
|
+
|
|
(* Return guest capabilities from the convert () function. *)
|
|
let guestcaps = {
|
|
gcaps_block_bus = block_driver;
|
|
@@ -220,6 +226,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
gcaps_virtio_rng = virtio_rng_supported;
|
|
gcaps_virtio_balloon = virtio_ballon_supported;
|
|
gcaps_isa_pvpanic = isa_pvpanic_supported;
|
|
+ gcaps_machine = machine;
|
|
gcaps_arch = Utils.kvm_arch inspect.i_arch;
|
|
gcaps_acpi = true;
|
|
} in
|
|
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
|
|
index fbe90eeaa..8a34c94b0 100644
|
|
--- a/v2v/create_libvirt_xml.ml
|
|
+++ b/v2v/create_libvirt_xml.ml
|
|
@@ -81,15 +81,17 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
match target_firmware with
|
|
| TargetBIOS -> None
|
|
| TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in
|
|
- let secure_boot_required =
|
|
- match uefi_firmware with
|
|
- | Some { Uefi.flags = flags }
|
|
- when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true
|
|
- | _ -> false in
|
|
- (* Currently these are required by secure boot, but in theory they
|
|
- * might be independent properties.
|
|
- *)
|
|
- let machine_q35 = secure_boot_required in
|
|
+ let machine, secure_boot_required =
|
|
+ match guestcaps.gcaps_machine, uefi_firmware with
|
|
+ | _, Some { Uefi.flags = flags }
|
|
+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags ->
|
|
+ (* Force machine type to Q35 because PC does not support
|
|
+ * secure boot. We must remove this when we get the
|
|
+ * correct machine type from libosinfo in future. XXX
|
|
+ *)
|
|
+ Q35, true
|
|
+ | machine, _ ->
|
|
+ machine, false in
|
|
let smm = secure_boot_required in
|
|
|
|
(* We have the machine features of the guest when it was on the
|
|
@@ -140,7 +142,18 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
|
|
(* The <os> section subelements. *)
|
|
let os_section =
|
|
- let machine = if machine_q35 then [ "machine", "q35" ] else [] in
|
|
+ let os = ref [] in
|
|
+
|
|
+ let machine =
|
|
+ match machine with
|
|
+ | I440FX -> "pc"
|
|
+ | Q35 -> "q35"
|
|
+ | Virt -> "virt" in
|
|
+
|
|
+ List.push_back os
|
|
+ (e "type" ["arch", guestcaps.gcaps_arch;
|
|
+ "machine", machine]
|
|
+ [PCData "hvm"]);
|
|
|
|
let loader =
|
|
match uefi_firmware with
|
|
@@ -152,8 +165,8 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
[ PCData code ];
|
|
e "nvram" ["template", vars_template] [] ] in
|
|
|
|
- (e "type" (["arch", guestcaps.gcaps_arch] @ machine) [PCData "hvm"])
|
|
- :: loader in
|
|
+ List.push_back_list os loader;
|
|
+ !os in
|
|
|
|
List.push_back_list body [
|
|
e "os" [] os_section;
|
|
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
index 5db239d66..01970013e 100644
|
|
--- a/v2v/create_ovf.ml
|
|
+++ b/v2v/create_ovf.ml
|
|
@@ -602,6 +602,8 @@ let rec create_ovf source targets guestcaps inspect
|
|
source.s_vcpu memsize_mb)]
|
|
] in
|
|
|
|
+ (* XXX How to set machine type for Q35? *)
|
|
+
|
|
List.push_back virtual_hardware_section_items (
|
|
e "Item" [] ([
|
|
e "rasd:Caption" [] [PCData (sprintf "%d virtual cpu" source.s_vcpu)];
|
|
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
|
|
index c334def42..96c31da59 100644
|
|
--- a/v2v/output_glance.ml
|
|
+++ b/v2v/output_glance.ml
|
|
@@ -86,6 +86,11 @@ object
|
|
(match guestcaps.gcaps_video with
|
|
| QXL -> "qxl"
|
|
| Cirrus -> "cirrus");
|
|
+ "hw_machine_type",
|
|
+ (match guestcaps.gcaps_machine with
|
|
+ | I440FX -> "pc"
|
|
+ | Q35 -> "q35"
|
|
+ | Virt -> "virt");
|
|
"architecture", guestcaps.gcaps_arch;
|
|
"hypervisor_type", "kvm";
|
|
"vm_mode", "hvm";
|
|
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
|
|
index 952660de2..e23f22e12 100644
|
|
--- a/v2v/output_qemu.ml
|
|
+++ b/v2v/output_qemu.ml
|
|
@@ -56,17 +56,25 @@ object
|
|
match target_firmware with
|
|
| TargetBIOS -> None
|
|
| TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in
|
|
- let secure_boot_required =
|
|
- match uefi_firmware with
|
|
- | Some { Uefi.flags }
|
|
- when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true
|
|
- | _ -> false in
|
|
- (* Currently these are required by secure boot, but in theory they
|
|
- * might be independent properties.
|
|
- *)
|
|
- let machine_q35 = secure_boot_required in
|
|
+ let machine, secure_boot_required =
|
|
+ match guestcaps.gcaps_machine, uefi_firmware with
|
|
+ | _, Some { Uefi.flags }
|
|
+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags ->
|
|
+ (* Force machine type to Q35 because PC does not support
|
|
+ * secure boot. We must remove this when we get the
|
|
+ * correct machine type from libosinfo in future. XXX
|
|
+ *)
|
|
+ Q35, true
|
|
+ | machine, _ ->
|
|
+ machine, false in
|
|
let smm = secure_boot_required in
|
|
|
|
+ let machine =
|
|
+ match machine with
|
|
+ | I440FX -> "pc"
|
|
+ | Q35 -> "q35"
|
|
+ | Virt -> "virt" in
|
|
+
|
|
(* Construct the command line. Note that the [Qemuopts]
|
|
* module deals with shell and qemu comma quoting.
|
|
*)
|
|
@@ -80,8 +88,8 @@ object
|
|
|
|
flag "-no-user-config"; flag "-nodefaults";
|
|
arg "-name" source.s_name;
|
|
- arg_list "-machine" (if machine_q35 then ["q35"] else [] @
|
|
- if smm then ["smm=on"] else [] @
|
|
+ arg_list "-machine" (machine ::
|
|
+ (if smm then ["smm=on"] else []) @
|
|
["accel=kvm:tcg"]);
|
|
|
|
(match uefi_firmware with
|
|
diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml
|
|
index 5a303b80a..b277193a8 100644
|
|
--- a/v2v/test-v2v-i-ova.xml
|
|
+++ b/v2v/test-v2v-i-ova.xml
|
|
@@ -10,7 +10,7 @@
|
|
<apic/>
|
|
</features>
|
|
<os>
|
|
- <type arch='x86_64'>hvm</type>
|
|
+ <type arch='x86_64' machine='pc'>hvm</type>
|
|
</os>
|
|
<on_poweroff>destroy</on_poweroff>
|
|
<on_reboot>restart</on_reboot>
|
|
diff --git a/v2v/types.ml b/v2v/types.ml
|
|
index bb77e5669..9851386f7 100644
|
|
--- a/v2v/types.ml
|
|
+++ b/v2v/types.ml
|
|
@@ -401,6 +401,7 @@ type guestcaps = {
|
|
gcaps_virtio_rng : bool;
|
|
gcaps_virtio_balloon : bool;
|
|
gcaps_isa_pvpanic : bool;
|
|
+ gcaps_machine : guestcaps_machine;
|
|
gcaps_arch : string;
|
|
gcaps_acpi : bool;
|
|
}
|
|
@@ -412,6 +413,7 @@ and requested_guestcaps = {
|
|
and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
|
|
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
|
|
and guestcaps_video_type = QXL | Cirrus
|
|
+and guestcaps_machine = I440FX | Q35 | Virt
|
|
|
|
let string_of_block_type = function
|
|
| Virtio_blk -> "virtio-blk"
|
|
@@ -424,17 +426,23 @@ let string_of_net_type = function
|
|
let string_of_video = function
|
|
| QXL -> "qxl"
|
|
| Cirrus -> "cirrus"
|
|
+let string_of_machine = function
|
|
+ | I440FX -> "i440fx"
|
|
+ | Q35 -> "q35"
|
|
+ | Virt -> "virt"
|
|
|
|
let string_of_guestcaps gcaps =
|
|
sprintf "\
|
|
gcaps_block_bus = %s
|
|
gcaps_net_bus = %s
|
|
gcaps_video = %s
|
|
+gcaps_machine = %s
|
|
gcaps_arch = %s
|
|
gcaps_acpi = %b
|
|
" (string_of_block_type gcaps.gcaps_block_bus)
|
|
(string_of_net_type gcaps.gcaps_net_bus)
|
|
(string_of_video gcaps.gcaps_video)
|
|
+ (string_of_machine gcaps.gcaps_machine)
|
|
gcaps.gcaps_arch
|
|
gcaps.gcaps_acpi
|
|
|
|
diff --git a/v2v/types.mli b/v2v/types.mli
|
|
index f60e5c98f..5e33b1de9 100644
|
|
--- a/v2v/types.mli
|
|
+++ b/v2v/types.mli
|
|
@@ -240,8 +240,9 @@ type guestcaps = {
|
|
gcaps_virtio_balloon : bool; (** Guest supports virtio balloon. *)
|
|
gcaps_isa_pvpanic : bool; (** Guest supports ISA pvpanic device. *)
|
|
|
|
- gcaps_arch : string; (** Architecture that KVM must emulate. *)
|
|
- gcaps_acpi : bool; (** True if guest supports acpi. *)
|
|
+ gcaps_machine : guestcaps_machine; (** Machine model. *)
|
|
+ gcaps_arch : string; (** Architecture that KVM must emulate. *)
|
|
+ gcaps_acpi : bool; (** True if guest supports acpi. *)
|
|
}
|
|
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
|
|
|
|
@@ -257,6 +258,7 @@ and requested_guestcaps = {
|
|
and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
|
|
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
|
|
and guestcaps_video_type = QXL | Cirrus
|
|
+and guestcaps_machine = I440FX | Q35 | Virt
|
|
|
|
val string_of_guestcaps : guestcaps -> string
|
|
val string_of_requested_guestcaps : requested_guestcaps -> string
|
|
--
|
|
2.21.0
|
|
|