Blame SOURCES/0020-detect_kernels-deal-with-RHEL-s-kernel-core-kernel-m.patch

1359b8
From 9449d21eeae81d4283e74d7cdccf776e695783f0 Mon Sep 17 00:00:00 2001
1359b8
From: Laszlo Ersek <lersek@redhat.com>
1359b8
Date: Wed, 5 Apr 2023 17:08:29 +0200
1359b8
Subject: [PATCH] detect_kernels: deal with RHEL's kernel-core /
1359b8
 kernel-modules-core split
1359b8
1359b8
In "kernel-5.14.0-269.el9", the "kernel-modules-core" subpackage got split
1359b8
from the "kernel-core" subpackage. Therefore, a single binary RPM
1359b8
containing *both* the "/boot/vmlinuz-5.14.0-269.el9.x86_64" file *and* the
1359b8
"/lib/modules/5.14.0-269.el9.x86_64" directory no longer exists. The file
1359b8
now belongs to "kernel-core", and the directory to "kernel-modules-core".
1359b8
1359b8
As a result, when we investigate the file list of "kernel-core" (based on
1359b8
"kernel-core" providing "/boot/vmlinuz-5.14.0-269.el9.x86_64"), the first
1359b8
match against "/lib/modules/" is not the actual module root directory
1359b8
"/lib/modules/5.14.0-269.el9.x86_64", but the nonsensical
1359b8
"/lib/modules/5.14.0-269.el9.x86_64/.vmlinuz.hmac" regular file. This
1359b8
latter file is never a directory, therefore we rule out "kernel-core" as a
1359b8
kernel package.
1359b8
1359b8
We also rule out "kernel-modules-core" (even earlier) because it does not
1359b8
contain "/boot/vmlinuz-5.14.0-269.el9.x86_64".
1359b8
1359b8
Now, the code already deals with the case if the prospective kernel
1359b8
package *does not provide a match* for the "/lib/modules/" prefix: in that
1359b8
case, we construct the modpath manually, from said prefix, and the version
1359b8
number found in "/boot/vmlinuz-<version>". This fallback is good, but it's
1359b8
unreachable if *there is* a candidate, it's just wrong (i.e., not a
1359b8
directory).
1359b8
1359b8
Perform the "is_dir" check on the candidate modpath earlier, so that we
1359b8
can fall back to the manual modpath construction if the modpath candidate
1359b8
exists, but is wrong.
1359b8
1359b8
With this, the original "is_dir" check becomes superfluous (duplicated)
1359b8
*except* when the "Not_found" branch is taken. Therefore, hoist the
1359b8
original "is_dir" check into that branch.
1359b8
1359b8
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2175703
1359b8
Reported-by: Vera Wu <vwu@redhat.com>
1359b8
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
1359b8
Tested-by: Vera Wu <vwu@redhat.com>
1359b8
(ported from libguestfs-common commit 70c10a079a30ff3a84f38596d725a6c5d46e2470)
1359b8
Message-Id: <20230405150829.171720-3-lersek@redhat.com>
1359b8
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
1359b8
---
1359b8
 convert/linux_kernels.ml | 24 ++++++++++++++++++------
1359b8
 1 file changed, 18 insertions(+), 6 deletions(-)
1359b8
1359b8
diff --git a/convert/linux_kernels.ml b/convert/linux_kernels.ml
1359b8
index 75ab94c4..d0b31643 100644
1359b8
--- a/convert/linux_kernels.ml
1359b8
+++ b/convert/linux_kernels.ml
1359b8
@@ -124,7 +124,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
1359b8
              let prefix = "/lib/modules/" in
1359b8
              let prefix_len = String.length prefix in
1359b8
              try
1359b8
-               List.find_map (
1359b8
+               let modpath, version = List.find_map (
1359b8
                  fun filename ->
1359b8
                    let filename_len = String.length filename in
1359b8
                    if filename_len > prefix_len &&
1359b8
@@ -134,17 +134,29 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
1359b8
                      Some (filename, version)
1359b8
                    ) else
1359b8
                      None
1359b8
-               ) files
1359b8
+               ) files in
1359b8
+               (* Fall back to the version in the vmlinuz file name not only if
1359b8
+                * a candidate pathname couldn't be found under /lib/modules/,
1359b8
+                * but also in case the candidate pathname doesn't reference a
1359b8
+                * directory. See RHBZ#2175703.
1359b8
+                *
1359b8
+                * Note that this "is_dir" check is deliberately kept outside of
1359b8
+                * the "find_map"'s mapper function above: we want the first
1359b8
+                * candidate *to be* a directory, and not the first candidate
1359b8
+                * *that is* a directory.
1359b8
+                *)
1359b8
+               if not (g#is_dir ~followsymlinks:true modpath) then
1359b8
+                 raise Not_found;
1359b8
+               modpath, version
1359b8
              with Not_found ->
1359b8
                let version =
1359b8
                  String.sub vmlinuz 14 (String.length vmlinuz - 14) in
1359b8
                let modpath = prefix ^ version in
1359b8
+               (* Check that the modpath exists. *)
1359b8
+               if not (g#is_dir ~followsymlinks:true modpath) then
1359b8
+                 raise Not_found;
1359b8
                modpath, version in
1359b8
 
1359b8
-           (* Check that the modpath exists. *)
1359b8
-           if not (g#is_dir ~followsymlinks:true modpath) then
1359b8
-             raise Not_found;
1359b8
-
1359b8
            (* Find the initramfs which corresponds to the kernel.
1359b8
             * Since the initramfs is built at runtime, and doesn't have
1359b8
             * to be covered by the RPM file list, this is basically