|
|
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 |
|