@@ -17762,18 +17762,19 @@ the system boots up.
@table @code
@item source
-This is either a string specifying the name of the block device to be mapped,
-such as @code{"/dev/sda3"}, or a list of such strings when several devices
-need to be assembled for creating a new one. In case of LVM this is a
-string specifying name of the volume group to be mapped.
+This is either a string specifying the name of the block device to be
+mapped, such as @code{"/dev/sda3"}. For MD array devices it is either
+the UUID of the array or a string that is interpreted as the array name
+(see mdadm.conf(5) in the manual). In case of LVM it is a string
+specifying name of the volume group to be mapped.
@item target
This string specifies the name of the resulting mapped device. For
kernel mappers such as encrypted devices of type @code{luks-device-mapping},
specifying @code{"my-partition"} leads to the creation of
the @code{"/dev/mapper/my-partition"} device.
-For RAID devices of type @code{raid-device-mapping}, the full device name
-such as @code{"/dev/md0"} needs to be given.
+For MD array devices of type @code{md-array-device-mapping}, the full device
+name such as @code{"/dev/md18"} needs to be given.
LVM logical volumes of type @code{lvm-device-mapping} need to
be specified as @code{"VGNAME-LVNAME"}.
@@ -17793,11 +17794,12 @@ command from the package with the same name. It relies on the
@code{dm-crypt} Linux kernel module.
@end defvar
-@defvar raid-device-mapping
+@defvar md-array-device-mapping
This defines a RAID device, which is assembled using the @code{mdadm}
-command from the package with the same name. It requires a Linux kernel
-module for the appropriate RAID level to be loaded, such as @code{raid456}
-for RAID-4, RAID-5 or RAID-6, or @code{raid10} for RAID-10.
+command from the package with the same name. It requires the Linux kernel
+module for the appropriate RAID level to be loaded, such as @code{raid1}
+for mirroring, @code{raid456} for the checksum-based RAID levels 4, 5 or 6,
+or @code{raid10} for RAID-10.
@end defvar
@cindex LVM, logical volume manager
@@ -17855,9 +17857,9 @@ may be declared as follows:
@lisp
(mapped-device
- (source (list "/dev/sda1" "/dev/sdb1"))
- (target "/dev/md0")
- (type raid-device-mapping))
+ (source (uuid "33cf3e31:8e33d75b:517d64b9:0a8f7623" 'mdadm))
+ (target "/dev/md17")
+ (type md-array-device-mapping))
@end lisp
The @file{/dev/md0} device can then be used as the @code{device} of a
@@ -64,6 +64,7 @@ (define-module (gnu system mapped-devices)
check-device-initrd-modules ;XXX: needs a better place
luks-device-mapping
+ md-array-device-mapping
raid-device-mapping
lvm-device-mapping))
@@ -276,6 +277,39 @@ (define luks-device-mapping
(close close-luks-device)
(check check-luks-device)))
+(define (open-md-array-device source targets)
+ "Return a gexp that assembles SOURCE to the MD device
+TARGET (e.g., \"/dev/md0\"), using 'mdadm'."
+ (let ((array-selector
+ (match source
+ ((? uuid?)
+ (string-append "--uuid=" (uuid->string source)))
+ ((? string?)
+ (string-append "--name=" source))))
+ (md-device
+ (match targets
+ ((target)
+ target))))
+ ;; Use 'mdadm-static' rather than 'mdadm' to avoid pulling its whole
+ ;; closure (80 MiB) in the initrd when an MD device is needed for boot.
+ #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm")
+ "--assemble" #$md-device
+ "--run"
+ #$array-selector))))
+
+(define (close-md-array-device source targets)
+ "Return a gexp that stops the MD device TARGET."
+ (match targets
+ ((target)
+ #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm")
+ "--stop" #$target)))))
+
+(define md-array-device-mapping
+ ;; The type of MD mapped device.
+ (mapped-device-kind
+ (open open-md-array-device)
+ (close close-md-array-device)))
+
(define (open-raid-device sources targets)
"Return a gexp that assembles SOURCES (a list of devices) to the RAID device
TARGET (e.g., \"/dev/md0\"), using 'mdadm'."
@@ -317,6 +351,8 @@ (define raid-device-mapping
(open open-raid-device)
(close close-raid-device)))
+(define-deprecated raid-device-mapping md-array-device-mapping)
+
(define (open-lvm-device source targets)
#~(and
(zero? (system* #$(file-append lvm2-static "/sbin/lvm")
@@ -64,6 +64,7 @@ (define-module (gnu tests install)
%test-iso-image-installer
%test-separate-store-os
%test-separate-home-os
+ %test-md-array-root-os
%test-raid-root-os
%test-encrypted-root-os
%test-encrypted-home-os
@@ -610,6 +611,89 @@ (define %test-separate-store-os
(command (qemu-command* images)))
(run-basic-test %separate-store-os command "separate-store-os")))))
+
+;;;
+;;; MD root device.
+;;;
+
+(define-os-with-source (%md-array-root-os %md-array-root-os-source)
+ ;; An OS whose root partition is a MD partition.
+ (use-modules (gnu) (gnu tests))
+
+ (operating-system
+ (host-name "raidified")
+ (timezone "Europe/Paris")
+ (locale "en_US.utf8")
+
+ (bootloader (bootloader-configuration
+ (bootloader grub-bootloader)
+ (targets (list "/dev/vdb"))))
+ (kernel-arguments '("console=ttyS0"))
+
+ ;; Add a kernel module for RAID-1 (aka. "mirror").
+ (initrd-modules (cons "raid1" %base-initrd-modules))
+
+ (mapped-devices (list (mapped-device
+ (source "marionette:mirror0")
+ (target "/dev/md0")
+ (type md-array-device-mapping))))
+ (file-systems (cons (file-system
+ (device (file-system-label "root-fs"))
+ (mount-point "/")
+ (type "ext4")
+ (dependencies mapped-devices))
+ %base-file-systems))
+ (users %base-user-accounts)
+ (services (cons (service marionette-service-type
+ (marionette-configuration
+ (imported-modules '((gnu services herd)
+ (guix combinators)))))
+ %base-services))))
+
+(define %md-array-root-installation-script
+ ;; Installation with a separate /gnu partition. See
+ ;; <https://raid.wiki.kernel.org/index.php/RAID_setup> for more on RAID and
+ ;; mdadm.
+ "\
+. /etc/profile
+set -e -x
+guix --version
+
+export GUIX_BUILD_OPTIONS=--no-grafts
+parted --script /dev/vdb mklabel gpt \\
+ mkpart primary ext2 1M 3M \\
+ mkpart primary ext2 3M 1.6G \\
+ mkpart primary ext2 1.6G 3.2G \\
+ set 1 boot on \\
+ set 1 bios_grub on
+yes | mdadm --create /dev/md0 --verbose --homehost=marionette --name=mirror0 \\
+ --level=mirror --raid-devices=2 /dev/vdb2 /dev/vdb3
+mkfs.ext4 -L root-fs /dev/md0
+mount /dev/md0 /mnt
+df -h /mnt
+herd start cow-store /mnt
+mkdir /mnt/etc
+cp /etc/target-config.scm /mnt/etc/config.scm
+guix system init /mnt/etc/config.scm /mnt --no-substitutes
+sync
+reboot\n")
+
+(define %test-md-array-root-os
+ (system-test
+ (name "md-array-root-os")
+ (description
+ "Test functionality of an OS installed with a RAID root partition managed
+by 'mdadm'.")
+ (value
+ (mlet* %store-monad ((images (run-install %md-array-root-os
+ %md-array-root-os-source
+ #:script
+ %md-array-root-installation-script
+ #:target-size (* 3200 MiB)))
+ (command (qemu-command* images)))
+ (run-basic-test %md-array-root-os
+ `(,@command) "md-array-root-os")))))
+
;;;
;;; RAID root device.