From 984124173bc6a7aba3ac0d54d943742492024119 Mon Sep 17 00:00:00 2001 From: Oleg Pykhalov Date: Tue, 24 Nov 2020 07:41:34 +0300 Subject: doc: Fix a typo in WebSSH configuration documentation. * doc/guix.texi (Networking Services): Fix a typo in webssh-configuration. --- doc/guix.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'doc/guix.texi') diff --git a/doc/guix.texi b/doc/guix.texi index ea220fbd63..c5a88b15fa 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -16718,7 +16718,7 @@ Connection policy. @var{reject} policy requires to specify @var{known-hosts}. List of hosts which allowed for SSH connection from @command{webssh}. @item @code{log-file} (default: @file{"/var/log/webssh.log"}) -Name of the file where @command{rsync} writes its log file. +Name of the file where @command{webssh} writes its log file. @item @code{log-level} (default: @var{#f}) Logging level. -- cgit v1.2.3 From 788df2ecd62d5c2fc0d94928f45c947e6393e20b Mon Sep 17 00:00:00 2001 From: Mikhail Tsykalov Date: Fri, 6 Nov 2020 12:47:37 +0300 Subject: mapped-devices: Allow target to be list of strings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/system/mapped-devices.scm (): Rename constructor to %mapped-device. [target]: Remove field. [targets]: New field. Adjust users. (mapped-device-compatibility-helper, mapped-device): New macros. (mapped-device-target): New deprecated procedure. Signed-off-by: Ludovic Courtès --- doc/guix.texi | 3 + gnu/services/base.scm | 3 +- gnu/system.scm | 11 +-- gnu/system/linux-initrd.scm | 10 +-- gnu/system/mapped-devices.scm | 174 +++++++++++++++++++++++++----------------- 5 files changed, 119 insertions(+), 82 deletions(-) (limited to 'doc/guix.texi') diff --git a/doc/guix.texi b/doc/guix.texi index c5a88b15fa..13fb4b1531 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -13780,6 +13780,9 @@ 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. +@item targets +This list of strings specifies names of the resulting mapped devices in case +there are several. The format is identical to @var{target}. @item type This must be a @code{mapped-device-kind} object, which specifies how diff --git a/gnu/services/base.scm b/gnu/services/base.scm index 029df5ac16..3fc4d5f885 100644 --- a/gnu/services/base.scm +++ b/gnu/services/base.scm @@ -298,7 +298,8 @@ FILE-SYSTEM." (define (mapped-device->shepherd-service-name md) "Return the symbol that denotes the shepherd service of MD, a ." (symbol-append 'device-mapping- - (string->symbol (mapped-device-target md)))) + (string->symbol (string-join + (mapped-device-targets md) "-")))) (define dependency->shepherd-service-name (match-lambda diff --git a/gnu/system.scm b/gnu/system.scm index b257ea0385..fcf3310fa3 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -475,9 +475,9 @@ marked as 'needed-for-boot'." (let ((device (file-system-device fs))) (if (string? device) ;title is 'device (filter (lambda (md) - (string=? (string-append "/dev/mapper/" - (mapped-device-target md)) - device)) + (any (cut string=? device <>) + (map (cut string-append "/dev/mapper" <>) + (mapped-device-targets md)))) (operating-system-mapped-devices os)) '()))) @@ -497,11 +497,12 @@ marked as 'needed-for-boot'." (define (mapped-device-users device file-systems) "Return the subset of FILE-SYSTEMS that use DEVICE." - (let ((target (string-append "/dev/mapper/" (mapped-device-target device)))) + (let ((targets (map (cut string-append "/dev/mapper/" <>) + (mapped-device-targets device)))) (filter (lambda (fs) (or (member device (file-system-dependencies fs)) (and (string? (file-system-device fs)) - (string=? (file-system-device fs) target)))) + (any (cut string=? (file-system-device fs) <>) targets)))) file-systems))) (define (operating-system-user-mapped-devices os) diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm index b8a30c0abc..3e2f1282cc 100644 --- a/gnu/system/linux-initrd.scm +++ b/gnu/system/linux-initrd.scm @@ -195,11 +195,11 @@ upon error." (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))) + (let* ((source (mapped-device-source md)) + (targets (mapped-device-targets md)) + (type (mapped-device-type md)) + (open (mapped-device-kind-open type))) + (open source targets))) mapped-devices)) (define kodir diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm index 31c50c4e40..8b5aec983d 100644 --- a/gnu/system/mapped-devices.scm +++ b/gnu/system/mapped-devices.scm @@ -28,6 +28,7 @@ formatted-message &fix-hint &error-location)) + #:use-module (guix deprecation) #:use-module (gnu services) #:use-module (gnu services shepherd) #:use-module (gnu system uuid) @@ -42,10 +43,12 @@ #:use-module (srfi srfi-35) #:use-module (ice-9 match) #:use-module (ice-9 format) - #:export (mapped-device + #:export (%mapped-device + mapped-device mapped-device? mapped-device-source mapped-device-target + mapped-device-targets mapped-device-type mapped-device-location @@ -70,15 +73,36 @@ ;;; ;;; Code: -(define-record-type* mapped-device +(define-record-type* %mapped-device make-mapped-device mapped-device? (source mapped-device-source) ;string | list of strings - (target mapped-device-target) ;string + (targets mapped-device-targets) ;list of strings (type mapped-device-type) ; (location mapped-device-location (default (current-source-location)) (innate))) +(define-syntax mapped-device-compatibility-helper + (syntax-rules (target) + ((_ () (fields ...)) + (%mapped-device fields ...)) + ((_ ((target exp) rest ...) (others ...)) + (%mapped-device others ... + (targets (list exp)) + rest ...)) + ((_ (field rest ...) (others ...)) + (mapped-device-compatibility-helper (rest ...) + (others ... field))))) + +(define-syntax-rule (mapped-device fields ...) + "Build an record, automatically converting 'target' field +specifications to 'targets'." + (mapped-device-compatibility-helper (fields ...) ())) + +(define-deprecated (mapped-device-target md) + mapped-device-targets + (car (mapped-device-targets md))) + (define-record-type* mapped-device-kind make-mapped-device-kind mapped-device-kind? @@ -97,14 +121,14 @@ (shepherd-service-type 'device-mapping (match-lambda - (($ source target + (($ source targets ($ open close)) (shepherd-service - (provision (list (symbol-append 'device-mapping- (string->symbol target)))) + (provision (list (symbol-append 'device-mapping- (string->symbol (string-join targets "-"))))) (requirement '(udev)) (documentation "Map a device node using Linux's device mapper.") - (start #~(lambda () #$(open source target))) - (stop #~(lambda _ (not #$(close source target)))) + (start #~(lambda () #$(open source targets))) + (stop #~(lambda _ (not #$(close source targets)))) (respawn? #f)))))) (define (device-mapping-service mapped-device) @@ -162,48 +186,52 @@ option of @command{guix system}.\n") ;;; Common device mappings. ;;; -(define (open-luks-device source target) +(define (open-luks-device source targets) "Return a gexp that maps SOURCE to TARGET as a LUKS device, using 'cryptsetup'." (with-imported-modules (source-module-closure '((gnu build file-systems))) - #~(let ((source #$(if (uuid? source) - (uuid-bytevector source) - source))) - ;; XXX: 'use-modules' should be at the top level. - (use-modules (rnrs bytevectors) ;bytevector? - ((gnu build file-systems) - #:select (find-partition-by-luks-uuid))) - - ;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling the - ;; whole world inside the initrd (for when we're in an initrd). - (zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") - "open" "--type" "luks" - - ;; Note: We cannot use the "UUID=source" syntax here - ;; because 'cryptsetup' implements it by searching the - ;; udev-populated /dev/disk/by-id directory but udev may - ;; be unavailable at the time we run this. - (if (bytevector? source) - (or (let loop ((tries-left 10)) - (and (positive? tries-left) - (or (find-partition-by-luks-uuid source) - ;; If the underlying partition is - ;; not found, try again after - ;; waiting a second, up to ten - ;; times. FIXME: This should be - ;; dealt with in a more robust way. - (begin (sleep 1) - (loop (- tries-left 1)))))) - (error "LUKS partition not found" source)) - source) - - #$target))))) - -(define (close-luks-device source target) + (match targets + ((target) + #~(let ((source #$(if (uuid? source) + (uuid-bytevector source) + source))) + ;; XXX: 'use-modules' should be at the top level. + (use-modules (rnrs bytevectors) ;bytevector? + ((gnu build file-systems) + #:select (find-partition-by-luks-uuid))) + + ;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling the + ;; whole world inside the initrd (for when we're in an initrd). + (zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") + "open" "--type" "luks" + + ;; Note: We cannot use the "UUID=source" syntax here + ;; because 'cryptsetup' implements it by searching the + ;; udev-populated /dev/disk/by-id directory but udev may + ;; be unavailable at the time we run this. + (if (bytevector? source) + (or (let loop ((tries-left 10)) + (and (positive? tries-left) + (or (find-partition-by-luks-uuid source) + ;; If the underlying partition is + ;; not found, try again after + ;; waiting a second, up to ten + ;; times. FIXME: This should be + ;; dealt with in a more robust way. + (begin (sleep 1) + (loop (- tries-left 1)))))) + (error "LUKS partition not found" source)) + source) + + #$target))))))) + +(define (close-luks-device source targets) "Return a gexp that closes TARGET, a LUKS device." - #~(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") - "close" #$target))) + (match targets + ((target) + #~(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") + "close" #$target))))) (define* (check-luks-device md #:key needed-for-boot? @@ -235,36 +263,40 @@ option of @command{guix system}.\n") (close close-luks-device) (check check-luks-device))) -(define (open-raid-device sources target) +(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'." - #~(let ((sources '#$sources) - - ;; XXX: We're not at the top level here. We could use a - ;; non-top-level 'use-modules' form but that doesn't work when the - ;; code is eval'd, like the Shepherd does. - (every (@ (srfi srfi-1) every)) - (format (@ (ice-9 format) format))) - (let loop ((attempts 0)) - (unless (every file-exists? sources) - (when (> attempts 20) - (error "RAID devices did not show up; bailing out" - sources)) - - (format #t "waiting for RAID source devices~{ ~a~}...~%" - sources) - (sleep 1) - (loop (+ 1 attempts)))) - - ;; Use 'mdadm-static' rather than 'mdadm' to avoid pulling its whole - ;; closure (80 MiB) in the initrd when a RAID device is needed for boot. - (zero? (apply system* #$(file-append mdadm-static "/sbin/mdadm") - "--assemble" #$target sources)))) - -(define (close-raid-device sources target) + (match targets + ((target) + #~(let ((sources '#$sources) + + ;; XXX: We're not at the top level here. We could use a + ;; non-top-level 'use-modules' form but that doesn't work when the + ;; code is eval'd, like the Shepherd does. + (every (@ (srfi srfi-1) every)) + (format (@ (ice-9 format) format))) + (let loop ((attempts 0)) + (unless (every file-exists? sources) + (when (> attempts 20) + (error "RAID devices did not show up; bailing out" + sources)) + + (format #t "waiting for RAID source devices~{ ~a~}...~%" + sources) + (sleep 1) + (loop (+ 1 attempts)))) + + ;; Use 'mdadm-static' rather than 'mdadm' to avoid pulling its whole + ;; closure (80 MiB) in the initrd when a RAID device is needed for boot. + (zero? (apply system* #$(file-append mdadm-static "/sbin/mdadm") + "--assemble" #$target sources)))))) + +(define (close-raid-device sources targets) "Return a gexp that stops the RAID device TARGET." - #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm") - "--stop" #$target))) + (match targets + ((target) + #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm") + "--stop" #$target))))) (define raid-device-mapping ;; The type of RAID mapped devices. -- cgit v1.2.3 From a9a2fdaabcc78e7a54d9a6bcfa4ee3de308e9a90 Mon Sep 17 00:00:00 2001 From: Mikhail Tsykalov Date: Fri, 6 Nov 2020 12:47:38 +0300 Subject: mapped-devices: Add 'lvm-device-mapping'. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/system/mapped-devices.scm (lvm-device-mapping, open-lvm-device, close-lvm-device): New variables. * gnu/tests/install.scm (%lvm-separate-home-os, %lvm-separate-home-os-source, %lvm-separate-home-installation-script, %test-lvm-separate-home-os): New variables. * gnu/system/linux-initrd.scm (raw-initrd): Add (srfi srfi-1) to initrd expression. Signed-off-by: Ludovic Courtès --- doc/guix.texi | 25 ++++++++++++- gnu/system/linux-initrd.scm | 1 + gnu/system/mapped-devices.scm | 25 ++++++++++++- gnu/tests/install.scm | 87 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 4 deletions(-) (limited to 'doc/guix.texi') diff --git a/doc/guix.texi b/doc/guix.texi index 13fb4b1531..22102972a3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -13758,7 +13758,6 @@ Guix extends this notion by considering any device or set of devices that are @dfn{transformed} in some way to create a new device; for instance, RAID devices are obtained by @dfn{assembling} several other devices, such as hard disks or partitions, into a new one that behaves as one partition. -Other examples, not yet implemented, are LVM logical volumes. Mapped devices are declared using the @code{mapped-device} form, defined as follows; for examples, see below. @@ -13771,7 +13770,8 @@ the system boots up. @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. +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. @item target This string specifies the name of the resulting mapped device. For @@ -13780,6 +13780,9 @@ 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. +LVM logical volumes of type @code{lvm-device-mapping} need to +be specified as @code{"VGNAME-LVNAME"}. + @item targets This list of strings specifies names of the resulting mapped devices in case there are several. The format is identical to @var{target}. @@ -13803,6 +13806,11 @@ 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. @end defvr +@defvr {Scheme Variable} lvm-device-mapping +This defines LVM logical volume(s). Volume group is activated by +@command{vgchange} command from the package @code{lvm2}. +@end defvr + @cindex disk encryption @cindex LUKS The following example specifies a mapping from @file{/dev/sda3} to @@ -13860,6 +13868,19 @@ Note that the RAID level need not be given; it is chosen during the initial creation and formatting of the RAID device and is determined automatically later. +LVM logical volumes ``alpha'' and ``beta'' from volume group ``vg0'' can +be declared as follows: + +@lisp +(mapped-device + (source "vg0") + (target (list "vg0-alpha" "vg0-beta")) + (type lvm-device-mapping)) +@end lisp + +Devices @file{/dev/mapper/vg0-alpha} and @file{/dev/mapper/vg0-beta} can +then be used as the @code{device} of a @code{file-system} declaration +(@pxref{File Systems}). @node User Accounts @section User Accounts diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm index 3e2f1282cc..85e493fecb 100644 --- a/gnu/system/linux-initrd.scm +++ b/gnu/system/linux-initrd.scm @@ -217,6 +217,7 @@ upon error." (gnu system file-systems) ((guix build utils) #:hide (delete)) (guix build bournish) ;add the 'bournish' meta-command + (srfi srfi-1) ;for lvm-device-mapping (srfi srfi-26) ;; FIXME: The following modules are for diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm index 8b5aec983d..559c27bb28 100644 --- a/gnu/system/mapped-devices.scm +++ b/gnu/system/mapped-devices.scm @@ -36,7 +36,7 @@ #:autoload (gnu build linux-modules) (missing-modules) #:autoload (gnu packages cryptsetup) (cryptsetup-static) - #:autoload (gnu packages linux) (mdadm-static) + #:autoload (gnu packages linux) (mdadm-static lvm2-static) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) @@ -64,7 +64,8 @@ check-device-initrd-modules ;XXX: needs a better place luks-device-mapping - raid-device-mapping)) + raid-device-mapping + lvm-device-mapping)) ;;; Commentary: ;;; @@ -304,4 +305,24 @@ TARGET (e.g., \"/dev/md0\"), using 'mdadm'." (open open-raid-device) (close close-raid-device))) +(define (open-lvm-device source targets) + #~(and + (zero? (system* #$(file-append lvm2-static "/sbin/lvm") + "vgchange" "--activate" "ay" #$source)) + ; /dev/mapper nodes are usually created by udev, but udev may be unavailable at the time we run this. So we create them here. + (zero? (system* #$(file-append lvm2-static "/sbin/lvm") + "vgscan" "--mknodes")) + (every file-exists? (map (lambda (file) (string-append "/dev/mapper/" file)) + '#$targets)))) + + +(define (close-lvm-device source targets) + #~(zero? (system* #$(file-append lvm2-static "/sbin/lvm") + "vgchange" "--activate" "n" #$source))) + +(define lvm-device-mapping + (mapped-device-kind + (open open-lvm-device) + (close close-lvm-device))) + ;;; mapped-devices.scm ends here diff --git a/gnu/tests/install.scm b/gnu/tests/install.scm index 2d62a873ca..71caa3a493 100644 --- a/gnu/tests/install.scm +++ b/gnu/tests/install.scm @@ -67,6 +67,7 @@ %test-btrfs-root-on-subvolume-os %test-jfs-root-os %test-f2fs-root-os + %test-lvm-separate-home-os %test-gui-installed-os %test-gui-installed-os-encrypted @@ -796,6 +797,92 @@ build (current-guix) and then store a couple of full system images.") (run-basic-test %encrypted-root-os command "encrypted-root-os" #:initialization enter-luks-passphrase))))) + +;;; +;;; Separate /home on LVM +;;; + +;; Since LVM support in guix currently doesn't allow root-on-LVM we use /home on LVM +(define-os-with-source (%lvm-separate-home-os %lvm-separate-home-os-source) + (use-modules (gnu) (gnu tests)) + + (operating-system + (host-name "separate-home-on-lvm") + (timezone "Europe/Paris") + (locale "en_US.utf8") + + (bootloader (bootloader-configuration + (bootloader grub-bootloader) + (target "/dev/vdb"))) + (kernel-arguments '("console=ttyS0")) + + (mapped-devices (list (mapped-device + (source "vg0") + (target "vg0-home") + (type lvm-device-mapping)))) + (file-systems (cons* (file-system + (device (file-system-label "root-fs")) + (mount-point "/") + (type "ext4")) + (file-system + (device "/dev/mapper/vg0-home") + (mount-point "/home") + (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 %lvm-separate-home-installation-script + "\ +. /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 1.6G 3.2G \\ + set 1 boot on \\ + set 1 bios_grub on +pvcreate /dev/vdb3 +vgcreate vg0 /dev/vdb3 +lvcreate -L 1.6G -n home vg0 +vgchange -ay +mkfs.ext4 -L root-fs /dev/vdb2 +mkfs.ext4 /dev/mapper/vg0-home +mount /dev/vdb2 /mnt +mkdir /mnt/home +mount /dev/mapper/vg0-home /mnt/home +df -h /mnt /mnt/home +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-lvm-separate-home-os + (system-test + (name "lvm-separate-home-os") + (description + "Test functionality of an OS installed with a LVM /home partition") + (value + (mlet* %store-monad ((image (run-install %lvm-separate-home-os + %lvm-separate-home-os-source + #:script + %lvm-separate-home-installation-script + #:packages (list lvm2-static) + #:target-size (* 3200 MiB))) + (command (qemu-command/writable-image image))) + (run-basic-test %lvm-separate-home-os + `(,@command) "lvm-separate-home-os"))))) + ;;; ;;; Btrfs root file system. -- cgit v1.2.3 From c350a99bea137186842164ae59161c3dd2dec783 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Wed, 25 Nov 2020 23:58:02 +0100 Subject: doc: Tweak LVM-related info. * doc/guix.texi (Limitations): Remove LVM support. (Mapped Devices): Add link the to LVM web site. Tweak wording. --- doc/guix.texi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'doc/guix.texi') diff --git a/doc/guix.texi b/doc/guix.texi index 22102972a3..484c11162e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -1954,9 +1954,6 @@ Nevertheless, before you proceed with the installation, be aware of the following noteworthy limitations applicable to version @value{VERSION}: @itemize -@item -Support for the Logical Volume Manager (LVM) is missing. - @item More and more system services are provided (@pxref{Services}), but some may be missing. @@ -13806,9 +13803,12 @@ 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. @end defvr +@cindex LVM, logical volume manager @defvr {Scheme Variable} lvm-device-mapping -This defines LVM logical volume(s). Volume group is activated by -@command{vgchange} command from the package @code{lvm2}. +This defines one or more logical volumes for the Linux +@uref{https://www.sourceware.org/lvm2/, Logical Volume Manager (LVM)}. +The volume group is activated by the @command{vgchange} command from the +@code{lvm2} package. @end defvr @cindex disk encryption -- cgit v1.2.3