Blob Blame History Raw
From f0cea012d0183edf6f7b769c28d5038593f3fe6a Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 6 Jan 2022 15:09:10 +0100
Subject: [PATCH] convert: determine machine type and virtio-1.0 from osinfo
 for x86 guests

Determine the machine type and virtio-1.0 support from osinfo, for x86
guests. This connects the previous two parts of this series.

Keep the original logic from commit ac39fa292c31 ("v2v: Set machine type
explicitly for outputs which support it (RHBZ#1581428).", 2020-12-04) for
non-x86 guests, and for the case when libosinfo does not recognize the
guest OS.

Update the "cdrom", "floppy", and "i-ova" test cases, which all use a
(phony) Windows 7 image -- Windows 7 does not support virtio-1.0-only
devices, according to libosinfo.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1942325
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220106140910.13695-10-lersek@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
---
 convert/convert_linux.ml       | 51 +++++++++++++++++++++-------------
 convert/convert_windows.ml     | 32 ++++++++++++++-------
 tests/test-v2v-cdrom.expected  |  2 +-
 tests/test-v2v-floppy.expected |  2 +-
 tests/test-v2v-i-ova.xml       |  8 +++---
 5 files changed, 60 insertions(+), 35 deletions(-)

diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml
index 3f1114ad..45ce069a 100644
--- a/convert/convert_linux.ml
+++ b/convert/convert_linux.ml
@@ -123,26 +123,39 @@ let convert (g : G.guestfs) source inspect keep_serial_console _ =
 
     SELinux_relabel.relabel g;
 
-    (* Pivot on the year 2007.  Any Linux distro from earlier than
-     * 2007 should use i440fx, anything 2007 or newer should use q35.
-     * XXX Look up this information in libosinfo in future.
-     *)
-    let machine =
-      match inspect.i_arch, inspect.i_distro, inspect.i_major_version with
-      | ("i386"|"x86_64"), "fedora", _ -> Q35
-      | ("i386"|"x86_64"), ("rhel"|"centos"|"scientificlinux"|
-                            "redhat-based"|"oraclelinux"), major ->
-         if major <= 4 then I440FX else Q35
-      | ("i386"|"x86_64"), ("sles"|"suse-based"|"opensuse"), major ->
-         if major < 10 then I440FX else Q35
-      | ("i386"|"x86_64"), ("debian"|"ubuntu"|"linuxmint"|
-                            "kalilinux"), major ->
-         if major < 4 then I440FX else Q35
+    let machine, virtio_1_0 =
+      match inspect.i_arch with
+      | ("i386"|"x86_64") ->
+        (try
+           let os = Libosinfo_utils.get_os_by_short_id inspect.i_osinfo in
+           let devices = os#get_devices () in
+           debug "libosinfo devices for OS \"%s\":\n%s" inspect.i_osinfo
+             (Libosinfo_utils.string_of_osinfo_device_list devices);
+           let { Libosinfo_utils.q35; vio10 } =
+             Libosinfo_utils.os_support_of_osinfo_device_list devices in
+           (if q35 then Q35 else I440FX), vio10
+         with
+         | Not_found ->
+           (* Pivot on the year 2007.  Any Linux distro from earlier than 2007
+            * should use i440fx, anything 2007 or newer should use q35.
+            *)
+           (match inspect.i_distro, inspect.i_major_version with
+            | "fedora", _ -> Q35
+            | ("rhel"|"centos"|"scientificlinux"|"redhat-based"|"oraclelinux"),
+              major ->
+              if major <= 4 then I440FX else Q35
+            | ("sles"|"suse-based"|"opensuse"), major ->
+              if major < 10 then I440FX else Q35
+            | ("debian"|"ubuntu"|"linuxmint"|"kalilinux"), major ->
+              if major < 4 then I440FX else Q35
 
-      (* reasonable default for all modern Linux kernels *)
-      | ("i386"|"x86_64"), _, _ -> Q35
+            (* reasonable default for all modern Linux kernels *)
+            | _, _ -> Q35
+           ), true
+        )
 
-      | _ -> Virt in
+      | _ -> Virt, true
+    in
 
     (* Return guest capabilities from the convert () function. *)
     let guestcaps = {
@@ -155,7 +168,7 @@ let convert (g : G.guestfs) source inspect keep_serial_console _ =
       gcaps_machine = machine;
       gcaps_arch = Utils.kvm_arch inspect.i_arch;
       gcaps_acpi = acpi;
-      gcaps_virtio_1_0 = true;
+      gcaps_virtio_1_0 = virtio_1_0;
     } in
 
     guestcaps
diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
index 30e494ea..1c2d17f2 100644
--- a/convert/convert_windows.ml
+++ b/convert/convert_windows.ml
@@ -238,15 +238,27 @@ let convert (g : G.guestfs) _ inspect _ static_ips =
         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.");
     );
 
-    (* Pivot on the year 2007.  Any Windows version from earlier than
-     * 2007 should use i440fx, anything 2007 or newer should use q35.
-     * Luckily this coincides almost exactly with the release of NT 6.
-     * XXX Look up this information in libosinfo in future.
-     *)
-    let machine =
-      match inspect.i_arch, inspect.i_major_version with
-      | ("i386"|"x86_64"), major -> if major < 6 then I440FX else Q35
-      | _ -> Virt in
+    let machine, virtio_1_0 =
+      match inspect.i_arch with
+      | ("i386"|"x86_64") ->
+        (try
+           let os = Libosinfo_utils.get_os_by_short_id inspect.i_osinfo in
+           let devices = os#get_devices () in
+           debug "libosinfo devices for OS \"%s\":\n%s" inspect.i_osinfo
+             (Libosinfo_utils.string_of_osinfo_device_list devices);
+           let { Libosinfo_utils.q35; vio10 } =
+             Libosinfo_utils.os_support_of_osinfo_device_list devices in
+           (if q35 then Q35 else I440FX), vio10
+         with
+         | Not_found ->
+           (* Pivot on the year 2007.  Any Windows version from earlier than
+            * 2007 should use i440fx, anything 2007 or newer should use q35.
+            * Luckily this coincides almost exactly with the release of NT 6.
+            *)
+           (if inspect.i_major_version < 6 then I440FX else Q35), true
+        )
+      | _ -> Virt, true
+    in
 
     (* Return guest capabilities from the convert () function. *)
     let guestcaps = {
@@ -259,7 +271,7 @@ let convert (g : G.guestfs) _ inspect _ static_ips =
       gcaps_machine = machine;
       gcaps_arch = Utils.kvm_arch inspect.i_arch;
       gcaps_acpi = true;
-      gcaps_virtio_1_0 = true;
+      gcaps_virtio_1_0 = virtio_1_0;
     } in
 
     guestcaps
diff --git a/tests/test-v2v-cdrom.expected b/tests/test-v2v-cdrom.expected
index 17bd152d..b9504929 100644
--- a/tests/test-v2v-cdrom.expected
+++ b/tests/test-v2v-cdrom.expected
@@ -1,4 +1,4 @@
-    <disk type='file' device='disk'>
+    <disk type='file' device='disk' model='virtio-transitional'>
       <driver name='qemu' type='raw'/>
       <target dev='vda' bus='virtio'/>
     </disk>
diff --git a/tests/test-v2v-floppy.expected b/tests/test-v2v-floppy.expected
index a718c21f..f4b67954 100644
--- a/tests/test-v2v-floppy.expected
+++ b/tests/test-v2v-floppy.expected
@@ -1,4 +1,4 @@
-    <disk type='file' device='disk'>
+    <disk type='file' device='disk' model='virtio-transitional'>
       <driver name='qemu' type='raw'/>
       <target dev='vda' bus='virtio'/>
     </disk>
diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml
index 9f3c1974..2b6a8de0 100644
--- a/tests/test-v2v-i-ova.xml
+++ b/tests/test-v2v-i-ova.xml
@@ -21,7 +21,7 @@
   <on_reboot>restart</on_reboot>
   <on_crash>restart</on_crash>
   <devices>
-    <disk type='file' device='disk'>
+    <disk type='file' device='disk' model='virtio-transitional'>
       <driver name='qemu' type='raw'/>
       <source file='TestOva-sda'/>
       <target dev='vda' bus='virtio'/>
@@ -36,16 +36,16 @@
     </disk>
     <interface type='bridge'>
       <source bridge='VM Network'/>
-      <model type='virtio'/>
+      <model type='virtio-transitional'/>
     </interface>
     <video>
       <model type='vga' vram='16384' heads='1'/>
     </video>
     <graphics type='vnc' autoport='yes' port='-1'/>
-    <rng model='virtio'>
+    <rng model='virtio-transitional'>
       <backend model='random'>/dev/urandom</backend>
     </rng>
-    <memballoon model='virtio'/>
+    <memballoon model='virtio-transitional'/>
     <viosock model='none'/>
     <input type='tablet' bus='usb'/>
     <input type='mouse' bus='ps2'/>
-- 
2.31.1