From 413ebec0392892ca36b86f416f650090ef8825d3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 5 Apr 2017 13:44:00 +0100 Subject: [PATCH] v2v: linux: Fix Xen PV-only detection. We want to detect if a Linux kernel is Xen PV only ("PV-only"). Such a kernel will not boot on KVM, and if a guest has only PV-only kernels, it will not be able to boot at all on the target. Our previous test was wrong. It tested whether the xennet.ko module exists. This module was renamed in more recent kernels (to xen-netfront.ko), so it happened to not detect modern kernels as PV-only, but this was by chance. Modern kernel images can be compiled with Xen PV guest support. The same image can boot on baremetal, KVM, Xen PV or Xen HVM. Testing if the xennet (or xen-netfront) module exists is irrelevant to this. This test, which is based on ideas from Laszlo Ersek and https://wiki.xen.org/wiki/Xen_Project_Software_Overview#Guest_Types uses the kernel config test CONFIG_X86_XEN || CONFIG_X86_64_XEN to determine PV-only kernels. Note that these CONFIG flags were never upstream, and existed only in Linux kernels forked by Xen ("XenLinux"). By the time Xen guest support was added upstream, it was implemented using pvops support, so a single image could boot on Xen and non-Xen as described above, and these flags were no longer used. Updates commit 7eb219d1938968c4d6bffda038aaace936f7efbf. Thanks: Laszlo Ersek. --- v2v/convert_linux.ml | 6 ++++-- v2v/linux_kernels.ml | 10 ++++++---- v2v/linux_kernels.mli | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml index c768902cc..2f8d7457f 100644 --- a/v2v/convert_linux.ml +++ b/v2v/convert_linux.ml @@ -397,7 +397,7 @@ let rec convert (g : G.guestfs) inspect source output rcaps = (* Check a non-Xen kernel exists. *) let only_xen_kernels = List.for_all ( - fun { ki_is_xen_kernel = is_xen_kernel } -> is_xen_kernel + fun { ki_is_xen_pv_only_kernel = pv_only } -> pv_only ) bootloader_kernels in if only_xen_kernels then error (f_"only Xen kernels are installed in this guest.\n\nRead the %s(1) manual, section \"XEN PARAVIRTUALIZED GUESTS\", to see what to do.") prog; @@ -417,7 +417,9 @@ let rec convert (g : G.guestfs) inspect source output rcaps = ) in let kernels = bootloader_kernels in - let kernels = List.filter (fun { ki_is_xen_kernel = is_xen_kernel } -> not is_xen_kernel) kernels in + let kernels = + List.filter (fun { ki_is_xen_pv_only_kernel = pv_only } -> not pv_only) + kernels in let kernels = List.sort compare_best_kernels kernels in let kernels = List.rev kernels (* so best is first *) in List.hd kernels in diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml index 2efd070a6..312d6d1c0 100644 --- a/v2v/linux_kernels.ml +++ b/v2v/linux_kernels.ml @@ -39,7 +39,7 @@ type kernel_info = { ki_modpath : string; ki_modules : string list; ki_supports_virtio : bool; - ki_is_xen_kernel : bool; + ki_is_xen_pv_only_kernel : bool; ki_is_debug : bool; ki_config_file : string option; } @@ -49,7 +49,7 @@ let string_of_kernel_info ki = ki.ki_name ki.ki_version ki.ki_arch ki.ki_vmlinuz (match ki.ki_initrd with None -> "None" | Some f -> f) (match ki.ki_config_file with None -> "None" | Some f -> f) - ki.ki_supports_virtio ki.ki_is_xen_kernel ki.ki_is_debug + ki.ki_supports_virtio ki.ki_is_xen_pv_only_kernel ki.ki_is_debug let detect_kernels (g : G.guestfs) inspect family bootloader = (* What kernel/kernel-like packages are installed on the current guest? *) @@ -182,7 +182,9 @@ let detect_kernels (g : G.guestfs) inspect family bootloader = List.mem what modules || check_config kconf config_file in let supports_virtio = kernel_supports "virtio_net" "VIRTIO_NET" in - let is_xen_kernel = List.mem "xennet" modules in + let is_xen_pv_only_kernel = + check_config "X86_XEN" config_file || + check_config "X86_64_XEN" config_file in (* If the package name is like "kernel-debug", then it's * a debug kernel. @@ -202,7 +204,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader = ki_modpath = modpath; ki_modules = modules; ki_supports_virtio = supports_virtio; - ki_is_xen_kernel = is_xen_kernel; + ki_is_xen_pv_only_kernel = is_xen_pv_only_kernel; ki_is_debug = is_debug; ki_config_file = config_file; } diff --git a/v2v/linux_kernels.mli b/v2v/linux_kernels.mli index 8d5b9f736..a56516233 100644 --- a/v2v/linux_kernels.mli +++ b/v2v/linux_kernels.mli @@ -29,7 +29,7 @@ type kernel_info = { ki_modpath : string; (** The module path. *) ki_modules : string list; (** The list of module names. *) ki_supports_virtio : bool; (** Kernel has virtio drivers? *) - ki_is_xen_kernel : bool; (** Is a Xen paravirt kernel? *) + ki_is_xen_pv_only_kernel : bool; (** Is a Xen paravirt-only kernel? *) ki_is_debug : bool; (** Is debug kernel? *) ki_config_file : string option; (** Path of config file, if found. *) }