mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

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

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