system: Add support for boot-time mapped devices.

* gnu/build/linux-boot.scm (boot-system): Add #:pre-mount parameter and
  honor it.
* gnu/system/linux-initrd.scm (base-initrd): Add #:mapped-devices
  parameter.  Add 'device-mapping-commands' variable, and use it to
  build the #:pre-mount argument of 'boot-system'.
* gnu/system.scm (mapped-device-user,
  operating-system-user-mapped-devices,
  operating-system-boot-mapped-devices): New procedures.
  (device-mapping-services): Use 'operating-system-user-mapped-devices'
  instead of 'operating-system-mapped-devices'.
  (operating-system-initrd-file): Call the initrd with #:mapped-devices.
This commit is contained in:
Ludovic Courtès 2014-09-22 11:06:42 +02:00
parent e2b464b7f4
commit de1c158f32
3 changed files with 61 additions and 9 deletions

View File

@ -340,13 +340,14 @@ bailing out.~%root contents: ~s~%" (scandir "/"))
(linux-modules '()) (linux-modules '())
qemu-guest-networking? qemu-guest-networking?
volatile-root? volatile-root?
pre-mount
(mounts '())) (mounts '()))
"This procedure is meant to be called from an initrd. Boot a system by "This procedure is meant to be called from an initrd. Boot a system by
first loading LINUX-MODULES (a list of absolute file names of '.ko' files), first loading LINUX-MODULES (a list of absolute file names of '.ko' files),
then setting up QEMU guest networking if QEMU-GUEST-NETWORKING? is true, then setting up QEMU guest networking if QEMU-GUEST-NETWORKING? is true,
mounting the file systems specified in MOUNTS, and finally booting into the calling PRE-MOUNT, mounting the file systems specified in MOUNTS, and finally
new root if any. The initrd supports kernel command-line options '--load', booting into the new root if any. The initrd supports kernel command-line
'--root', and '--repl'. options '--load', '--root', and '--repl'.
Mount the root file system, specified by the '--root' command-line argument, Mount the root file system, specified by the '--root' command-line argument,
if any. if any.
@ -403,6 +404,11 @@ to it are lost."
(mkdir "/root/dev") (mkdir "/root/dev")
(make-essential-device-nodes #:root "/root")) (make-essential-device-nodes #:root "/root"))
(when (procedure? pre-mount)
;; Do whatever actions are needed before mounting--e.g., installing
;; device mappings.
(pre-mount))
;; Mount the specified file systems. ;; Mount the specified file systems.
(for-each mount-file-system (for-each mount-file-system
(remove root-mount-point? mounts)) (remove root-mount-point? mounts))

View File

@ -216,6 +216,34 @@ as 'needed-for-boot'."
#:flags flags)))) #:flags flags))))
file-systems))) file-systems)))
(define (mapped-device-user device file-systems)
"Return a file system among FILE-SYSTEMS that uses DEVICE, or #f."
(let ((target (string-append "/dev/mapper/" (mapped-device-target device))))
(find (lambda (fs)
(string=? (file-system-device fs) target))
file-systems)))
(define (operating-system-user-mapped-devices os)
"Return the subset of mapped devices that can be installed in
user-land--i.e., those not needed during boot."
(let ((devices (operating-system-mapped-devices os))
(file-systems (operating-system-file-systems os)))
(filter (lambda (md)
(let ((user (mapped-device-user md file-systems)))
(or (not user)
(not (file-system-needed-for-boot? user)))))
devices)))
(define (operating-system-boot-mapped-devices os)
"Return the subset of mapped devices that must be installed during boot,
from the initrd."
(let ((devices (operating-system-mapped-devices os))
(file-systems (operating-system-file-systems os)))
(filter (lambda (md)
(let ((user (mapped-device-user md file-systems)))
(and user (file-system-needed-for-boot? user))))
devices)))
(define (device-mapping-services os) (define (device-mapping-services os)
"Return the list of device-mapping services for OS as a monadic list." "Return the list of device-mapping services for OS as a monadic list."
(sequence %store-monad (sequence %store-monad
@ -228,7 +256,7 @@ as 'needed-for-boot'."
(device-mapping-service target (device-mapping-service target
(open source target) (open source target)
(close source target)))) (close source target))))
(operating-system-mapped-devices os)))) (operating-system-user-mapped-devices os))))
(define (swap-services os) (define (swap-services os)
"Return the list of swap services for OS as a monadic list." "Return the list of swap services for OS as a monadic list."
@ -561,10 +589,14 @@ we're running in the final root."
boot?)) boot?))
(operating-system-file-systems os))) (operating-system-file-systems os)))
;; TODO: Pass the mapped devices required by boot-time file systems to the (define mapped-devices
;; initrd. (operating-system-boot-mapped-devices os))
(mlet %store-monad
((initrd ((operating-system-initrd os) boot-file-systems))) (define make-initrd
(operating-system-initrd os))
(mlet %store-monad ((initrd (make-initrd boot-file-systems
#:mapped-devices mapped-devices)))
(return #~(string-append #$initrd "/initrd")))) (return #~(string-append #$initrd "/initrd"))))
(define (kernel->grub-label kernel) (define (kernel->grub-label kernel)

View File

@ -126,14 +126,16 @@ initrd code."
(define* (base-initrd file-systems (define* (base-initrd file-systems
#:key #:key
(mapped-devices '())
qemu-networking? qemu-networking?
virtio? virtio?
volatile-root? volatile-root?
(extra-modules '())) (extra-modules '()))
;; TODO: Support boot-time device mappings.
"Return a monadic derivation that builds a generic initrd. FILE-SYSTEMS is "Return a monadic derivation that builds a generic initrd. FILE-SYSTEMS is
a list of file-systems to be mounted by the initrd, possibly in addition to 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'. 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.
When QEMU-NETWORKING? is true, set up networking with the standard QEMU When QEMU-NETWORKING? is true, set up networking with the standard QEMU
parameters. When VIRTIO? is true, load additional modules so the initrd can parameters. When VIRTIO? is true, load additional modules so the initrd can
@ -191,6 +193,16 @@ loaded at boot time in the order in which they appear."
(list unionfs-fuse/static) (list unionfs-fuse/static)
'()))) '())))
(define device-mapping-commands
;; List of gexps to open the mapped devices.
(map (lambda (md)
(let* ((source (mapped-device-source md))
(target (mapped-device-target md))
(type (mapped-device-type md))
(open (mapped-device-kind-open type)))
(open source target)))
mapped-devices))
(mlet %store-monad ((kodir (flat-linux-module-directory linux-libre (mlet %store-monad ((kodir (flat-linux-module-directory linux-libre
linux-modules))) linux-modules)))
(expression->initrd (expression->initrd
@ -205,6 +217,8 @@ loaded at boot time in the order in which they appear."
'#$helper-packages))) '#$helper-packages)))
(boot-system #:mounts '#$(map file-system->spec file-systems) (boot-system #:mounts '#$(map file-system->spec file-systems)
#:pre-mount (lambda ()
(and #$@device-mapping-commands))
#:linux-modules (map (lambda (file) #:linux-modules (map (lambda (file)
(string-append #$kodir "/" file)) (string-append #$kodir "/" file))
'#$linux-modules) '#$linux-modules)