Blame SOURCES/0049-v2v-linux-fix-kernel-detection-when-split-in-differe.patch

97ae69
From f9586e74f18110ab7a70e29a5a577afed0666ca0 Mon Sep 17 00:00:00 2001
97ae69
From: Pino Toscano <ptoscano@redhat.com>
97ae69
Date: Tue, 22 May 2018 10:46:21 +0200
97ae69
Subject: [PATCH] v2v: linux: fix kernel detection when split in different
97ae69
 packages
97ae69
97ae69
The current detection code for Linux kernels assumes that a kernel
97ae69
package contains everything in it, i.e. the kernel itself, its modules,
97ae69
and its configuration.  However, since recent Ubuntu versions (e.g.
97ae69
starting from 18.04) modules & config (with few more files) are split in
97ae69
an own package, thus not detecting the modpath from installed vmlinuz
97ae69
files.
97ae69
97ae69
To overcome this situation, rework this detection a bit:
97ae69
1) find the vmlinuz file as before, but then immediately make sure it
97ae69
   exists by stat'ing it
97ae69
2) find the modules path from the package as before:
97ae69
2a) if found, extract the version in the same step
97ae69
2b) if not found, get the kernel version from the vmlinuz filename,
97ae69
    and use it to detect the modules path
97ae69
3) check that the modules path exists
97ae69
97ae69
The detection done in (2b) is based on the current packaging scheme
97ae69
found in the most important Linux distributions (Fedora, RHEL, CentOS,
97ae69
Debian, Ubuntu, openSUSE, AltLinux, and possibly more).  The notable
97ae69
exception is Arch Linux.
97ae69
97ae69
As additional change, do not assume the config file is in the same
97ae69
package as vmlinuz, but directly look into the filesystem using the
97ae69
version we already have.
97ae69
97ae69
(cherry picked from commit 500acb15f8f777e9fe99a60c4216daf84a92aae3)
97ae69
---
97ae69
 v2v/linux_kernels.ml | 47 +++++++++++++++++++++++++++++---------------
97ae69
 1 file changed, 31 insertions(+), 16 deletions(-)
97ae69
97ae69
diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml
97ae69
index c047d6deb..24f61429d 100644
97ae69
--- a/v2v/linux_kernels.ml
97ae69
+++ b/v2v/linux_kernels.ml
97ae69
@@ -103,27 +103,42 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
97ae69
              None
97ae69
            )
97ae69
            else (
97ae69
-             (* Which of these is the kernel itself? *)
97ae69
+             (* Which of these is the kernel itself?  Also, make sure to check
97ae69
+              * it exists by stat'ing it.
97ae69
+              *)
97ae69
              let vmlinuz = List.find (
97ae69
                fun filename -> String.is_prefix filename "/boot/vmlinuz-"
97ae69
              ) files in
97ae69
-             (* Which of these is the modpath? *)
97ae69
-             let modpath = List.find (
97ae69
-               fun filename ->
97ae69
-                 String.length filename >= 14 &&
97ae69
-                   String.is_prefix filename "/lib/modules/"
97ae69
-             ) files in
97ae69
-
97ae69
-             (* Check vmlinuz & modpath exist. *)
97ae69
-             if not (g#is_dir ~followsymlinks:true modpath) then
97ae69
-               raise Not_found;
97ae69
              let vmlinuz_stat =
97ae69
                try g#statns vmlinuz with G.Error _ -> raise Not_found in
97ae69
 
97ae69
-             (* Get/construct the version.  XXX Read this from kernel file. *)
97ae69
-             let version =
97ae69
-               let prefix_len = String.length "/lib/modules/" in
97ae69
-               String.sub modpath prefix_len (String.length modpath - prefix_len) in
97ae69
+             (* Determine the modpath from the package, falling back to the
97ae69
+              * version in the vmlinuz file name.
97ae69
+              *)
97ae69
+             let modpath, version =
97ae69
+               let prefix = "/lib/modules/" in
97ae69
+               try
97ae69
+                 let prefix_len = String.length prefix in
97ae69
+                 List.find_map (
97ae69
+                   fun filename ->
97ae69
+                     let filename_len = String.length filename in
97ae69
+                     if filename_len > prefix_len &&
97ae69
+                        String.is_prefix filename prefix then (
97ae69
+                       let version = String.sub filename prefix_len
97ae69
+                                                (filename_len - prefix_len) in
97ae69
+                       Some (filename, version)
97ae69
+                     ) else
97ae69
+                       None
97ae69
+                 ) files
97ae69
+               with Not_found ->
97ae69
+                 let version =
97ae69
+                   String.sub vmlinuz 14 (String.length vmlinuz - 14) in
97ae69
+                 let modpath = prefix ^ version in
97ae69
+                 modpath, version in
97ae69
+
97ae69
+             (* Check that the modpath exists. *)
97ae69
+             if not (g#is_dir ~followsymlinks:true modpath) then
97ae69
+               raise Not_found;
97ae69
 
97ae69
              (* Find the initramfs which corresponds to the kernel.
97ae69
               * Since the initramfs is built at runtime, and doesn't have
97ae69
@@ -188,7 +203,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
97ae69
 
97ae69
              let config_file =
97ae69
                let cfg = "/boot/config-" ^ version in
97ae69
-               if List.mem cfg files then Some cfg
97ae69
+               if g#is_file ~followsymlinks:true cfg then Some cfg
97ae69
                else None in
97ae69
 
97ae69
              let kernel_supports what kconf =
97ae69
-- 
fd1da6
2.17.2
97ae69