[bug#55231,v5,1/3] Allows copying of out-of-tree modules to the Linux initrd.

Message ID 15e253236ef3ffae9adf9139c274eeb8cfdf9e8e.1739285590.git.morgan.arnold@proton.me
State New
Headers
Series [bug#55231,v5,1/3] Allows copying of out-of-tree modules to the Linux initrd. |

Commit Message

Morgan Arnold Feb. 11, 2025, 2:56 p.m. UTC
  From: Brian Cully <bjc@spork.org>

With this patch, modules for ‘initrd-modules’ will not only be searched for in
the in-tree Linux modules, but also any additional modules specified in
‘kernel-loadable-modules’.

* gnu/build/linux-modules.scm (find-module-file): change DIRECTORY argument to
DIRECTORIES. Now takes a list of directories to search, rather than a single
one.
* gnu/system/linux-initrd.scm (flat-linux-module-directory): change LINUX
argument to PACKAGES. Now contains a list of file-likes to search for modules.
(raw-initrd): Add LINUX-EXTRA-MODULE-DIRECTORIES keyword argument. Pass it
to (flat-linux-module-directory) along with the selected LINUX package.
(base-initrd): Add LINUX-EXTRA-MODULE-DIRECTORIES keyword argument. Pass it
to (raw-initrd).
* gnu/system.scm (operating-system-initrd-file): pass in operating system
definition's kernel-loadable-modules into (make-initrd) as
LINUX-EXTRA-MODULE-DIRECTORIES.
---
 gnu/build/linux-modules.scm | 19 ++++++++------
 gnu/system.scm              |  2 ++
 gnu/system/linux-initrd.scm | 50 ++++++++++++++++++++++++-------------
 3 files changed, 45 insertions(+), 26 deletions(-)


base-commit: a8f223f91cf1170c85c0133e12856476e40a8288
  

Comments

Maxim Cournoyer Feb. 16, 2025, 7:31 a.m. UTC | #1
Hi Morgan, Brian and all,

Morgan Arnold <morgan.arnold@proton.me> writes:

> From: Brian Cully <bjc@spork.org>
>
> With this patch, modules for ‘initrd-modules’ will not only be searched for in
> the in-tree Linux modules, but also any additional modules specified in
> ‘kernel-loadable-modules’.
>
> * gnu/build/linux-modules.scm (find-module-file): change DIRECTORY argument to
> DIRECTORIES. Now takes a list of directories to search, rather than a single
> one.
> * gnu/system/linux-initrd.scm (flat-linux-module-directory): change LINUX
> argument to PACKAGES. Now contains a list of file-likes to search for modules.
> (raw-initrd): Add LINUX-EXTRA-MODULE-DIRECTORIES keyword argument. Pass it
> to (flat-linux-module-directory) along with the selected LINUX package.
> (base-initrd): Add LINUX-EXTRA-MODULE-DIRECTORIES keyword argument. Pass it
> to (raw-initrd).
> * gnu/system.scm (operating-system-initrd-file): pass in operating system
> definition's kernel-loadable-modules into (make-initrd) as
> LINUX-EXTRA-MODULE-DIRECTORIES.

This change looks reasonable to me, *if* we can make the possible
copyright violation fix that Morgan is working on work correctly.  I've
applied it locally and made the following small changes, also
normalizing the commit message a bit and squashing the documentation
change along the actual change commit:

--8<---------------cut here---------------start------------->8---
modified   doc/guix.texi
@@ -43414,11 +43414,11 @@ Initial RAM Disk
 @end lisp
 
 If a module listed in @code{initrd-modules} is not included in the
-Linux-libre kernel, then the location to it must be added to the
+Linux-libre kernel, then its location must be provided via the
 @code{kernel-loadable-modules} list.
 
-For example, if you need the driver for a Realtek RTL8821CE wireless
-network adapter for mounting the root filesystem over NFS, your
+As an example, if you need the driver for a Realtek RTL8821CE wireless
+network adapter for mounting the root file system over NFS, your
 configuration might include the following:
 
 @lisp
modified   gnu/build/linux-modules.scm
@@ -255,6 +255,9 @@ (define (find-module-file directories module)
 module names usually (always?) use underscores as the inter-word separator,
 whereas file names often, but not always, use hyphens.  Examples:
 \"usb-storage.ko\", \"serpent_generic.ko\"."
+  (define directories (if pair? directories
+                          directories
+                          (list directories))) ;for backward compatibility
   (define names
     ;; List of possible file names.  XXX: It would of course be cleaner to
     ;; have a database that maps module names to file names and vice versa,
@@ -270,7 +273,7 @@ (define (find-module-file directories module)
 
   (match (append-map (lambda (directory)
                        (find-files directory
-                                   (lambda (file _stat)
+                                   (lambda (file _)
                                      (member (strip-extension
                                               (basename file))
                                              names))))
modified   gnu/system/linux-initrd.scm
@@ -128,10 +128,9 @@ (define (flat-linux-module-directory packages modules)
                              (guix build utils))))
 
   (define package-inputs
-    (map (lambda (p)
-           (match p
-             ((p o) (gexp-input p o))
-             (p     (gexp-input p "out"))))
+    (map (match-lambda
+           ((p o) (gexp-input p o))
+           (p     (gexp-input p "out")))
          packages))
 
   (define build-exp
--8<---------------cut here---------------end--------------->8---

I'll now take a look at the initrd substitutability issue/potential fix
from Morgan.
  

Patch

diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm
index 32baf6c525..b47bce9ab2 100644
--- a/gnu/build/linux-modules.scm
+++ b/gnu/build/linux-modules.scm
@@ -246,8 +246,8 @@  (define (file-name->module-name file)
 '.ko[.gz|.xz|.zst]' and normalizing it."
   (normalize-module-name (strip-extension (basename file))))
 
-(define (find-module-file directory module)
-  "Lookup module NAME under DIRECTORY, and return its absolute file name.
+(define (find-module-file directories module)
+  "Lookup module NAME under DIRECTORIES, and return its absolute file name.
 NAME can be a file name with or without '.ko', or it can be a module name.
 Raise an error if it could not be found.
 
@@ -268,16 +268,19 @@  (define (find-module-file directory module)
                            (else chr)))
                        module))))
 
-  (match (find-files directory
-                     (lambda (file stat)
-                       (member (strip-extension
-                                (basename file)) names)))
+  (match (append-map (lambda (directory)
+                       (find-files directory
+                                   (lambda (file _stat)
+                                     (member (strip-extension
+                                              (basename file))
+                                             names))))
+                       directories)
     ((file)
      file)
     (()
-     (error "kernel module not found" module directory))
+     (error "kernel module not found" module directories))
     ((_ ...)
-     (error "several modules by that name" module directory))))
+     (error "several modules by that name" module directories))))
 
 (define* (recursive-module-dependencies files
                                         #:key (lookup-module dot-ko))
diff --git a/gnu/system.scm b/gnu/system.scm
index 8df871f255..1921b60c25 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -1373,6 +1373,8 @@  (define (operating-system-initrd-file os)
                #:linux (operating-system-kernel os)
                #:linux-modules
                (operating-system-initrd-modules os)
+               #:linux-extra-module-directories
+               (operating-system-kernel-loadable-modules os)
                #:mapped-devices mapped-devices
                #:keyboard-layout (operating-system-keyboard-layout os)))
 
diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm
index dc08edc791..dab40dfe22 100644
--- a/gnu/system/linux-initrd.scm
+++ b/gnu/system/linux-initrd.scm
@@ -120,13 +120,20 @@  (define* (expression->initrd exp
                               `(#:references-graphs (("closure" ,init))))
                "/initrd.cpio.gz"))
 
-(define (flat-linux-module-directory linux modules)
+(define (flat-linux-module-directory packages modules)
   "Return a flat directory containing the Linux kernel modules listed in
-MODULES and taken from LINUX."
+MODULES and taken from PACKAGES."
   (define imported-modules
     (source-module-closure '((gnu build linux-modules)
                              (guix build utils))))
 
+  (define package-inputs
+    (map (lambda (p)
+           (match p
+             ((p o) (gexp-input p o))
+             (p     (gexp-input p "out"))))
+         packages))
+
   (define build-exp
     (with-imported-modules imported-modules
       (with-extensions (list guile-zlib guile-zstd)
@@ -138,8 +145,9 @@  (define (flat-linux-module-directory linux modules)
                          (srfi srfi-26)
                          (ice-9 match))
 
-            (define module-dir
-              (string-append #$linux "/lib/modules"))
+            (define module-dirs
+              (map (cut string-append <> "/lib/modules")
+                   '#$package-inputs))
 
             (define builtin-modules
               (match (find-files module-dir (lambda (file stat)
@@ -157,7 +165,7 @@  (define (flat-linux-module-directory linux modules)
               (lset-difference string=? '#$modules builtin-modules))
 
             (define modules
-              (let* ((lookup  (cut find-module-file module-dir <>))
+              (let* ((lookup  (cut find-module-file module-dirs <>))
                      (modules (map lookup modules-to-lookup)))
                 (append modules
                         (recursive-module-dependencies
@@ -192,6 +200,7 @@  (define* (raw-initrd file-systems
                       #:key
                       (linux linux-libre)
                       (linux-modules '())
+                      (linux-extra-module-directories '())
                       (pre-mount #t)
                       (mapped-devices '())
                       (keyboard-layout #f)
@@ -199,15 +208,16 @@  (define* (raw-initrd file-systems
                       qemu-networking?
                       volatile-root?
                       (on-error 'debug))
-  "Return as a file-like object a raw initrd, with kernel
-modules taken from LINUX.  FILE-SYSTEMS is a list of file-systems to be
-mounted by the initrd, possibly in addition to the root file system specified
-on the kernel command line via 'root'.  LINUX-MODULES is a list of kernel
-modules to be loaded at boot time. MAPPED-DEVICES is a list of device
-mappings to realize before FILE-SYSTEMS are mounted. PRE-MOUNT is a
-G-expression to evaluate before realizing MAPPED-DEVICES.
-HELPER-PACKAGES is a list of packages to be copied in the initrd. It may include
-e2fsck/static or other packages needed by the initrd to check root partition.
+  "Return as a file-like object a raw initrd, with kernel modules taken from
+LINUX.  FILE-SYSTEMS is a list of file-systems to be mounted by the initrd,
+possibly in addition to the root file system specified on the kernel command
+line via 'root'.  LINUX-MODULES is a list of kernel modules to be loaded at
+boot time. LINUX-EXTRA-MODULE-DIRECTORIES is a list of file-like objects which
+will be searched for modules in addition to the linux kernel. MAPPED-DEVICES
+is a list of device mappings to realize before FILE-SYSTEMS are mounted.
+HELPER-PACKAGES is a list of packages to be copied in the initrd. It may
+include e2fsck/static or other packages needed by the initrd to check root
+partition.
 
 When true, KEYBOARD-LAYOUT is a <keyboard-layout> record denoting the desired
 console keyboard layout.  This is done before MAPPED-DEVICES are set up and
@@ -243,7 +253,8 @@  (define* (raw-initrd file-systems
           #~())))
 
   (define kodir
-    (flat-linux-module-directory linux linux-modules))
+    (flat-linux-module-directory (cons linux linux-extra-module-directories)
+                                 linux-modules))
 
   (expression->initrd
    (with-imported-modules (source-module-closure
@@ -390,6 +401,7 @@  (define* (base-initrd file-systems
                       #:key
                       (linux linux-libre)
                       (linux-modules '())
+                      (linux-extra-module-directories '())
                       (mapped-devices '())
                       (keyboard-layout #f)
                       qemu-networking?
@@ -410,9 +422,10 @@  (define* (base-initrd file-systems
 QEMU-NETWORKING? and VOLATILE-ROOT? behaves as in raw-initrd.
 
 The initrd is automatically populated with all the kernel modules necessary
-for FILE-SYSTEMS and for the given options.  Additional kernel
-modules can be listed in LINUX-MODULES.  They will be added to the initrd, and
-loaded at boot time in the order in which they appear."
+for FILE-SYSTEMS and for the given options.  Additional kernel modules can be
+listed in LINUX-MODULES.  Additional directories for modules can be listed in
+LINUX-EXTRA-MODULE-DIRECTORIES.  They will be added to the initrd, and loaded
+at boot time in the order in which they appear."
   (define linux-modules*
     ;; Modules added to the initrd and loaded from the initrd.
     `(,@linux-modules
@@ -432,6 +445,7 @@  (define* (base-initrd file-systems
   (raw-initrd file-systems
               #:linux linux
               #:linux-modules linux-modules*
+              #:linux-extra-module-directories linux-extra-module-directories
               #:mapped-devices mapped-devices
               #:helper-packages helper-packages
               #:keyboard-layout keyboard-layout