Subject: [PATCH 3/4] linux-initrd: Add kmod.

From: Danny Milosavljevic <[email-masked]>
Date: Sun, 25 Feb 2018 12:48:15 +0100

* gnu/system/linux-initrd.scm (raw-initrd): Add kmod.
(base-initrd): Add kmod.
(expression->initrd): Add kmod, linux-module-directory.
(flat-linux-module-directory): Add kmod; invoke depmod.
* gnu/build/linux-initrd.scm (build-initrd): Add kmod, linux-module-directory.
---
 gnu/build/linux-initrd.scm  | 13 +++++++++++-
 gnu/system/linux-initrd.scm | 48 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/gnu/build/linux-initrd.scm b/gnu/build/linux-initrd.scm
index c65b5aacf..52cc180b4 100644
--- a/gnu/build/linux-initrd.scm
+++ b/gnu/build/linux-initrd.scm
@@ -107,7 +107,7 @@ This is similar to what 'compiled-file-name' in (system base compile) does."
 
 (define* (build-initrd output
                        #:key
-                       guile init
+                       guile init kmod linux-module-directory
                        (references-graphs '())
                        (gzip "gzip"))
   "Write an initial RAM disk (initrd) to OUTPUT.  The initrd starts the script
@@ -131,6 +131,17 @@ REFERENCES-GRAPHS."
     (symlink (string-append guile "/bin/guile") "proc/self/exe")
     (readlink "proc/self/exe")
 
+    ;; Make modprobe available as /sbin/modprobe so the kernel finds it.
+    (if kmod
+        (begin
+          (mkdir-p "sbin")
+          (symlink (string-append kmod "/bin/modprobe") "sbin/modprobe")))
+
+    ;; Make modules available as /lib/modules so modprobe finds them.
+    (mkdir-p "lib")
+    (symlink (string-append linux-module-directory "/lib/modules")
+             "lib/modules")
+
     ;; Reset the timestamps of all the files that will make it in the initrd.
     (for-each (lambda (file)
                 (unless (eq? 'symlink (stat:type (lstat file)))
diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm
index 7170d1c0e..93089a869 100644
--- a/gnu/system/linux-initrd.scm
+++ b/gnu/system/linux-initrd.scm
@@ -59,6 +59,8 @@
                              #:key
                              (guile %guile-static-stripped)
                              (gzip gzip)
+                             kmod
+                             linux-module-directory
                              (name "guile-initrd")
                              (system (%current-system)))
   "Return a derivation that builds a Linux initrd (a gzipped cpio archive)
@@ -94,6 +96,8 @@ the derivations referenced by EXP are automatically copied to the initrd."
           (build-initrd (string-append #$output "/initrd")
                         #:guile #$guile
                         #:init #$init
+                        #:kmod #$kmod
+                        #:linux-module-directory #$linux-module-directory
                         ;; Copy everything INIT refers to into the initrd.
                         #:references-graphs '("closure")
                         #:gzip (string-append #$gzip "/bin/gzip")))))
@@ -101,7 +105,7 @@ the derivations referenced by EXP are automatically copied to the initrd."
   (gexp->derivation name builder
                     #:references-graphs `(("closure" ,init))))
 
-(define (flat-linux-module-directory linux modules)
+(define (flat-linux-module-directory linux modules kmod)
   "Return a flat directory containing the Linux kernel modules listed in
 MODULES and taken from LINUX."
   (define build-exp
@@ -109,7 +113,7 @@ MODULES and taken from LINUX."
                             '((guix build utils)
                               (gnu build linux-modules)))
       #~(begin
-          (use-modules (ice-9 match) (ice-9 regex)
+          (use-modules (ice-9 match) (ice-9 regex) (ice-9 ftw)
                        (srfi srfi-1)
                        (guix build utils)
                        (gnu build linux-modules))
@@ -138,13 +142,30 @@ MODULES and taken from LINUX."
                       (recursive-module-dependencies modules
                                                      #:lookup-module lookup))))
 
-          (mkdir #$output)
-          (for-each (lambda (module)
-                      (format #t "copying '~a'...~%" module)
-                      (copy-file module
-                                 (string-append #$output "/"
-                                                (basename module))))
-                    (delete-duplicates modules)))))
+          (define version
+            (car
+             (filter
+              (lambda (name)
+                (not (string-prefix? "." name)))
+              (scandir module-dir))))
+
+          (display "VERSION")
+          (display version)
+          (newline)
+
+          (let ((output (string-append #$output "/lib/modules/" version)))
+            (mkdir-p output)
+            (for-each (lambda (module)
+                        (format #t "copying '~a'...~%" module)
+                        (copy-file module
+                                   (string-append output "/"
+                                                  (basename module))))
+                      (delete-duplicates modules)))
+          (invoke (string-append #$kmod "/bin/depmod") "-a" "-b" #$output
+                  ; -E
+                  "-F" (string-append #$linux "/System.map")
+                  version)
+          #t)))
 
   (computed-file "linux-modules" build-exp))
 
@@ -152,6 +173,7 @@ MODULES and taken from LINUX."
                       #:key
                       (linux linux-libre)
                       (linux-modules '())
+                      (kmod kmod-minimal/static)
                       (mapped-devices '())
                       (helper-packages '())
                       qemu-networking?
@@ -185,7 +207,7 @@ upon error."
          mapped-devices))
 
   (define kodir
-    (flat-linux-module-directory linux linux-modules))
+    (flat-linux-module-directory linux linux-modules kmod))
 
   (expression->initrd
    (with-imported-modules (source-module-closure
@@ -223,6 +245,8 @@ upon error."
                       #:qemu-guest-networking? #$qemu-networking?
                       #:volatile-root? '#$volatile-root?
                       #:on-error '#$on-error)))
+   #:kmod kmod
+   #:linux-module-directory kodir
    #:name "raw-initrd"))
 
 (define* (file-system-packages file-systems #:key (volatile-root? #f))
@@ -245,6 +269,7 @@ FILE-SYSTEMS."
 (define* (base-initrd file-systems
                       #:key
                       (linux linux-libre)
+                      (kmod kmod-minimal/static)
                       (mapped-devices '())
                       qemu-networking?
                       volatile-root?
@@ -322,8 +347,9 @@ loaded at boot time in the order in which they appear."
   (raw-initrd file-systems
               #:linux linux
               #:linux-modules linux-modules
+              #:kmod kmod
               #:mapped-devices mapped-devices
-              #:helper-packages helper-packages
+              #:helper-packages (cons kmod helper-packages)
               #:qemu-networking? qemu-networking?
               #:volatile-root? volatile-root?
               #:on-error on-error))