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) get the kernel version from the vmlinuz filename, which should be a
good assumption to do
3) use the calculated version to detect the modules path, checking that
it exists
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.
---
v2v/linux_kernels.ml | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml
index c047d6deb..6a355b880 100644
--- a/v2v/linux_kernels.ml
+++ b/v2v/linux_kernels.ml
@@ -103,27 +103,27 @@ 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. *)
+ (* Get/construct the version from the vmlinuz file.
+ * 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
+ String.sub vmlinuz 14 (String.length vmlinuz - 14) in
+
+ (* Determine the modpath from the vmlinuz version, and check it
+ * exists.
+ *)
+ let modpath = "/lib/modules/" ^ version in
+ 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 +188,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 =
--
2.17.0