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