file-systems: Convey hint via '&fix-hint'.
[jackhill/guix/guix.git] / gnu / system / linux-initrd.scm
index e7f97bb..0971ec2 100644 (file)
@@ -1,8 +1,9 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
-;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2017, 2019 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2019 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -20,8 +21,6 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu system linux-initrd)
-  #:use-module (guix monads)
-  #:use-module (guix store)
   #:use-module (guix gexp)
   #:use-module (guix utils)
   #:use-module ((guix store)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages disk)
   #:use-module (gnu packages linux)
+  #:use-module (gnu packages file-systems)
   #:use-module (gnu packages guile)
+  #:use-module ((gnu packages xorg)
+                #:select (console-setup xkeyboard-config))
   #:use-module ((gnu packages make-bootstrap)
-                #:select (%guile-static-stripped))
+                #:select (%guile-3.0-static-stripped))
   #:use-module (gnu system file-systems)
   #:use-module (gnu system mapped-devices)
+  #:use-module (gnu system keyboard)
   #:use-module (ice-9 match)
   #:use-module (ice-9 regex)
   #:use-module (ice-9 vlist)
 
 (define* (expression->initrd exp
                              #:key
-                             (guile %guile-static-stripped)
+                             (guile %guile-3.0-static-stripped)
                              (gzip gzip)
                              (name "guile-initrd")
                              (system (%current-system)))
-  "Return a derivation that builds a Linux initrd (a gzipped cpio archive)
+  "Return as a file-like object a Linux initrd (a gzipped cpio archive)
 containing GUILE and that evaluates EXP, a G-expression, upon booting.  All
 the derivations referenced by EXP are automatically copied to the initrd."
 
@@ -93,49 +96,35 @@ the derivations referenced by EXP are automatically copied to the initrd."
             (lambda (port)
               (simple-format port "~A\n" #$guile)))
 
-          (build-initrd (string-append #$output "/initrd")
+          (build-initrd (string-append #$output "/initrd.cpio.gz")
                         #:guile #$guile
                         #:init #$init
                         ;; Copy everything INIT refers to into the initrd.
                         #:references-graphs '("closure")
-                        #:gzip (string-append #$gzip "/bin/gzip")))))
+                        #:gzip (string-append #+gzip "/bin/gzip")))))
 
-  (gexp->derivation name builder
-                    #:references-graphs `(("closure" ,init))))
+  (file-append (computed-file name builder
+                              #:options
+                              `(#:references-graphs (("closure" ,init))))
+               "/initrd.cpio.gz"))
 
 (define (flat-linux-module-directory linux modules)
   "Return a flat directory containing the Linux kernel modules listed in
 MODULES and taken from LINUX."
   (define build-exp
     (with-imported-modules (source-module-closure
-                            '((guix build utils)
-                              (gnu build linux-modules)))
+                            '((gnu build linux-modules)))
       #~(begin
-          (use-modules (ice-9 match) (ice-9 regex)
+          (use-modules (gnu build linux-modules)
                        (srfi srfi-1)
-                       (guix build utils)
-                       (gnu build linux-modules))
-
-          (define (string->regexp str)
-            ;; Return a regexp that matches STR exactly.
-            (string-append "^" (regexp-quote str) "$"))
+                       (srfi srfi-26))
 
           (define module-dir
             (string-append #$linux "/lib/modules"))
 
-          (define (lookup module)
-            (let ((name (ensure-dot-ko module)))
-              (match (find-files module-dir (string->regexp name))
-                ((file)
-                 file)
-                (()
-                 (error "module not found" name module-dir))
-                ((_ ...)
-                 (error "several modules by that name"
-                        name module-dir)))))
-
           (define modules
-            (let ((modules (map lookup '#$modules)))
+            (let* ((lookup  (cut find-module-file module-dir <>))
+                   (modules (map lookup '#$modules)))
               (append modules
                       (recursive-module-dependencies modules
                                                      #:lookup-module lookup))))
@@ -146,7 +135,10 @@ MODULES and taken from LINUX."
                       (copy-file module
                                  (string-append #$output "/"
                                                 (basename module))))
-                    (delete-duplicates modules)))))
+                    (delete-duplicates modules))
+
+          ;; Hyphen or underscore?  This database tells us.
+          (write-module-name-database #$output))))
 
   (computed-file "linux-modules" build-exp))
 
@@ -155,11 +147,12 @@ MODULES and taken from LINUX."
                       (linux linux-libre)
                       (linux-modules '())
                       (mapped-devices '())
+                      (keyboard-layout #f)
                       (helper-packages '())
                       qemu-networking?
                       volatile-root?
                       (on-error 'debug))
-  "Return a monadic derivation that builds a raw initrd, with kernel
+  "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
@@ -168,6 +161,11 @@ 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
+before FILE-SYSTEMS are mounted such that, should the user need to enter a
+passphrase or use the REPL, this happens using the intended keyboard layout.
+
 When QEMU-NETWORKING? is true, set up networking with the standard QEMU
 parameters.
 
@@ -199,7 +197,7 @@ upon error."
      #~(begin
          (use-modules (gnu build linux-boot)
                       (gnu system file-systems)
-                      (guix build utils)
+                      ((guix build utils) #:hide (delete))
                       (guix build bournish)   ;add the 'bournish' meta-command
                       (srfi srfi-26)
 
@@ -215,16 +213,19 @@ upon error."
              (set-path-environment-variable "PATH" '("bin" "sbin")
                                             '#$helper-packages)))
 
-         (boot-system #:mounts
-                      (map spec->file-system
-                           '#$(map file-system->spec file-systems))
-                      #:pre-mount (lambda ()
-                                    (and #$@device-mapping-commands))
-                      #:linux-modules '#$linux-modules
-                      #:linux-module-directory '#$kodir
-                      #:qemu-guest-networking? #$qemu-networking?
-                      #:volatile-root? '#$volatile-root?
-                      #:on-error '#$on-error)))
+         (parameterize ((current-warning-port (%make-void-port "w")))
+           (boot-system #:mounts
+                        (map spec->file-system
+                             '#$(map file-system->spec file-systems))
+                        #:pre-mount (lambda ()
+                                      (and #$@device-mapping-commands))
+                        #:linux-modules '#$linux-modules
+                        #:linux-module-directory '#$kodir
+                        #:keymap-file #+(and=> keyboard-layout
+                                               keyboard-layout->console-keymap)
+                        #:qemu-guest-networking? #$qemu-networking?
+                        #:volatile-root? '#$volatile-root?
+                        #:on-error '#$on-error))))
    #:name "raw-initrd"))
 
 (define* (file-system-packages file-systems #:key (volatile-root? #f))
@@ -242,6 +243,12 @@ FILE-SYSTEMS."
           '())
     ,@(if (find (file-system-type-predicate "btrfs") file-systems)
           (list btrfs-progs/static)
+          '())
+    ,@(if (find (file-system-type-predicate "jfs") file-systems)
+          (list jfs_fsck/static)
+          '())
+    ,@(if (find (file-system-type-predicate "f2fs") file-systems)
+          (list f2fs-fsck/static)
           '())))
 
 (define-syntax vhash                              ;TODO: factorize
@@ -262,8 +269,8 @@ FILE-SYSTEMS."
      (let ((table (vhash mapping ...)))
        (lambda (key)
          (match (vhash-assoc key table)
-           (#f    default)
-           (value value)))))))
+           (#f            default)
+           ((key . value) value)))))))
 
 (define file-system-type-modules
   ;; Given a file system type, return the list of modules it needs.
@@ -271,6 +278,8 @@ FILE-SYSTEMS."
                     ("9p" => '("9p" "9pnet_virtio"))
                     ("btrfs" => '("btrfs"))
                     ("iso9660" => '("isofs"))
+                    ("jfs" => '("jfs"))
+                    ("f2fs" => '("f2fs" "crc32_generic"))
                     (else '())))
 
 (define (file-system-modules file-systems)
@@ -278,8 +287,16 @@ FILE-SYSTEMS."
   (append-map (compose file-system-type-modules file-system-type)
               file-systems))
 
-(define* (default-initrd-modules #:optional (system (%current-system)))
+(define* (default-initrd-modules
+           #:optional
+           (system (or (%current-target-system)
+                       (%current-system))))
   "Return the list of modules included in the initrd by default."
+  (define virtio-modules
+    ;; Modules for Linux para-virtualized devices, for use in QEMU guests.
+    '("virtio_pci" "virtio_balloon" "virtio_blk" "virtio_net"
+      "virtio_console" "virtio-rng"))
+
   `("ahci"                                  ;for SATA controllers
     "usb-storage" "uas"                     ;for the installation image etc.
     "usbhid" "hid-generic" "hid-apple"      ;keyboards during early boot
@@ -288,7 +305,9 @@ FILE-SYSTEMS."
     ,@(if (string-match "^(x86_64|i[3-6]86)-" system)
           '("pata_acpi" "pata_atiixp"    ;for ATA controllers
             "isci")                      ;for SAS controllers like Intel C602
-          '())))
+          '())
+
+    ,@virtio-modules))
 
 (define-syntax %base-initrd-modules
   ;; This more closely matches our naming convention.
@@ -299,38 +318,31 @@ FILE-SYSTEMS."
                       (linux linux-libre)
                       (linux-modules '())
                       (mapped-devices '())
+                      (keyboard-layout #f)
                       qemu-networking?
                       volatile-root?
-                      (virtio? #t)
                       (extra-modules '())         ;deprecated
                       (on-error 'debug))
-  "Return a monadic derivation that builds a generic initrd, with kernel
+  "Return as a file-like object a generic 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'.  MAPPED-DEVICES is a list of device
 mappings to realize before FILE-SYSTEMS are mounted.
 
-QEMU-NETWORKING? and VOLATILE-ROOT? behaves as in raw-initrd.
+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
+before FILE-SYSTEMS are mounted such that, should the user need to enter a
+passphrase or use the REPL, this happens using the intended keyboard layout.
 
-When VIRTIO? is true, load additional modules so the initrd can
-be used as a QEMU guest with the root file system on a para-virtualized block
-device.
+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.  However, additional kernel
-modules can be listed in EXTRA-MODULES.  They will be added to the initrd, and
+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."
-  (define virtio-modules
-    ;; Modules for Linux para-virtualized devices, for use in QEMU guests.
-    '("virtio_pci" "virtio_balloon" "virtio_blk" "virtio_net"
-      "virtio_console"))
-
   (define linux-modules*
     ;; Modules added to the initrd and loaded from the initrd.
     `(,@linux-modules
-      ,@(if (or virtio? qemu-networking?)
-            virtio-modules
-            '())
       ,@(file-system-modules file-systems)
       ,@(if volatile-root?
             '("overlay")
@@ -338,13 +350,18 @@ loaded at boot time in the order in which they appear."
       ,@extra-modules))
 
   (define helper-packages
-    (file-system-packages file-systems #:volatile-root? volatile-root?))
+    (append (file-system-packages file-systems
+                                  #:volatile-root? volatile-root?)
+            (if keyboard-layout
+                (list loadkeys-static)
+                '())))
 
   (raw-initrd file-systems
               #:linux linux
               #:linux-modules linux-modules*
               #:mapped-devices mapped-devices
               #:helper-packages helper-packages
+              #:keyboard-layout keyboard-layout
               #:qemu-networking? qemu-networking?
               #:volatile-root? volatile-root?
               #:on-error on-error))