[Libguestfs] [PATCH v4 2/9] v2v: linux: Fix Xen PV-only detection.

Richard W.M. Jones rjones at redhat.com
Thu Apr 6 10:04:20 UTC 2017


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  |  4 ++--
 v2v/linux_kernels.ml  | 10 ++++++----
 v2v/linux_kernels.mli |  2 +-
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index c768902cc..5a83be625 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 = is_xen_pv_only_kernel } -> is_xen_pv_only_kernel
     ) 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,7 @@ 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 = is_xen_pv_only_kernel } -> not is_xen_pv_only_kernel) 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. *)
 }
-- 
2.12.0




More information about the Libguestfs mailing list