[PATCH] Allow booting from a Btrfs subvolume.

DoneSubmitted by Maxim Cournoyer.
Details
4 participants
  • Ludovic Courtès
  • Pierre Neidhardt
  • Christopher Baines
  • Maxim Cournoyer
Owner
unassigned
Severity
normal
M
M
Maxim Cournoyer wrote on 5 Sep 2019 02:20
(name . guix-patches)(address . guix-patches@gnu.org)
87sgpby4p9.fsf@gmail.com
Hello!
I'm sending this patch series to add support for booting off Btrfssubvolumes. There was some interested shown on #guix, so hopefullysomeone can test it on their system :-)
Before this change, it wasn't possible to pass the required options tothe Linux kernel as our init script would ignore them.
I'm not including system tests yet, as this will take a bit more timeand is starting to be a big change in itself.
From 6858efa540d89c54ce377bfa6a6882e551cd2e56 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH 1/4] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (prepend-subvol, arguments->subvol): New procedures.(grub-configuration-file): Use ARGUMENTS->SUBVOL to extract the subvolume namefrom the kernel arguments, and prepend it to the kernel and initrd paths usingthe PREPEND-SUBVOL procedure.* tests/grub.scm: Add tests for the "arguments->subvol" procedure.* doc/guix.texi (File Systems, (Bootloader Configuration): Document the use ofBtrfs subvolumes.--- doc/guix.texi | 29 ++++++++++++++++++++- gnu/bootloader/grub.scm | 43 +++++++++++++++++++++++++------ gnu/build/linux-boot.scm | 7 +++-- gnu/build/linux-modules.scm | 3 ++- tests/grub.scm | 51 +++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 tests/grub.scm
Toggle diff (239 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 707c2ba700..cc7c91ac92 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -48,7 +48,7 @@ Copyright @copyright{} 2017 humanitiesNerd@* Copyright @copyright{} 2017 Christopher Allan Webber@* Copyright @copyright{} 2017, 2018 Marius Bakke@* Copyright @copyright{} 2017 Hartmut Goebel@*-Copyright @copyright{} 2017 Maxim Cournoyer@*+Copyright @copyright{} 2017, 2019 Maxim Cournoyer@* Copyright @copyright{} 2017, 2018, 2019 Tobias Geerinckx-Rice@* Copyright @copyright{} 2017 George Clemmer@* Copyright @copyright{} 2017 Andy Wingo@*@@ -10802,6 +10802,20 @@ using the @code{file-system} form, like this: (type "ext4")) @end example +@cindex Btrfs subvolume, file system+Below is a more complex example, making use of a Btrfs subvolume, named+@code{rootfs}, which parent Btrfs file system is labeled @code{my-btrfs-pool},+on an encrypted device (hence the dependency on @code{mapped-devices}):++@example+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options "defaults,subvol=rootfs")+ (dependencies mapped-devices))+@end example+ As usual, some of the fields are mandatory---those shown in the example above---while others can be omitted. These are described below. @@ -24868,6 +24882,19 @@ when you boot it on your system. @code{grub-bootloader} allows you to boot in particular Intel-based machines in ``legacy'' BIOS mode. +@cindex rootflags, Grub+@cindex Btrfs root subvolume, Grub+To allow using a Btrfs @emph{subvolume} for the root partition, the Grub-based+bootloaders can use a subvolume @emph{name} passed using the @code{rootflags}+kernel argument, e.g.:++@example+(kernel-arguments '("rootflags=subvol=@var{root-subvolume-name}"))+@end example++to correctly populate the @code{kernel} and @code{initrd} fields of the Grub+configuration file.+ @cindex ARM, bootloaders @cindex AArch64, bootloaders Available bootloaders are described in @code{(gnu bootloader @dots{})}diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex d984d5f5e3..dee6028dd0 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -3,6 +3,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Leo Famulari <leo@famulari.name> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>+;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -25,6 +26,8 @@ #:use-module (guix gexp) #:use-module (gnu artwork) #:use-module (gnu bootloader)+ #:use-module ((gnu build linux-modules) #:select (%not-comma))+ #:use-module ((gnu build linux-boot) #:select (find-long-option)) #:use-module (gnu system uuid) #:use-module (gnu system file-systems) #:use-module (gnu system keyboard)@@ -34,6 +37,7 @@ #:use-module (ice-9 match) #:use-module (ice-9 regex) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-26) #:export (grub-image grub-image? grub-image-aspect-ratio@@ -73,6 +77,14 @@ denoting a file name." file)))) (#f file))) +(define (prepend-subvol subvol file)+ "Prepend SUBVOL from FILE, which is a gexp or other lowerable object+denoting a file name."+ (match subvol+ ((? string? subvol)+ #~(string-append "/" #$subvol #$file))+ (#f file)))+ (define-record-type* <grub-image> grub-image make-grub-image grub-image?@@ -313,6 +325,13 @@ code." ((or #f (? string?)) #~(format #f "search --file --set ~a" #$file))))) +(define (arguments->subvol arguments)+ "Return any \"subvol\" value given as an option to the \"rootflags\"+argument, or #f on failure."+ (let* ((rootflags (find-long-option "rootflags" arguments))+ (rootflags-options (and=> rootflags (cut string-tokenize <> %not-comma))))+ (and=> rootflags-options (cut find-long-option "subvol" <>))))+ (define* (grub-configuration-file config entries #:key (system (%current-system))@@ -324,18 +343,26 @@ entries corresponding to old generations of the system." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (kernel (menu-entry-linux entry))+ (arguments (menu-entry-linux-arguments entry))+ (subvol (arguments->subvol arguments))+ (initrd (menu-entry-initrd entry))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))++ ;; Also, in case a subvolume name could be extracted from the "subvol"+ ;; option given to the "rootflags" argument of the kernel, it is+ ;; prepended to the kernel and initrd paths, to allow booting from+ ;; a Btrfs subvolume.+ (let ((kernel (prepend-subvol subvol (strip-mount-point+ device-mount-point kernel)))+ (initrd (prepend-subvol subvol (strip-mount-point+ device-mount-point initrd)))) #~(format port "menuentry ~s { ~a linux ~a ~adiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex f273957d78..7a30ebcef1 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -92,9 +92,12 @@ (define (find-long-option option arguments) "Find OPTION among ARGUMENTS, where OPTION is something like \"--load\".-Return the value associated with OPTION, or #f on failure."+Return the value associated with OPTION, or #f on failure. Any non-string+arguments are ignored." (let ((opt (string-append option "=")))- (and=> (find (cut string-prefix? opt <>)+ (and=> (find (lambda (arg)+ (and (string? arg)+ (string-prefix? opt arg))) arguments) (lambda (arg) (substring arg (+ 1 (string-index arg #\=)))))))diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scmindex a149eff329..5f2efe7484 100644--- a/gnu/build/linux-modules.scm+++ b/gnu/build/linux-modules.scm@@ -32,7 +32,8 @@ #:use-module (ice-9 match) #:use-module (ice-9 rdelim) #:autoload (ice-9 pretty-print) (pretty-print)- #:export (dot-ko+ #:export (%not-comma+ dot-ko ensure-dot-ko module-formal-name module-aliasesdiff --git a/tests/grub.scm b/tests/grub.scmnew file mode 100644index 0000000000..81453b00ab--- /dev/null+++ b/tests/grub.scm@@ -0,0 +1,51 @@+;;; GNU Guix --- Functional package management for GNU+;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>+;;;+;;; This file is part of GNU Guix.+;;;+;;; GNU Guix is free software; you can redistribute it and/or modify it+;;; under the terms of the GNU General Public License as published by+;;; the Free Software Foundation; either version 3 of the License, or (at+;;; your option) any later version.+;;;+;;; GNU Guix is distributed in the hope that it will be useful, but+;;; WITHOUT ANY WARRANTY; without even the implied warranty of+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+;;; GNU General Public License for more details.+;;;+;;; You should have received a copy of the GNU General Public License+;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.++(define-module (test-grub)+ #:use-module (gnu bootloader grub)+ #:use-module (srfi srfi-64))++;;; Local bindings to private procedures that are to be tested.+(define arguments->subvol (@@ (gnu bootloader grub) arguments->subvol))++ +(test-begin "grub")++(test-equal "Get subvolume name from arguments, multiple options"+ "@"+ (arguments->subvol '("ro" "debug"+ "rootflags=foo=bar,subvol=@,bar=baz")))++(test-equal "No subvolume from arguments"+ #f+ (arguments->subvol '("rootflags=foo=bar")))++(test-equal "No rootflags argument"+ #f+ (arguments->subvol '("ro" "debug")))++(test-equal "Empty arguments list"+ #f+ (arguments->subvol '()))++;;; The other types would typically be gexp objects.+(test-equal "Argument list may contain other types than string"+ "rootfs"+ (arguments->subvol '(#f "rootflags=subvol=rootfs")))++(test-end "grub")-- 2.23.0
From 3a628d1e731b2857a4c964484213cce980cb596f Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 16 Jul 2019 18:09:38 +0900Subject: [PATCH 2/4] build: initrd: Fix "write-cpio-archive" return value.
* gnu/build/linux-initrd.scm (write-cpio-archive): Really return OUTPUT onsuccess, even when compression is disabled.--- gnu/build/linux-initrd.scm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
Toggle diff (24 lines)diff --git a/gnu/build/linux-initrd.scm b/gnu/build/linux-initrd.scmindex 3aaa06d3a0..ea7de58553 100644--- a/gnu/build/linux-initrd.scm+++ b/gnu/build/linux-initrd.scm@@ -71,8 +71,7 @@ COMPRESS? is true, compress it using GZIP. On success, return OUTPUT." (cpio:write-cpio-archive files port #:file->header cpio:file->cpio-header*))) - (or (not compress?)-+ (if compress? ;; Gzip insists on adding a '.gz' suffix and does nothing if the input ;; file already has that suffix. Shuffle files around to placate it. (let* ((gz-suffix? (string-suffix? ".gz" output))@@ -88,7 +87,6 @@ COMPRESS? is true, compress it using GZIP. On success, return OUTPUT." (unless gz-suffix? (rename-file (string-append output ".gz") output)) output)))- output)) (define (cache-compiled-file-name file)-- 2.23.0
From 49ffe9a2645252bb708995169a9f1749f3982385 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Thu, 18 Jul 2019 07:23:48 +0900Subject: [PATCH 3/4] linux-boot: Fix typo.
* gnu/build/linux-boot.scm (mount-root-file-system): Fix typo.--- gnu/build/linux-boot.scm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Toggle diff (18 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 7a30ebcef1..b4e6421b27 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -362,8 +362,9 @@ the last argument of `mknod'." (define* (mount-root-file-system root type #:key volatile-root?) "Mount the root file system of type TYPE at device ROOT. If VOLATILE-ROOT?-is true, mount ROOT read-only and make it a overlay with a writable tmpfs-using the kernel build-in overlayfs."+is true, mount ROOT read-only and make it an overlay with a writable tmpfs+using the kernel built-in overlayfs."+ (if volatile-root? (begin (mkdir-p "/real-root")-- 2.23.0
From b56aea9c62b015c8a8b48827f9587b1578c83af3 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Thu, 18 Jul 2019 04:59:25 +0900Subject: [PATCH 4/4] linux-boot: Honor "rootflags" kernel argument.
* gnu/build/linux-boot.scm (mount-root-file-system): Add the optional FLAGSand OPTIONS arguments; and document them. Pass those to the `mount' calls.(boot-system): Parse the "rootflags" kernel argument, and use it when calling`mount-root-file-system'.* doc/guix.texi (Initial RAM Disk): Document the use of the "rootflags"argument.--- doc/guix.texi | 19 +++++++++++++++++++ gnu/build/linux-boot.scm | 22 +++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-)
Toggle diff (100 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex cc7c91ac92..1e093b38a0 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -24761,6 +24761,25 @@ Instruct the initial RAM disk as well as the @command{modprobe} command must be a comma-separated list of module names---e.g., @code{usbkbd,9pnet}. +@item rootflags=@var{options}@dots{}+@cindex mount options, passed to initrd+@cindex rootflags, initrd+This argument allows passing one or multiple file system specific mount+options to the @code{mount} procedure used by the init script. @var{options}+must be a comma-separated list of option names or option-value pairs. The+following example instructs the initial RAM disk to mount the Btrfs subvolume+named ``rootfs'' as the root file system, and to enable automatic file+defragmentation:++@example+rootflags=subvol=rootfs,autodefrag+@end example++Specifying the subvolume to mount by its name, as shown above, is also used in+Guix to produce a working Grub configuration for the Grub-based bootloaders+when using a Btrfs subvolume for the root file system (@xref{Bootloader+Configuration}).+ @item --repl Start a read-eval-print loop (REPL) from the initial RAM disk before it tries to load kernel modules and to mount the root file system. Ourdiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex b4e6421b27..b2d8f74a71 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>+;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -360,15 +361,16 @@ the last argument of `mknod'." (filter-map string->number (scandir "/proc"))))) (define* (mount-root-file-system root type+ #:optional (flags 0) options #:key volatile-root?)- "Mount the root file system of type TYPE at device ROOT. If VOLATILE-ROOT?-is true, mount ROOT read-only and make it an overlay with a writable tmpfs-using the kernel built-in overlayfs."-+ "Mount the root file system of type TYPE at device ROOT. The optional FLAGS+and OPTIONS arguments behave the same as for the `mount' procedure. If+VOLATILE-ROOT? is true, mount ROOT read-only and make it an overlay with a+writable tmpfs using the kernel built-in overlayfs." (if volatile-root? (begin (mkdir-p "/real-root")- (mount root "/real-root" type MS_RDONLY)+ (mount root "/real-root" type (logior MS_RDONLY flags) options) (mkdir-p "/rw-root") (mount "none" "/rw-root" "tmpfs") @@ -385,11 +387,11 @@ using the kernel built-in overlayfs." "lowerdir=/real-root,upperdir=/rw-root/upper,workdir=/rw-root/work")) (begin (check-file-system root type)- (mount root "/root" type)))+ (mount root "/root" type flags options))) ;; Make sure /root/etc/mtab is a symlink to /proc/self/mounts. (false-if-exception- (delete-file "/root/etc/mtab"))+ (delete-file "/root/etc/mtab")) (mkdir-p "/root/etc") (symlink "/proc/self/mounts" "/root/etc/mtab")) @@ -483,7 +485,8 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root (find-long-option "--root" args))+ (rootflags (find-long-option "rootflags" args))) (when (member "--repl" args) (start-repl))@@ -526,7 +529,8 @@ upon error." ((uuid root) => identity) (else (file-system-label root))))) (mount-root-file-system (canonicalize-device-spec root)- root-fs-type+ root-fs-type 0+ rootflags #:volatile-root? volatile-root?)) (mount "none" "/root" "tmpfs")) -- 2.23.0
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl1wVLIACgkQEmDkZILmNWLKPhAAixwXUlhjtluKkuXgMqow/tjWQf2O0fpWJB+UrmZjJvVDWkpIsR6fOjpn+/RdR7cDp4SqlhsNr15CwWIt0NYbNcSZGwgcVD/59Hj5YER2Nl/gBdgw8wV1jBbQnkW45+PhCko5WBahxOB4F53VWdPJ5YzO5mLRNSbAvH7+mRqdyctLZmqkSRfGmbb34/ndo3399GMzhgS1h4hc+t+jsBwFfj9SmaVNZbAyXB/5gmyCSvmcwYFMrfYaCHGT7ZOSw/khhCKzGuzXyE8fsYsybOHuWkD2fDrOHLW9lv4F9+VyIoZgY1gAdoddAmPyAt0kxr+Lpeqf9ujlJu494A8hG+DpmgeMP2zp4pCVPcTN5S/LNqvBhzlifyf7bynjcI5Lv15C6YNibT8Su/v27XSo4heZm8GsCtpVLkjzVJAFeQnoedFelIgot/nLAuHU2CSEe0ZUC0IC5ltmB16T/5POVBF0dqWBgKa0xXRVyY202f6AyhY3OE3z929kgiD4w8oBHNed2Oxq7ZTc2WdTsgJ5C1IJod+sUr6R6BtdVTZKXgH6ijA7hf35rBUSKSh56YgzG1J0/KoaWSICfGLUgJ8DRX7s+vDFjBCxem68ZLhwvp0vvQAyhDSEGxdeOFeBnXbrtg0YbM4R2VJr8Ic5bcKovzlhtuwINu2Ku+Weu/6BSegyVes==rD4K-----END PGP SIGNATURE-----
C
C
Christopher Baines wrote on 8 Sep 2019 18:10
(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
87mufeojks.fsf@cbaines.net
Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:
Toggle quote (12 lines)> Hello!>> I'm sending this patch series to add support for booting off Btrfs> subvolumes. There was some interested shown on #guix, so hopefully> someone can test it on their system :-)>> Before this change, it wasn't possible to pass the required options to> the Linux kernel as our init script would ignore them.>> I'm not including system tests yet, as this will take a bit more time> and is starting to be a big change in itself.
Hey,
I haven't got around to looking at this yet, but I did write a systemtest when I reported this bug [1], it's in the0001-WIP-Btrfs-store-subvolume-test.patch file in the initialmessage [2]. Maybe you could see if that passes with your changes here?
1: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=335172: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=33517#5
Chris
-----BEGIN PGP SIGNATURE-----
iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAl11J+RfFIAAAAAALgAoaXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNFODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE9XeqCw//dzTr+fXTT2cQcmyIr6hHgN01PMo99uAkjkcg6wqa5sHmSAV7cilf4iQ5GhkwUToC8swwoeXLplKB/3mSZ+Q70qkNazLOEDP6Ff6z+IXHVcbVMYbEdPb2ugridiwnnFvBuRvH2n2JYjG8STkOfQWFcBEkL2+5Eed16KQ9OpSWyy3FHptxdpz+U6paGlXKkmd4zUOJ5Qg6UtYRDstohX4c2w9hMzbe1rViSrOlTVbWs3ExDm4zewY77z3WahVe26YK3tYBpXo+kyn8l/vYPLAzV92vSELHaKzSo40sxAczugjjIwTgB2UJDWyY9SwRznty5DnfNgGB4DHd8QUjrmL+bNZ6SvfhFBHq1FNkGekHpo2Big3ysU1VA0IIaeTirw0H8/zS4SG6UuGpboZK4ItccbFmytrsGjiNZ5SyLlBISmXGCZejBLlHOzgjmbsrgebene51W/H+6fSCXvlQatw7vVfnYBbhcAz86HdeeuU55+0PXAdbiSkqrHLk+Y6YjM6FHPDTPNJaTKY7OkDSIxVmzPAoqduoQ67WVTE8Ig5AM/XKA3p7tfL6vxqFA+a3pcgeWl/CcUMOsHiU1QnWAtezIjQ2levvcCHB/wgnDqPAYgwNs7arKXMHLoSrjbWySATWSoLKr7eLiNzJCcSrfogBtxLcPm6OQEsx8Jap0k6a6Xo==y5iw-----END PGP SIGNATURE-----
L
L
Ludovic Courtès wrote on 22 Sep 2019 23:43
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
87y2yg3t3s.fsf@gnu.org
Hi!
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (10 lines)> I'm sending this patch series to add support for booting off Btrfs> subvolumes. There was some interested shown on #guix, so hopefully> someone can test it on their system :-)>> Before this change, it wasn't possible to pass the required options to> the Linux kernel as our init script would ignore them.>> I'm not including system tests yet, as this will take a bit more time> and is starting to be a big change in itself.
Did you have a chance to look at the system test that Chris mentioned?
Toggle quote (13 lines)> From 6858efa540d89c54ce377bfa6a6882e551cd2e56 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Sun, 14 Jul 2019 20:50:23 +0900> Subject: [PATCH 1/4] bootloader: grub: Allow booting from a Btrfs subvolume.>> * gnu/bootloader/grub.scm (prepend-subvol, arguments->subvol): New procedures.> (grub-configuration-file): Use ARGUMENTS->SUBVOL to extract the subvolume name> from the kernel arguments, and prepend it to the kernel and initrd paths using> the PREPEND-SUBVOL procedure.> * tests/grub.scm: Add tests for the "arguments->subvol" procedure.> * doc/guix.texi (File Systems, (Bootloader Configuration): Document the use of> Btrfs subvolumes.
[...]
Toggle quote (4 lines)> +@cindex rootflags, Grub> +@cindex Btrfs root subvolume, Grub> +To allow using a Btrfs @emph{subvolume} for the root partition, the Grub-based
Nitpick: s/Grub/GRUB/
Toggle quote (16 lines)> --- a/gnu/bootloader/grub.scm> +++ b/gnu/bootloader/grub.scm> @@ -3,6 +3,7 @@> ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>> ;;; Copyright © 2017 Leo Famulari <leo@famulari.name>> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>> +;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>> ;;;> ;;; This file is part of GNU Guix.> ;;;> @@ -25,6 +26,8 @@> #:use-module (guix gexp)> #:use-module (gnu artwork)> #:use-module (gnu bootloader)> + #:use-module ((gnu build linux-modules) #:select (%not-comma))
‘%not-comma’ is not a great API and not quite related to linux-modules:-), so it’s one of the rare cases where I’d rather keep it private andduplicate it if needed.
Toggle quote (7 lines)> +(define (arguments->subvol arguments)> + "Return any \"subvol\" value given as an option to the \"rootflags\"> +argument, or #f on failure."> + (let* ((rootflags (find-long-option "rootflags" arguments))> + (rootflags-options (and=> rootflags (cut string-tokenize <> %not-comma))))> + (and=> rootflags-options (cut find-long-option "subvol" <>))))
Maybe rename ‘arguments->subvol’ to ‘linux-arguments-btrfs-subvolume’ orsimilar?
Is “rootflags” the commonly-used name here?
Toggle quote (23 lines)> + (let* ((device (menu-entry-device entry))> + (device-mount-point (menu-entry-device-mount-point entry))> + (label (menu-entry-label entry))> + (kernel (menu-entry-linux entry))> + (arguments (menu-entry-linux-arguments entry))> + (subvol (arguments->subvol arguments))> + (initrd (menu-entry-initrd entry)))> ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point.> ;; Use the right file names for KERNEL and INITRD in case> ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a> ;; separate partition.> - (let ((kernel (strip-mount-point device-mount-point kernel))> - (initrd (strip-mount-point device-mount-point initrd)))> +> + ;; Also, in case a subvolume name could be extracted from the "subvol"> + ;; option given to the "rootflags" argument of the kernel, it is> + ;; prepended to the kernel and initrd paths, to allow booting from> + ;; a Btrfs subvolume.> + (let ((kernel (prepend-subvol subvol (strip-mount-point> + device-mount-point kernel)))> + (initrd (prepend-subvol subvol (strip-mount-point> + device-mount-point initrd))))
It might be clearer to have an explicit:
(if subvolume #~(string-append #$subvolume …) (strip-mount-point …))
than to hide the ‘if’ in ‘prepend-subvol’.
Regarding the interface, it’s the only time where we extract info fromthe user-provided ‘kernel-arguments’ list. Usually it’s the other wayaround: we have ‘file-systems’, and from that we build up the list ofkernel arguments.
Do you think it could be made to work similarly? (I’m not familiar withBtrfs though.) That way, we wouldn’t have to parse the kernelarguments, the user wouldn’t have to fiddle explicitly with kernelarguments, and the end result might more easily work with all thebootloaders.
Toggle quote (14 lines)> (define (find-long-option option arguments)> "Find OPTION among ARGUMENTS, where OPTION is something like \"--load\".> -Return the value associated with OPTION, or #f on failure."> +Return the value associated with OPTION, or #f on failure. Any non-string> +arguments are ignored."> (let ((opt (string-append option "=")))> - (and=> (find (cut string-prefix? opt <>)> + (and=> (find (lambda (arg)> + (and (string? arg)> + (string-prefix? opt arg)))> arguments)> (lambda (arg)> (substring arg (+ 1 (string-index arg #\=)))))))
Ignoring non-strings makes for a weird API IMO. :-)I understand this is because, when using it on the host side, you maynow pass it gexps instead of strings. But perhaps that calls for a newprocedure?
Toggle quote (8 lines)> From 3a628d1e731b2857a4c964484213cce980cb596f Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 16 Jul 2019 18:09:38 +0900> Subject: [PATCH 2/4] build: initrd: Fix "write-cpio-archive" return value.>> * gnu/build/linux-initrd.scm (write-cpio-archive): Really return OUTPUT on> success, even when compression is disabled.
Good catch, go for it!
Toggle quote (7 lines)> From 49ffe9a2645252bb708995169a9f1749f3982385 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Thu, 18 Jul 2019 07:23:48 +0900> Subject: [PATCH 3/4] linux-boot: Fix typo.>> * gnu/build/linux-boot.scm (mount-root-file-system): Fix typo.
LGTM!
Toggle quote (12 lines)> From b56aea9c62b015c8a8b48827f9587b1578c83af3 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Thu, 18 Jul 2019 04:59:25 +0900> Subject: [PATCH 4/4] linux-boot: Honor "rootflags" kernel argument.>> * gnu/build/linux-boot.scm (mount-root-file-system): Add the optional FLAGS> and OPTIONS arguments; and document them. Pass those to the `mount' calls.> (boot-system): Parse the "rootflags" kernel argument, and use it when calling> `mount-root-file-system'.> * doc/guix.texi (Initial RAM Disk): Document the use of the "rootflags"> argument.
We’ll have to wait for patch #1, but in the final patch set, it shouldprobably come before patch #1, no?
Thank you!
Ludo’.
M
M
Maxim Cournoyer wrote on 12 Feb 2020 09:47
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87k14sfaz7.fsf@gmail.com
Hello Ludovic!
My much delayed answer to your review are the attached, much improvedpatches.
The new test passes and I'm already using this on one of my system successfully.
Thanks for your patience,
Maxim
From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 17 Nov 2019 06:01:00 +0900Subject: [PATCH 1/8] gnu: tests: Reduce the time required to run the system tests.
When setting the GUIX_DEV_HACKS environment variable, the Guix package usedinside the instrumented VMs recycles the binaries already found in the Guixcheckout of the developer instead of rebuilding Guix from scratch. Thisbrings the time required for this component from 20+ minutes down to 2-3minutes on an X200 machine.
* gnu/packages/package-management.scm (current-guix/pre-built): New procedure.* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, whenGUIX_DEV_HACKS is defined.--- build-aux/run-system-tests.scm | 11 ++++- gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
Toggle diff (108 lines)diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scmindex b0cb3bd2bf..04b6fa29c3 100644--- a/build-aux/run-system-tests.scm+++ b/build-aux/run-system-tests.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -58,8 +59,16 @@ instance." ;; of tests to run in the usual way: ;; ;; make check-system TESTS=installed-os++ ;; When the GUIX_DEV_HACKS environment variable is defined, override the+ ;; package returned by `current-guix' with a flavor that saves recompiling+ ;; Guix from scratch and reuse the developer's checkout binaries. The+ ;; override "builds" about 20 times faster than the regular `current-guix'+ ;; package, which can help speed iterative development. (parameterize ((current-guix-package- (channel-instance->package instance)))+ (if (getenv "GUIX_DEV_HACKS")+ (current-guix/pre-built)+ (channel-instance->package instance)))) (match (getenv "TESTS") (#f (all-system-tests))diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scmindex 422d4f1959..bd2ed85189 100644--- a/gnu/packages/package-management.scm+++ b/gnu/packages/package-management.scm@@ -468,6 +468,72 @@ out) and returning a package that uses that as its 'source'." #:recursive? #t #:select? (force select?)))))))) +(define-public (current-guix/pre-built)+ "Similar to `current-guix', but with a modified build procedure that+reuses the existing byte compiled artifacts to save recompilation time."++ (let* ( ;; The `current-source-directory' macro doesn't work from the REPL.+ ;; For testing, you can replace it with a static string pointing to+ ;; your Guix checkout directory.+ (repository-root (delay (canonicalize-path+ (string-append (current-source-directory)+ "/../.."))))+ (select? (lambda (file stat)+ (match (basename file)+ ((or ".git"+ "configure" "autom4te.cache"+ "config.log" "config.status"+ "stamp-1" "stamp-2" "stamp-3" "stamp-4" "stamp-5"+ "stamp-h1" "stamp-vti"+ "Makefile" "Makefile.in" ".libs"+ ".deps" ".dirstamp"+ "test-tmp"+ ) #f)+ (_ #t)))))+ (package+ (inherit guix)+ (version (string-append (package-version guix) "+"))+ (source (local-file (force repository-root) "guix-current"+ #:recursive? #t+ #:select? select?))+ (arguments+ (substitute-keyword-arguments (package-arguments guix)+ ((#:phases phases)+ `(modify-phases ,phases+ ;; XXX: References to tools such as 'mkdir' and 'install' are+ ;; captured in Makefile.in when 'autoconf' is run. It'd be nicer+ ;; to find those at configuration time.+ (delete 'copy-bootstrap-guile)+ (delete 'check)+ (delete 'disable-failing-tests)+ (delete 'strip) ;can't strip .go files anyway+ (replace 'build+ (lambda _+ ;; Set the write permission bit on some files that need to be+ ;; touched.+ (chmod "nix" #o777)+ (for-each (lambda (f)+ (chmod f #o666))+ (cons* "guix-daemon"+ (find-files "." ".*\\.(a|o)$")))++ ;; The following prevent 'make install' from rebuilding the+ ;; daemon and the documentation.+ (invoke "make" "--touch" "info"+ ;; TODO: Currently we must rebuild the daemon as it+ ;; was linked against external dependencies that+ ;; depend on the provenance of the profile (or+ ;; environment) that was used to build it.++ ;; If we could query the provenance of any profile,+ ;; we could make this package inherit from the guix+ ;; inferior that was used to provide such+ ;; dependencies. The most reliable way would+ ;; probably be to record that provenance at build+ ;; time (as a make target).+ ;"guix-daemon"+ ))))))))))+ ;;; ;;; Other tools.-- 2.25.0
From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 12:57:29 -0500Subject: [PATCH 2/8] gnu: linux-boot: Ensure volatile root is mounted read-only.
* gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY ispresent among the root file system flags when VOLATILE-ROOT? is #t.--- gnu/build/linux-boot.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Toggle diff (21 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 3d40a7d05d..4fb711b8f2 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -362,12 +362,12 @@ the last argument of `mknod'." "Mount the root file system of type TYPE at device ROOT. If VOLATILE-ROOT? is true, mount ROOT read-only and make it an overlay with a writable tmpfs using the kernel built-in overlayfs. FLAGS and OPTIONS indicates the options to use-to mount ROOT."+to mount ROOT, and behave the same as for the `mount' procedure." (if volatile-root? (begin (mkdir-p "/real-root")- (mount root "/real-root" type MS_RDONLY options)+ (mount root "/real-root" type (logior MS_RDONLY flags) options) (mkdir-p "/rw-root") (mount "none" "/rw-root" "tmpfs") -- 2.25.0
From 870277ade6c20546566161adbe3e6f4a5c4368a8 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 23:56:45 -0500Subject: [PATCH 3/8] file-systems: Add a 'file-system-device->string' procedure.
* gnu/system/file-systems.scm (file-system-device->string): New procedure.* gnu/system.scm (bootable-kernel-arguments): Use it.* gnu/system/vm.scm (operating-system-uuid): Likewise.* guix/scripts/system.scm (display-system-generation): Likewise.--- gnu/system.scm | 15 +++++---------- gnu/system/file-systems.scm | 13 +++++++++++++ gnu/system/vm.scm | 8 +------- guix/scripts/system.scm | 7 +------ 4 files changed, 20 insertions(+), 23 deletions(-)
Toggle diff (96 lines)diff --git a/gnu/system.scm b/gnu/system.scmindex 01baa248a2..2e6d03272d 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -142,16 +142,11 @@ (define (bootable-kernel-arguments system root-device) "Return a list of kernel arguments (gexps) to boot SYSTEM from ROOT-DEVICE." (list (string-append "--root="- (cond ((uuid? root-device)-- ;; Note: Always use the DCE format because that's- ;; what (gnu build linux-boot) expects for the- ;; '--root' kernel command-line option.- (uuid->string (uuid-bytevector root-device)- 'dce))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else root-device)))+ ;; Note: Always use the DCE format because that's what+ ;; (gnu build linux-boot) expects for the '--root'+ ;; kernel command-line option.+ (file-system-device->string root-device+ #:uuid-type 'dce)) #~(string-append "--system=" #$system) #~(string-append "--load=" #$system "/boot"))) diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex d47a514b66..70a6febe3d 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -30,6 +30,7 @@ #:export (file-system file-system? file-system-device+ file-system-device->string file-system-title ;deprecated file-system-mount-point file-system-type@@ -235,6 +236,18 @@ where both FILE1 and FILE2 are absolute file name. For example: (() #f))))))) +(define* (file-system-device->string device #:key (uuid-type 'dce))+ "Return the string representations of the DEVICE field of a <file-system>+record. When the device is a UUID, its representation is chosen depening on+UUID-TYPE, a symbol such as 'dce or 'iso9660."+ (match device+ ((? file-system-label?)+ (file-system-label->string device))+ ((? uuid?)+ (uuid->string device))+ ((? string?)+ device)))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/gnu/system/vm.scm b/gnu/system/vm.scmindex 81b2e06ba2..03a511cdde 100644--- a/gnu/system/vm.scm+++ b/gnu/system/vm.scm@@ -609,13 +609,7 @@ TYPE (one of 'iso9660 or 'dce). Return a UUID object." (let ((device (file-system-device fs))) (list (file-system-mount-point fs) (file-system-type fs)- (cond ((file-system-label? device)- (file-system-label->string device))- ((uuid? device)- (uuid->string device))- ((string? device)- device)- (else #f))+ (file-system-device->string device) (file-system-options fs)))) (if (eq? type 'iso9660)diff --git a/guix/scripts/system.scm b/guix/scripts/system.scmindex e69a3b6c97..b0386a1392 100644--- a/guix/scripts/system.scm+++ b/guix/scripts/system.scm@@ -517,12 +517,7 @@ list of services." (cond ((uuid? root-device) 0) ((file-system-label? root-device) 1) (else 2))- (cond ((uuid? root-device)- (uuid->string root-device))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else- root-device)))+ (file-system-device->string root-device)) (format #t (G_ " kernel: ~a~%") kernel) -- 2.25.0
From 347cccca292119104383aa7116b5eb7473d8a51b Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:00:06 -0500Subject: [PATCH 4/8] gnu: linux-boot: Refactor boot-system.
The --root option can now be omitted, and inferred from the root file systemdeclaration instead.
* gnu/build/linux-boot.scm (boot-system): Remove nested definitions forroot-fs-type, root-fs-flags and root-fs-options, and bind those inside thelet* instead. Make "--root" take precendence over the device field stringrepresentation of the root file system.* doc/guix.texi (Initial RAM Disk): Document that "--root" can be leftunspecified.--- doc/guix.texi | 7 ++++--- gnu/build/linux-boot.scm | 42 +++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 25 deletions(-)
Toggle diff (87 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 42d7cfa2e8..85cfabc2f3 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25917,9 +25917,10 @@ service activation programs and then spawns the GNU@tie{}Shepherd, the initialization system. @item --root=@var{root}-Mount @var{root} as the root file system. @var{root} can be a-device name like @code{/dev/sda1}, a file system label, or a file system-UUID.+Mount @var{root} as the root file system. @var{root} can be a device+name like @code{/dev/sda1}, a file system label, or a file system UUID.+When unspecified, the device name from the root file system of the+operating system declaration is used. @item --system=@var{system} Have @file{/run/booted-system} and @file{/run/current-system} point todiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 4fb711b8f2..28697e7bbf 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -467,26 +467,6 @@ upon error." (define (root-mount-point? fs) (string=? (file-system-mount-point fs) "/")) - (define root-fs-type- (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-type fs)))- mounts)- "ext4"))-- (define root-fs-flags- (mount-flags->bit-mask (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-flags fs)))- mounts)- '())))-- (define root-fs-options- (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-options fs)))- mounts))- (display "Welcome, this is GNU's early boot Guile.\n") (display "Use '--repl' for an initrd REPL.\n\n") @@ -495,7 +475,25 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root-fs (find root-mount-point? mounts))+ (root-fs-type (or (and=> root-fs file-system-type)+ "ext4"))+ (root-device (and=> root-fs file-system-device))+ (root-device-str (and=> root-device file-system-device->string))+ ;; --root takes precedence over the 'device' field of the root+ ;; <file-system> record.+ (root (or (find-long-option "--root" args)+ root-device-str))+ (root-fs-flags (mount-flags->bit-mask+ (or (and=> root-fs file-system-flags)+ '())))+ (root-fs-options (if root-fs+ (file-system-options root-fs)+ '()))+ (root-options (if (null? root-fs-options)+ #f+ (file-system-options->str+ root-fs-options)))) (when (member "--repl" args) (start-repl))@@ -541,7 +539,7 @@ upon error." root-fs-type #:volatile-root? volatile-root? #:flags root-fs-flags- #:options root-fs-options))+ #:options root-options)) (mount "none" "/root" "tmpfs")) ;; Mount the specified file systems.-- 2.25.0
From 38286c910480a7102f9ae52c731eeea363f567f2 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 25 Sep 2019 22:43:41 +0900Subject: [PATCH 5/8] file-systems: Represent the file system options as an alist.
This allows accessing the parameter values easily, without having to parse astring.
* gnu/system/file-systems.scm (<file-system>): Update the default value of theOPTIONS field, doc.(%file-system-options): Field accessor renamed from `file-system-options'.(file-system-options, file-system-options->string): New procedures.* gnu/build/file-systems.scm (mount-file-system): Adapt.* gnu/services/base.scm (file-system->fstab-entry): Likewise.* tests/file-systems.scm: New tests.* doc/guix.texi (File Systems): Document the modified default value of the'file-system-options' field.--- doc/guix.texi | 11 ++++++----- gnu/build/file-systems.scm | 15 +++++++++------ gnu/services/base.scm | 35 +++++++++++++++++++---------------- gnu/system/file-systems.scm | 35 +++++++++++++++++++++++++++++++++-- tests/file-systems.scm | 24 ++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 29 deletions(-)
Toggle diff (201 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 85cfabc2f3..5d526b1aee 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11405,11 +11405,12 @@ update time on the in-memory version of the file inode), and @xref{Mount-Unmount-Remount,,, libc, The GNU C Library Reference Manual}, for more information on these flags. -@item @code{options} (default: @code{#f})-This is either @code{#f}, or a string denoting mount options passed to the-file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library-Reference Manual}, for details and run @command{man 8 mount} for options for-various file systems.+@item @code{options} (default: @code{'()})+A list of parameters and/or of pairs of parameter name and values, as+strings. Those represent the mount options that are passed to the file+system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library+Reference Manual}, for details and run @command{man 8 mount} for options+for various file systems. @item @code{mount?} (default: @code{#t}) This value indicates whether to automatically mount the file system whendiff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scmindex ee6375515f..cfa3898f83 100644--- a/gnu/build/file-systems.scm+++ b/gnu/build/file-systems.scm@@ -662,12 +662,15 @@ corresponds to the symbols listed in FLAGS." (if options (string-append "," options) "")))))- (let ((type (file-system-type fs))- (options (file-system-options fs))- (source (canonicalize-device-spec (file-system-device fs)))- (mount-point (string-append root "/"- (file-system-mount-point fs)))- (flags (mount-flags->bit-mask (file-system-flags fs))))+ (let* ((type (file-system-type fs))+ (fs-options (file-system-options fs))+ (options (if (null? fs-options)+ #f+ (file-system-options->string fs-options)))+ (source (canonicalize-device-spec (file-system-device fs)))+ (mount-point (string-append root "/"+ (file-system-mount-point fs)))+ (flags (mount-flags->bit-mask (file-system-flags fs)))) (when (file-system-check? fs) (check-file-system source type)) diff --git a/gnu/services/base.scm b/gnu/services/base.scmindex 0c154d1c4e..6104b47870 100644--- a/gnu/services/base.scm+++ b/gnu/services/base.scm@@ -313,22 +313,25 @@ seconds after @code{SIGTERM} has been sent are terminated with (define (file-system->fstab-entry file-system) "Return a @file{/etc/fstab} entry for @var{file-system}."- (string-append (match (file-system-device file-system)- ((? file-system-label? label)- (string-append "LABEL="- (file-system-label->string label)))- ((? uuid? uuid)- (string-append "UUID=" (uuid->string uuid)))- ((? string? device)- device))- "\t"- (file-system-mount-point file-system) "\t"- (file-system-type file-system) "\t"- (or (file-system-options file-system) "defaults") "\t"-- ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we- ;; don't have anything sensible to put in there.- ))+ (let ((options (file-system-options file-system)))+ (string-append (match (file-system-device file-system)+ ((? file-system-label? label)+ (string-append "LABEL="+ (file-system-label->string label)))+ ((? uuid? uuid)+ (string-append "UUID=" (uuid->string uuid)))+ ((? string? device)+ device))+ "\t"+ (file-system-mount-point file-system) "\t"+ (file-system-type file-system) "\t"+ (if (null? options)+ "defaults"+ (file-system-options->string options)) "\t"++ ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we+ ;; don't have anything sensible to put in there.+ ))) (define (file-systems->fstab file-systems) "Return a @file{/etc} entry for an @file{fstab} describingdiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 70a6febe3d..eff89f146c 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -37,6 +38,7 @@ file-system-needed-for-boot? file-system-flags file-system-options+ file-system-options->string file-system-mount? file-system-check? file-system-create-mount-point?@@ -97,8 +99,8 @@ (type file-system-type) ; string (flags file-system-flags ; list of symbols (default '()))- (options file-system-options ; string or #f- (default #f))+ (options %file-system-options ; list of strings and/or+ (default '())) ; pair of strings (mount? file-system-mount? ; Boolean (default #t)) (needed-for-boot? %file-system-needed-for-boot? ; Boolean@@ -248,6 +250,35 @@ UUID-TYPE, a symbol such as 'dce or 'iso9660." ((? string?) device))) +(define (file-system-options fs)+ "Return the options of a <file-system> record, as a list of options or+option/value pairs."++ ;; Support the deprecated options format (a string).+ (define (options-string->options-list str)+ (let ((option-list (string-split str #\,)))+ (map (lambda (param)+ (if (string-contains param "=")+ (apply cons (string-split param #\=))+ param))+ option-list)))++ (let ((fs-options (%file-system-options fs)))+ (if (string? fs-options)+ (options-string->options-list fs-options)+ fs-options)))++(define (file-system-options->string options)+ "Return the string representation of the OPTIONS field of a <file-system>+record"+ (string-join (map (match-lambda+ ((key . value)+ (string-append key "=" value))+ (key+ key))+ options)+ ","))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 4c28d0ebc5..b9f4f50aad 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -64,4 +65,27 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(define %fs-with-deprecated-options-string+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (type "btrfs")+ (options "autodefrag,subvol=home,compress=lzo")))++(define %fs+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/root")+ (type "btrfs")+ (options '("autodefrag" ("subvol" . "root") ("compress" . "lzo")))))++(test-equal "<file-system> options given as a string (deprecated)"+ '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))+ (file-system-options %fs-with-deprecated-options-string))++(test-equal "<file-system> options conversion to string"+ "autodefrag,subvol=root,compress=lzo"+ (file-system-options->string+ (file-system-options %fs)))+ (test-end)-- 2.25.0
From de7043998f2a2877f47e7952a435b711a0cbe9b5 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:14:36 -0500Subject: [PATCH 6/8] gnu: linux-boot: Honor the "--root-options" kernel argument.
* gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernelargument, and use it when calling `mount-root-file-system'. Update doc.* doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options"argument.--- doc/guix.texi | 10 ++++++++++ gnu/build/linux-boot.scm | 15 ++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-)
Toggle diff (63 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 5d526b1aee..d6bfbd7b55 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @command{modprobe} command must be a comma-separated list of module names---e.g., @code{usbkbd,9pnet}. +@item --root-options=@var{options}@dots{}+@cindex mount options for the root file system, passed to initrd+@cindex rootflags, initrd+@cindex root-options, initrd+This argument allows passing one or multiple file system specific mount+options used by the initrd to mount the root file system. @var{options}+must be a comma-separated list of option names or option-value pairs.+When unspecified, the value of the options field of the root file system+of the operating system declaration is used.+ @item --repl Start a read-eval-print loop (REPL) from the initial RAM disk before it tries to load kernel modules and to mount the root file system. Ourdiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 28697e7bbf..f65e942ebc 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -2,6 +2,7 @@ ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Guillaume Le Vaillant <glv@posteo.net>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE with 'loadkeys' (if KEYMAP-FILE is true), then setting up QEMU guest networking if QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file systems specified in MOUNTS, and finally booting into the new root if any. The initrd-supports kernel command-line options '--load', '--root', and '--repl'.+supports kernel command-line options '--load', '--root', '--root-options' and+'--repl'. Mount the root file system, specified by the '--root' command-line argument, if any.@@ -490,10 +492,13 @@ upon error." (root-fs-options (if root-fs (file-system-options root-fs) '()))- (root-options (if (null? root-fs-options)- #f- (file-system-options->str- root-fs-options))))+ ;; --root-options takes precedence over the 'options' field of the+ ;; root <file-system> record.+ (root-options (or (find-long-option "--root-options" args)+ (if (null? root-fs-options)+ #f+ (file-system-options->string+ root-fs-options))))) (when (member "--repl" args) (start-repl))-- 2.25.0
From 549d585266e32cf413ae0511edd315f615f0c3a9 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:27:19 -0500Subject: [PATCH 7/8] gnu: linux-boot: Filter out file system independent options.
This fixes an issue where options such as "defaults", which are understood bythe command line program "mount", are not understood by the system call of thesame name, which is used in the initial RAM disk.
* gnu/system/file-systems.scm (%file-system-independent-mount-options): New variable.(file-system-independent-mount-option?): New predicate.* gnu/build/linux-boot.scm (boot-system): Use the above predicate to filterout system independent mount options.--- gnu/build/linux-boot.scm | 3 ++- gnu/system/file-systems.scm | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-)
Toggle diff (49 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex f65e942ebc..8e55797549 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -490,7 +490,8 @@ upon error." (or (and=> root-fs file-system-flags) '()))) (root-fs-options (if root-fs- (file-system-options root-fs)+ (remove file-system-independent-mount-option?+ (file-system-options root-fs)) '())) ;; --root-options takes precedence over the 'options' field of the ;; root <file-system> record.diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex eff89f146c..2dcf41ba57 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -46,6 +46,7 @@ file-system-location file-system-type-predicate+ file-system-independent-mount-option? file-system-label file-system-label?@@ -563,4 +564,20 @@ system has the given TYPE." (lambda (fs) (string=? (file-system-type fs) type))) +(define %file-system-independent-mount-options+ ;; Taken from 'man 8 mount'.+ '("async" "atime" "auto" "noatime" "noauto" "context" "defaults" "dev" "nodev"+ "diratime" "nodiratime" "dirsync" "exec" "noexec" "group" "iversion"+ "noiversion" "mand" "nomand" "_netdev" "nofail" "relatime" "norelatime"+ "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid"+ "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "users"))++(define (file-system-independent-mount-option? option)+ "Predicate to check if a <file-system> option is file system independent."+ (let ((option-name (if (pair? option)+ (car option)+ option)))+ (or (string-prefix-ci? "x-" option-name)+ (member option-name %file-system-independent-mount-options))))+ ;;; file-systems.scm ends here-- 2.25.0
M
M
Maxim Cournoyer wrote on 13 Feb 2020 21:27
Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87lfp6b5cs.fsf_-_@gmail.com
I've fixed a few problems I've found with more extensive testing.
Attached is the version 2 of the patch series.
From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 17 Nov 2019 06:01:00 +0900Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the system tests.
When setting the GUIX_DEV_HACKS environment variable, the Guix package usedinside the instrumented VMs recycles the binaries already found in the Guixcheckout of the developer instead of rebuilding Guix from scratch. Thisbrings the time required for this component from 20+ minutes down to 2-3minutes on an X200 machine.
* gnu/packages/package-management.scm (current-guix/pre-built): New procedure.* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, whenGUIX_DEV_HACKS is defined.--- build-aux/run-system-tests.scm | 11 ++++- gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
Toggle diff (108 lines)diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scmindex b0cb3bd2bf..04b6fa29c3 100644--- a/build-aux/run-system-tests.scm+++ b/build-aux/run-system-tests.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -58,8 +59,16 @@ instance." ;; of tests to run in the usual way: ;; ;; make check-system TESTS=installed-os++ ;; When the GUIX_DEV_HACKS environment variable is defined, override the+ ;; package returned by `current-guix' with a flavor that saves recompiling+ ;; Guix from scratch and reuse the developer's checkout binaries. The+ ;; override "builds" about 20 times faster than the regular `current-guix'+ ;; package, which can help speed iterative development. (parameterize ((current-guix-package- (channel-instance->package instance)))+ (if (getenv "GUIX_DEV_HACKS")+ (current-guix/pre-built)+ (channel-instance->package instance)))) (match (getenv "TESTS") (#f (all-system-tests))diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scmindex 422d4f1959..bd2ed85189 100644--- a/gnu/packages/package-management.scm+++ b/gnu/packages/package-management.scm@@ -468,6 +468,72 @@ out) and returning a package that uses that as its 'source'." #:recursive? #t #:select? (force select?)))))))) +(define-public (current-guix/pre-built)+ "Similar to `current-guix', but with a modified build procedure that+reuses the existing byte compiled artifacts to save recompilation time."++ (let* ( ;; The `current-source-directory' macro doesn't work from the REPL.+ ;; For testing, you can replace it with a static string pointing to+ ;; your Guix checkout directory.+ (repository-root (delay (canonicalize-path+ (string-append (current-source-directory)+ "/../.."))))+ (select? (lambda (file stat)+ (match (basename file)+ ((or ".git"+ "configure" "autom4te.cache"+ "config.log" "config.status"+ "stamp-1" "stamp-2" "stamp-3" "stamp-4" "stamp-5"+ "stamp-h1" "stamp-vti"+ "Makefile" "Makefile.in" ".libs"+ ".deps" ".dirstamp"+ "test-tmp"+ ) #f)+ (_ #t)))))+ (package+ (inherit guix)+ (version (string-append (package-version guix) "+"))+ (source (local-file (force repository-root) "guix-current"+ #:recursive? #t+ #:select? select?))+ (arguments+ (substitute-keyword-arguments (package-arguments guix)+ ((#:phases phases)+ `(modify-phases ,phases+ ;; XXX: References to tools such as 'mkdir' and 'install' are+ ;; captured in Makefile.in when 'autoconf' is run. It'd be nicer+ ;; to find those at configuration time.+ (delete 'copy-bootstrap-guile)+ (delete 'check)+ (delete 'disable-failing-tests)+ (delete 'strip) ;can't strip .go files anyway+ (replace 'build+ (lambda _+ ;; Set the write permission bit on some files that need to be+ ;; touched.+ (chmod "nix" #o777)+ (for-each (lambda (f)+ (chmod f #o666))+ (cons* "guix-daemon"+ (find-files "." ".*\\.(a|o)$")))++ ;; The following prevent 'make install' from rebuilding the+ ;; daemon and the documentation.+ (invoke "make" "--touch" "info"+ ;; TODO: Currently we must rebuild the daemon as it+ ;; was linked against external dependencies that+ ;; depend on the provenance of the profile (or+ ;; environment) that was used to build it.++ ;; If we could query the provenance of any profile,+ ;; we could make this package inherit from the guix+ ;; inferior that was used to provide such+ ;; dependencies. The most reliable way would+ ;; probably be to record that provenance at build+ ;; time (as a make target).+ ;"guix-daemon"+ ))))))))))+ ;;; ;;; Other tools.-- 2.23.0
From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 12:57:29 -0500Subject: [PATCH 2/9] gnu: linux-boot: Ensure volatile root is mounted read-only.
* gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY ispresent among the root file system flags when VOLATILE-ROOT? is #t.--- gnu/build/linux-boot.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Toggle diff (21 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 3d40a7d05d..4fb711b8f2 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -362,12 +362,12 @@ the last argument of `mknod'." "Mount the root file system of type TYPE at device ROOT. If VOLATILE-ROOT? is true, mount ROOT read-only and make it an overlay with a writable tmpfs using the kernel built-in overlayfs. FLAGS and OPTIONS indicates the options to use-to mount ROOT."+to mount ROOT, and behave the same as for the `mount' procedure." (if volatile-root? (begin (mkdir-p "/real-root")- (mount root "/real-root" type MS_RDONLY options)+ (mount root "/real-root" type (logior MS_RDONLY flags) options) (mkdir-p "/rw-root") (mount "none" "/rw-root" "tmpfs") -- 2.23.0
From e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 23:56:45 -0500Subject: [PATCH 3/9] file-systems: Add a 'file-system-device->string' procedure.
* gnu/system/file-systems.scm (file-system-device->string): New procedure.* gnu/system.scm (bootable-kernel-arguments): Use it.* gnu/system/vm.scm (operating-system-uuid): Likewise.* guix/scripts/system.scm (display-system-generation): Likewise.--- gnu/system.scm | 15 +++++---------- gnu/system/file-systems.scm | 15 +++++++++++++++ gnu/system/vm.scm | 8 +------- guix/scripts/system.scm | 7 +------ 4 files changed, 22 insertions(+), 23 deletions(-)
Toggle diff (98 lines)diff --git a/gnu/system.scm b/gnu/system.scmindex 01baa248a2..2e6d03272d 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -142,16 +142,11 @@ (define (bootable-kernel-arguments system root-device) "Return a list of kernel arguments (gexps) to boot SYSTEM from ROOT-DEVICE." (list (string-append "--root="- (cond ((uuid? root-device)-- ;; Note: Always use the DCE format because that's- ;; what (gnu build linux-boot) expects for the- ;; '--root' kernel command-line option.- (uuid->string (uuid-bytevector root-device)- 'dce))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else root-device)))+ ;; Note: Always use the DCE format because that's what+ ;; (gnu build linux-boot) expects for the '--root'+ ;; kernel command-line option.+ (file-system-device->string root-device+ #:uuid-type 'dce)) #~(string-append "--system=" #$system) #~(string-append "--load=" #$system "/boot"))) diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex d47a514b66..fc383d8a5a 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -30,6 +30,7 @@ #:export (file-system file-system? file-system-device+ file-system-device->string file-system-title ;deprecated file-system-mount-point file-system-type@@ -235,6 +236,20 @@ where both FILE1 and FILE2 are absolute file name. For example: (() #f))))))) +(define* (file-system-device->string device #:key uuid-type)+ "Return the string representations of the DEVICE field of a <file-system>+record. When the device is a UUID, its representation is chosen depening on+UUID-TYPE, a symbol such as 'dce or 'iso9660."+ (match device+ ((? file-system-label?)+ (file-system-label->string device))+ ((? uuid?)+ (if uuid-type+ (uuid->string (uuid-bytevector device) uuid-type)+ (uuid->string device)))+ ((? string?)+ device)))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/gnu/system/vm.scm b/gnu/system/vm.scmindex 81b2e06ba2..03a511cdde 100644--- a/gnu/system/vm.scm+++ b/gnu/system/vm.scm@@ -609,13 +609,7 @@ TYPE (one of 'iso9660 or 'dce). Return a UUID object." (let ((device (file-system-device fs))) (list (file-system-mount-point fs) (file-system-type fs)- (cond ((file-system-label? device)- (file-system-label->string device))- ((uuid? device)- (uuid->string device))- ((string? device)- device)- (else #f))+ (file-system-device->string device) (file-system-options fs)))) (if (eq? type 'iso9660)diff --git a/guix/scripts/system.scm b/guix/scripts/system.scmindex e69a3b6c97..b0386a1392 100644--- a/guix/scripts/system.scm+++ b/guix/scripts/system.scm@@ -517,12 +517,7 @@ list of services." (cond ((uuid? root-device) 0) ((file-system-label? root-device) 1) (else 2))- (cond ((uuid? root-device)- (uuid->string root-device))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else- root-device)))+ (file-system-device->string root-device)) (format #t (G_ " kernel: ~a~%") kernel) -- 2.23.0
From 4f6e3955957beb5287e9d5a5d33b74725836e1ac Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:00:06 -0500Subject: [PATCH 4/9] gnu: linux-boot: Refactor boot-system.
The --root option can now be omitted, and inferred from the root file systemdeclaration instead.
* gnu/build/linux-boot.scm (boot-system): Remove nested definitions forroot-fs-type, root-fs-flags and root-fs-options, and bind those inside thelet* instead. Make "--root" take precendence over the device field stringrepresentation of the root file system.* doc/guix.texi (Initial RAM Disk): Document that "--root" can be leftunspecified.--- doc/guix.texi | 7 ++++--- gnu/build/linux-boot.scm | 42 +++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 25 deletions(-)
Toggle diff (87 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 42d7cfa2e8..85cfabc2f3 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25917,9 +25917,10 @@ service activation programs and then spawns the GNU@tie{}Shepherd, the initialization system. @item --root=@var{root}-Mount @var{root} as the root file system. @var{root} can be a-device name like @code{/dev/sda1}, a file system label, or a file system-UUID.+Mount @var{root} as the root file system. @var{root} can be a device+name like @code{/dev/sda1}, a file system label, or a file system UUID.+When unspecified, the device name from the root file system of the+operating system declaration is used. @item --system=@var{system} Have @file{/run/booted-system} and @file{/run/current-system} point todiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 4fb711b8f2..28697e7bbf 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -467,26 +467,6 @@ upon error." (define (root-mount-point? fs) (string=? (file-system-mount-point fs) "/")) - (define root-fs-type- (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-type fs)))- mounts)- "ext4"))-- (define root-fs-flags- (mount-flags->bit-mask (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-flags fs)))- mounts)- '())))-- (define root-fs-options- (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-options fs)))- mounts))- (display "Welcome, this is GNU's early boot Guile.\n") (display "Use '--repl' for an initrd REPL.\n\n") @@ -495,7 +475,25 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root-fs (find root-mount-point? mounts))+ (root-fs-type (or (and=> root-fs file-system-type)+ "ext4"))+ (root-device (and=> root-fs file-system-device))+ (root-device-str (and=> root-device file-system-device->string))+ ;; --root takes precedence over the 'device' field of the root+ ;; <file-system> record.+ (root (or (find-long-option "--root" args)+ root-device-str))+ (root-fs-flags (mount-flags->bit-mask+ (or (and=> root-fs file-system-flags)+ '())))+ (root-fs-options (if root-fs+ (file-system-options root-fs)+ '()))+ (root-options (if (null? root-fs-options)+ #f+ (file-system-options->str+ root-fs-options)))) (when (member "--repl" args) (start-repl))@@ -541,7 +539,7 @@ upon error." root-fs-type #:volatile-root? volatile-root? #:flags root-fs-flags- #:options root-fs-options))+ #:options root-options)) (mount "none" "/root" "tmpfs")) ;; Mount the specified file systems.-- 2.23.0
From af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 25 Sep 2019 22:43:41 +0900Subject: [PATCH 5/9] file-systems: Represent the file system options as an alist.
This allows accessing the parameter values easily, without having to parse astring.
* gnu/system/file-systems.scm (<file-system>): Update the default value of theOPTIONS field, doc.(%file-system-options): Field accessor renamed from `file-system-options'.(file-system-options, file-system-options->string): New procedures.* gnu/build/file-systems.scm (mount-file-system): Adapt.* gnu/services/base.scm (file-system->fstab-entry): Likewise.* tests/file-systems.scm: New tests.* doc/guix.texi (File Systems): Document the modified default value of the'file-system-options' field.--- doc/guix.texi | 11 ++++++----- gnu/build/file-systems.scm | 15 +++++++++------ gnu/services/base.scm | 35 +++++++++++++++++++---------------- gnu/system/file-systems.scm | 35 +++++++++++++++++++++++++++++++++-- tests/file-systems.scm | 24 ++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 29 deletions(-)
Toggle diff (201 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 85cfabc2f3..5d526b1aee 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11405,11 +11405,12 @@ update time on the in-memory version of the file inode), and @xref{Mount-Unmount-Remount,,, libc, The GNU C Library Reference Manual}, for more information on these flags. -@item @code{options} (default: @code{#f})-This is either @code{#f}, or a string denoting mount options passed to the-file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library-Reference Manual}, for details and run @command{man 8 mount} for options for-various file systems.+@item @code{options} (default: @code{'()})+A list of parameters and/or of pairs of parameter name and values, as+strings. Those represent the mount options that are passed to the file+system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library+Reference Manual}, for details and run @command{man 8 mount} for options+for various file systems. @item @code{mount?} (default: @code{#t}) This value indicates whether to automatically mount the file system whendiff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scmindex ee6375515f..cfa3898f83 100644--- a/gnu/build/file-systems.scm+++ b/gnu/build/file-systems.scm@@ -662,12 +662,15 @@ corresponds to the symbols listed in FLAGS." (if options (string-append "," options) "")))))- (let ((type (file-system-type fs))- (options (file-system-options fs))- (source (canonicalize-device-spec (file-system-device fs)))- (mount-point (string-append root "/"- (file-system-mount-point fs)))- (flags (mount-flags->bit-mask (file-system-flags fs))))+ (let* ((type (file-system-type fs))+ (fs-options (file-system-options fs))+ (options (if (null? fs-options)+ #f+ (file-system-options->string fs-options)))+ (source (canonicalize-device-spec (file-system-device fs)))+ (mount-point (string-append root "/"+ (file-system-mount-point fs)))+ (flags (mount-flags->bit-mask (file-system-flags fs)))) (when (file-system-check? fs) (check-file-system source type)) diff --git a/gnu/services/base.scm b/gnu/services/base.scmindex 0c154d1c4e..6104b47870 100644--- a/gnu/services/base.scm+++ b/gnu/services/base.scm@@ -313,22 +313,25 @@ seconds after @code{SIGTERM} has been sent are terminated with (define (file-system->fstab-entry file-system) "Return a @file{/etc/fstab} entry for @var{file-system}."- (string-append (match (file-system-device file-system)- ((? file-system-label? label)- (string-append "LABEL="- (file-system-label->string label)))- ((? uuid? uuid)- (string-append "UUID=" (uuid->string uuid)))- ((? string? device)- device))- "\t"- (file-system-mount-point file-system) "\t"- (file-system-type file-system) "\t"- (or (file-system-options file-system) "defaults") "\t"-- ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we- ;; don't have anything sensible to put in there.- ))+ (let ((options (file-system-options file-system)))+ (string-append (match (file-system-device file-system)+ ((? file-system-label? label)+ (string-append "LABEL="+ (file-system-label->string label)))+ ((? uuid? uuid)+ (string-append "UUID=" (uuid->string uuid)))+ ((? string? device)+ device))+ "\t"+ (file-system-mount-point file-system) "\t"+ (file-system-type file-system) "\t"+ (if (null? options)+ "defaults"+ (file-system-options->string options)) "\t"++ ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we+ ;; don't have anything sensible to put in there.+ ))) (define (file-systems->fstab file-systems) "Return a @file{/etc} entry for an @file{fstab} describingdiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex fc383d8a5a..6dc0e6814e 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -37,6 +38,7 @@ file-system-needed-for-boot? file-system-flags file-system-options+ file-system-options->string file-system-mount? file-system-check? file-system-create-mount-point?@@ -97,8 +99,8 @@ (type file-system-type) ; string (flags file-system-flags ; list of symbols (default '()))- (options file-system-options ; string or #f- (default #f))+ (options %file-system-options ; list of strings and/or+ (default '())) ; pair of strings (mount? file-system-mount? ; Boolean (default #t)) (needed-for-boot? %file-system-needed-for-boot? ; Boolean@@ -250,6 +252,35 @@ UUID-TYPE, a symbol such as 'dce or 'iso9660." ((? string?) device))) +(define (file-system-options fs)+ "Return the options of a <file-system> record, as a list of options or+option/value pairs."++ ;; Support the deprecated options format (a string).+ (define (options-string->options-list str)+ (let ((option-list (string-split str #\,)))+ (map (lambda (param)+ (if (string-contains param "=")+ (apply cons (string-split param #\=))+ param))+ option-list)))++ (let ((fs-options (%file-system-options fs)))+ (if (string? fs-options)+ (options-string->options-list fs-options)+ fs-options)))++(define (file-system-options->string options)+ "Return the string representation of the OPTIONS field of a <file-system>+record"+ (string-join (map (match-lambda+ ((key . value)+ (string-append key "=" value))+ (key+ key))+ options)+ ","))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 4c28d0ebc5..b9f4f50aad 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -64,4 +65,27 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(define %fs-with-deprecated-options-string+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (type "btrfs")+ (options "autodefrag,subvol=home,compress=lzo")))++(define %fs+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/root")+ (type "btrfs")+ (options '("autodefrag" ("subvol" . "root") ("compress" . "lzo")))))++(test-equal "<file-system> options given as a string (deprecated)"+ '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))+ (file-system-options %fs-with-deprecated-options-string))++(test-equal "<file-system> options conversion to string"+ "autodefrag,subvol=root,compress=lzo"+ (file-system-options->string+ (file-system-options %fs)))+ (test-end)-- 2.23.0
From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:14:36 -0500Subject: [PATCH 6/9] gnu: linux-boot: Honor the "--root-options" kernel argument.
* gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernelargument, and use it when calling `mount-root-file-system'. Update doc.* doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options"argument.--- doc/guix.texi | 10 ++++++++++ gnu/build/linux-boot.scm | 15 ++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-)
Toggle diff (63 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 5d526b1aee..d6bfbd7b55 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @command{modprobe} command must be a comma-separated list of module names---e.g., @code{usbkbd,9pnet}. +@item --root-options=@var{options}@dots{}+@cindex mount options for the root file system, passed to initrd+@cindex rootflags, initrd+@cindex root-options, initrd+This argument allows passing one or multiple file system specific mount+options used by the initrd to mount the root file system. @var{options}+must be a comma-separated list of option names or option-value pairs.+When unspecified, the value of the options field of the root file system+of the operating system declaration is used.+ @item --repl Start a read-eval-print loop (REPL) from the initial RAM disk before it tries to load kernel modules and to mount the root file system. Ourdiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 28697e7bbf..f65e942ebc 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -2,6 +2,7 @@ ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Guillaume Le Vaillant <glv@posteo.net>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE with 'loadkeys' (if KEYMAP-FILE is true), then setting up QEMU guest networking if QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file systems specified in MOUNTS, and finally booting into the new root if any. The initrd-supports kernel command-line options '--load', '--root', and '--repl'.+supports kernel command-line options '--load', '--root', '--root-options' and+'--repl'. Mount the root file system, specified by the '--root' command-line argument, if any.@@ -490,10 +492,13 @@ upon error." (root-fs-options (if root-fs (file-system-options root-fs) '()))- (root-options (if (null? root-fs-options)- #f- (file-system-options->str- root-fs-options))))+ ;; --root-options takes precedence over the 'options' field of the+ ;; root <file-system> record.+ (root-options (or (find-long-option "--root-options" args)+ (if (null? root-fs-options)+ #f+ (file-system-options->string+ root-fs-options))))) (when (member "--repl" args) (start-repl))-- 2.23.0
From cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:27:19 -0500Subject: [PATCH 7/9] gnu: linux-boot: Filter out file system independent options.
This fixes an issue where options such as "defaults", which are understood bythe command line program "mount", are not understood by the system call of thesame name, which is used in the initial RAM disk.
* gnu/system/file-systems.scm (%file-system-independent-mount-options): New variable.(file-system-independent-mount-option?): New predicate.* gnu/build/linux-boot.scm (boot-system): Use the above predicate to filterout system independent mount options.--- gnu/build/linux-boot.scm | 3 ++- gnu/system/file-systems.scm | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-)
Toggle diff (49 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex f65e942ebc..8e55797549 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -490,7 +490,8 @@ upon error." (or (and=> root-fs file-system-flags) '()))) (root-fs-options (if root-fs- (file-system-options root-fs)+ (remove file-system-independent-mount-option?+ (file-system-options root-fs)) '())) ;; --root-options takes precedence over the 'options' field of the ;; root <file-system> record.diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 6dc0e6814e..2c3c159d04 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -46,6 +46,7 @@ file-system-location file-system-type-predicate+ file-system-independent-mount-option? file-system-label file-system-label?@@ -565,4 +566,20 @@ system has the given TYPE." (lambda (fs) (string=? (file-system-type fs) type))) +(define %file-system-independent-mount-options+ ;; Taken from 'man 8 mount'.+ '("async" "atime" "auto" "noatime" "noauto" "context" "defaults" "dev" "nodev"+ "diratime" "nodiratime" "dirsync" "exec" "noexec" "group" "iversion"+ "noiversion" "mand" "nomand" "_netdev" "nofail" "relatime" "norelatime"+ "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid"+ "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "users"))++(define (file-system-independent-mount-option? option)+ "Predicate to check if a <file-system> option is file system independent."+ (let ((option-name (if (pair? option)+ (car option)+ option)))+ (or (string-prefix-ci? "x-" option-name)+ (member option-name %file-system-independent-mount-options))))+ ;;; file-systems.scm ends here-- 2.23.0
From 6cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH 8/9] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (grub-configuration-file) [btrfs-subvolume-path]:New parameter. When it is defined, prepend its value to the kernel andinitrd file paths.* gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.* gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.* gnu/system/file-systems.scm (btrfs-subvolume?)(btrfs-store-subvolume-path): New procedures.* gnu/system.scm (operating-system-bootcfg): Specify the Btrfs subvolume pathof the GNU store to the `operating-system-bootcfg' procedure, using the newBTRFS-SUBVOLUME-PATH argument.* doc/guix.texi (File Systems): Add a Btrfs subsection to document the use ofsubvolumes. Document the new `properties' field of the `<file-system>'record.* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".--- doc/guix.texi | 114 +++++++++++++++++++++++++++++++++ gnu/bootloader/depthcharge.scm | 3 +- gnu/bootloader/extlinux.scm | 3 +- gnu/bootloader/grub.scm | 42 +++++++----- gnu/system.scm | 9 ++- gnu/system/file-systems.scm | 51 +++++++++++++++ gnu/tests/install.scm | 87 +++++++++++++++++++++++++ 7 files changed, 290 insertions(+), 19 deletions(-)
Toggle diff (464 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex d6bfbd7b55..f0956f965a 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and Another example is a file system that depends on a mapped device, for example for an encrypted partition (@pxref{Mapped Devices}).++@item @code{properties} (default: @code{'()})+This is a list of key-value pairs that can be used to specify properties+not captured by other fields. For example, the top level path of a+Btrfs subvolume within its Btrfs pool can be specified using the+@code{btrfs-subvolume-path} property (@pxref{Btrfs file system}).+ @end table @end deftp @@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems. This requires the @code{fuse.ko} kernel module to be loaded. @end defvr +@node Btrfs file system+@subsection Btrfs file system++The Btrfs has special features, such as subvolumes, that merit being+explained in more details. The following section attempts to cover+basic as well as complex uses of a Btrfs file system with the Guix+System.++In its simplest usage, a Btrfs file system can be described, for+example, by:++@lisp+(file-system+ (mount-point "/home")+ (type "btrfs")+ (device (file-system-label "my-home")))+@end lisp++The example below is more complex, as it makes use of a Btrfs+subvolume, named @code{rootfs}. The parent Btrfs file system is labeled+@code{my-btrfs-pool}, and is located on an encrypted device (hence the+dependency on @code{mapped-devices}):++@example+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options '("defaults" ("subvol" . "rootfs"))+ (dependencies mapped-devices))+@end example++Some bootloaders, for example GRUB, only mount a Btrfs partition at its+top level during the early boot, and rely on their configuration to+refer to the correct subvolume path within that top level. The+bootloaders operating in this way typically produce their configuration+on a running system where the Btrfs partitions are already mounted and+where the subvolume information is readily available. As an example,+@command{grub-mkconfig}, the configuration generator command shipped+with GRUB, reads @file{/proc/self/mountinfo} to determine the top-level+path of a subvolume.++The Guix System produces a bootloader configuration using the operating+system configuration as its sole input; it is therefore necessary to+extract the subvolume name on which @file{/gnu/store} lives (if any)+from that operating system configuration. To better illustrate,+consider a subvolume named 'rootfs' which contains the root file system+data. In such situation, the GRUB bootloader would only see the top+level of the root Btrfs partition, e.g.:++@example+/ (top level)+├── rootfs (subvolume directory)+ ├── gnu (normal directory)+ ├── store (normal directory)+[...]+@end example++Thus, the subvolume name must be prepended to the @file{/gnu/store} path+of the kernel and initrd binaries in the GRUB configuration in order for+those to be found.++The next example shows a nested hierarchy of subvolumes and+directories:++@example+/ (top level)+├── rootfs (subvolume)+ ├── gnu (normal directory)+ ├── store (subvolume)+[...]+@end example++This scenario would work without mounting the 'store' subvolume.+Mounting 'rootfs' is sufficient, since the subvolume name matches its+intended mount point in the file system hierarchy.++Finally, a more contrived example of nested subvolumes:++@example+/ (top level)+├── root-snapshots (subvolume)+ ├── root-current (subvolume)+ ├── guix-store (subvolume)+[...]+@end example++Here, the 'guix-store' module name doesn't match its intended mount+point, so it is necessary to mount it. The layout cannot simply be+described by the <file-system> record, so it is required to specify the+exact path at which the subvolume exists within the top level of its+parent file system. This can be achieved by attaching a+@code{btrfs-subvolume-path} property to the corresponding file system+record:++@lisp+(file-system+ ...+ (properties '((btrfs-subvolume-path+ . "/root-snapshots/root-current/guix-store"))))+@end lisp++The default behavior of Guix is to assume that a subvolume exists+directly at the root of the top volume hierarchy. When this is not the+case, the above property must be used for the system to boot correctly+when using a GRUB based bootloader.+ @node Mapped Devices @section Mapped Devices diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scmindex 58cc3f3932..0a50374bd9 100644--- a/gnu/bootloader/depthcharge.scm+++ b/gnu/bootloader/depthcharge.scm@@ -82,7 +82,8 @@ (define* (depthcharge-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) (match entries ((entry) (let ((kernel (menu-entry-linux entry))diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scmindex 5b4dd84965..6b5ff298e7 100644--- a/gnu/bootloader/extlinux.scm+++ b/gnu/bootloader/extlinux.scm@@ -28,7 +28,8 @@ (define* (extlinux-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) "Return the U-Boot configuration file corresponding to CONFIG, a <u-boot-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu entriesdiff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex b99f5fa4f4..c9794c35c2 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -4,6 +4,7 @@ ;;; Copyright © 2017 Leo Famulari <leo@famulari.name> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -327,35 +328,46 @@ code." (define* (grub-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ btrfs-subvolume-path) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu-entries corresponding to old generations of the system."+entries corresponding to old generations of the system. BTRFS-SUBVOLUME-PATH+may be used to specify on which subvolume a Btrfs root file system resides." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (arguments (menu-entry-linux-arguments entry))+ (kernel* (strip-mount-point+ device-mount-point (menu-entry-linux entry)))+ (initrd* (strip-mount-point+ device-mount-point (menu-entry-initrd entry)))+ (kernel (if btrfs-subvolume-path+ #~(string-append #$btrfs-subvolume-path #$kernel*)+ kernel*))+ (initrd (if btrfs-subvolume-path+ #~(string-append #$btrfs-subvolume-path #$initrd*)+ initrd*))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))- #~(format port "menuentry ~s {++ ;; When BTRFS-SUBVOLUME-PATH is defined, prepend it the kernel and+ ;; initrd paths, to allow booting from a Btrfs subvolume.+ #~(format port "menuentry ~s { ~a linux ~a ~a initrd ~a }~%"- #$label- #$(grub-root-search device kernel)- #$kernel (string-join (list #$@arguments))- #$initrd))))+ #$label+ #$(grub-root-search device kernel)+ #$kernel (string-join (list #$@arguments))+ #$initrd))) (define sugar (eye-candy config (menu-entry-device (first all-entries))diff --git a/gnu/system.scm b/gnu/system.scmindex 2e6d03272d..ebc8bf1db8 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -5,6 +5,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Meiyo Peng <meiyo.peng@gmail.com>+;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -992,19 +993,23 @@ entry." (define* (operating-system-bootcfg os #:optional (old-entries '())) "Return the bootloader configuration file for OS. Use OLD-ENTRIES, a list of <menu-entry>, to populate the \"old entries\" menu."- (let* ((root-fs (operating-system-root-file-system os))+ (let* ((file-systems (operating-system-file-systems os))+ (root-fs (operating-system-root-file-system os)) (root-device (file-system-device root-fs)) (params (operating-system-boot-parameters os root-device #:system-kernel-arguments? #t)) (entry (boot-parameters->menu-entry params)) (bootloader-conf (operating-system-bootloader os)))+ (define generate-config-file (bootloader-configuration-file-generator (bootloader-configuration-bootloader bootloader-conf))) (generate-config-file bootloader-conf (list entry)- #:old-entries old-entries)))+ #:old-entries old-entries+ #:btrfs-subvolume-path (btrfs-store-subvolume-path+ file-systems)))) (define* (operating-system-boot-parameters os root-device #:key system-kernel-arguments?)diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 2c3c159d04..daef1c9d72 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -21,7 +21,9 @@ #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9)+ #:use-module (srfi srfi-26) #:use-module (srfi srfi-9 gnu) #:use-module (guix records) #:use-module (gnu system uuid)@@ -44,9 +46,12 @@ file-system-create-mount-point? file-system-dependencies file-system-location+ file-system-properties file-system-type-predicate file-system-independent-mount-option?+ btrfs-subvolume?+ btrfs-store-subvolume-path file-system-label file-system-label?@@ -112,6 +117,8 @@ (default #f)) (dependencies file-system-dependencies ; list of <file-system> (default '())) ; or <mapped-device>+ (properties file-system-properties ; list of name-value pairs+ (default '())) (location file-system-location (default (current-source-location)) (innate)))@@ -582,4 +589,48 @@ system has the given TYPE." (or (string-prefix-ci? "x-" option-name) (member option-name %file-system-independent-mount-options)))) +(define (btrfs-subvolume? fs)+ "Predicate to check if FS, a file-system object, is a Btrfs subvolume."+ (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))+ (option-keys (map (match-lambda+ ((key . value) key)+ (key key))+ (file-system-options fs))))+ (find (cut string-prefix? "subvol" <>) option-keys)))++(define (btrfs-store-subvolume-path file-systems)+ "Return the subvolume path within the Btrfs top level onto which the store+is located. When the BTRFS-SUBVOLUME-PATH file system property is not set, it+is assumed that the store subvolume path is a located at the root of the top+level of the file system."++ (define (find-mount-point-fs mount-point file-systems)+ (find (lambda (fs)+ (string= mount-point (file-system-mount-point fs)))+ file-systems))++ ;; Find a subvolume mounted at either /gnu/store, /gnu, or /.+ (let loop ((mount-point (%store-prefix)))+ (let ((mount-point-fs (find-mount-point-fs mount-point file-systems)))+ (cond+ ((string-null? mount-point)+ #f) ;store is not on a Btrfs subvolume+ ((and=> mount-point-fs btrfs-subvolume?)+ (let* ((fs-options (file-system-options mount-point-fs))+ (subvolid (assoc-ref fs-options "subvolid"))+ (subvol (assoc-ref fs-options "subvol")))+ (or (assoc-ref (file-system-properties mount-point-fs)+ "btrfs-subvolume-path")+ (and=> subvol (cut string-append "/" <>))+ (error "The store is on a Btrfs subvolume, but the \+subvolume name is unknown.+Hint: Define the \"btrfs-subvolume-path\" file system property or+use the \"subvol\" Btrfs file system option."))))+ (else+ (loop+ (cond ((string-suffix? "/" mount-point)+ (string-drop-right mount-point 1))+ ((string-take mount-point+ (1+ (string-index-right mount-point #\/)))))))))))+ ;;; file-systems.scm ends herediff --git a/gnu/tests/install.scm b/gnu/tests/install.scmindex d475bda2c7..b32130c2f3 100644--- a/gnu/tests/install.scm+++ b/gnu/tests/install.scm@@ -44,6 +44,7 @@ %test-raid-root-os %test-encrypted-root-os %test-btrfs-root-os+ %test-btrfs-root-on-subvolume-os %test-jfs-root-os)) ;;; Commentary:@@ -811,6 +812,92 @@ build (current-guix) and then store a couple of full system images.") (command (qemu-command/writable-image image))) (run-basic-test %btrfs-root-os command "btrfs-root-os"))))) + +;;;+;;; Btrfs root file system on a subvolume.+;;;++(define-os-with-source (%btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source)+ ;; The OS we want to install.+ (use-modules (gnu) (gnu tests) (srfi srfi-1))++ (operating-system+ (host-name "hurd")+ (timezone "America/Montreal")+ (locale "en_US.UTF-8")+ (bootloader (bootloader-configuration+ (bootloader grub-bootloader)+ (target "/dev/vdb")))+ (kernel-arguments '("console=ttyS0"))+ (file-systems (cons* (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (options '(("subvol" . "rootfs")+ ("compress" . "zstd")))+ (type "btrfs"))+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (options '(("subvol" . "homefs")+ ("compress" . "lzo")))+ (type "btrfs"))+ %base-file-systems))+ (users (cons (user-account+ (name "charlie")+ (group "users")+ (supplementary-groups '("wheel" "audio" "video")))+ %base-user-accounts))+ (services (cons (service marionette-service-type+ (marionette-configuration+ (imported-modules '((gnu services herd)+ (guix combinators)))))+ %base-services))))++(define %btrfs-root-on-subvolume-installation-script+ ;; Shell script of a simple installation.+ "\+. /etc/profile+set -e -x+guix --version++export GUIX_BUILD_OPTIONS=--no-grafts+ls -l /run/current-system/gc-roots+parted --script /dev/vdb mklabel gpt \\+ mkpart primary ext2 1M 3M \\+ mkpart primary ext2 3M 2G \\+ set 1 boot on \\+ set 1 bios_grub on+mkfs.btrfs -L btrfs-pool /dev/vdb2+mount /dev/vdb2 /mnt+btrfs subvolume create /mnt/rootfs+btrfs subvolume create /mnt/homefs+herd start cow-store /mnt/rootfs+mkdir /mnt/rootfs/etc+cp /etc/target-config.scm /mnt/rootfs/etc/config.scm+guix system build /mnt/rootfs/etc/config.scm+guix system init /mnt/rootfs/etc/config.scm /mnt/rootfs --no-substitutes+sync+reboot\n")++(define %test-btrfs-root-on-subvolume-os+ (system-test+ (name "btrfs-root-on-subvolume-os")+ (description+ "Test basic functionality of an OS installed like one would do by hand.+This test is expensive in terms of CPU and storage usage since we need to+build (current-guix) and then store a couple of full system images.")+ (value+ (mlet* %store-monad+ ((image+ (run-install %btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source+ #:script+ %btrfs-root-on-subvolume-installation-script))+ (command (qemu-command/writable-image image)))+ (run-basic-test %btrfs-root-on-subvolume-os command+ "btrfs-root-on-subvolume-os")))))+ ;;; ;;; JFS root file system.-- 2.23.0
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl5FsSMACgkQEmDkZILmNWJF9g/+O6OPoFHKB/nuzm4PEpATEzzdFhpLbUXoq+pdUzybD+s+NFWgBmuLZjgGp3XC5gFOPoOKOMaENdk3k37iOmUb5CZ2648Y7oX92nkkY/JEEtMlH4p5+DGWB8f8jIQOzL6JPL8qXgcj4KbVPEN6l9aPogYGvTA5aAmRZOvO6sl1CHDkiaHZp8HlxOPp0qcUtoUT9MGXk7pZ9Q2sHbACgcWJESYM2UW2XPrnvhbp2uV24vMNryjBRoJVLYk8M1RjJzovEeNAOWeZ4I6cTMK7JuzgqJW/qDc575NtShvCKMbELRTR5YFs3cTnqHU4q4wcz2KpToNQsFnbtM9yg1rnsQ8enkvELVIo2aRwBTnFbLEOo7EtCRZBonOVaaAzvwQeugCECbGmZSBcpbU287EPyHFvnaNZNUXjS8rXHpc2phKLx/1SgTbVNEqNG/9s1BTqNu65aouBTCz5NawPfqp5kaXXdQWoj+V/wUIfGHaP97jHhrlPFT5M/P3ANXP+50KIVstTeVj7dDftKIQ+Ljhk69zj1WHh80BUZo6rjv+U24GVjJL/N3hl17+8EvBsuoRJoqH2FaciU5hlCjm0XfF3Zng0h9Is5rPGqjpoIq8C++N9iGiL42WdqUWVmRurht/4kF8fLmCdr46zzBvgx64297EegO1dVUb5rkw51ZNg7358fIA==w4yc-----END PGP SIGNATURE-----
L
L
Ludovic Courtès wrote on 14 Feb 2020 18:22
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
8736bdf5il.fsf@gnu.org
Hi Maxim!
Great to see Btrfs support improving; many people will love that!
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (16 lines)> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Sun, 17 Nov 2019 06:01:00 +0900> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the system> tests.>> When setting the GUIX_DEV_HACKS environment variable, the Guix package used> inside the instrumented VMs recycles the binaries already found in the Guix> checkout of the developer instead of rebuilding Guix from scratch. This> brings the time required for this component from 20+ minutes down to 2-3> minutes on an X200 machine.>> * gnu/packages/package-management.scm (current-guix/pre-built): New procedure.> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when> GUIX_DEV_HACKS is defined.
I understand the need, but I’d really like to avoid that; it’s toofragile IMO.
But I have good news! First, commit887fd835a7c90f720d36a211478012547feaead0 really improved things byavoiding the full ‘guix’ package rebuild (and we’re only talking aboutthe installation tests; other tests are just fine.) Second, there areimprovements to Guile that will appear in 3.0.1/2.2.7 that makecompilation of big files roughly twice as fast.
There’s still room for improvement, but I’d rather work in thosedirections. WDYT?
Toggle quote (9 lines)> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 12:57:29 -0500> Subject: [PATCH 2/9] gnu: linux-boot: Ensure volatile root is mounted> read-only.>> * gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY is> present among the root file system flags when VOLATILE-ROOT? is #t.
(You can drop the “gnu:” prefix.)
OK!
Toggle quote (11 lines)> From e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 23:56:45 -0500> Subject: [PATCH 3/9] file-systems: Add a 'file-system-device->string'> procedure.>> * gnu/system/file-systems.scm (file-system-device->string): New procedure.> * gnu/system.scm (bootable-kernel-arguments): Use it.> * gnu/system/vm.scm (operating-system-uuid): Likewise.> * guix/scripts/system.scm (display-system-generation): Likewise.
OK!
Toggle quote (15 lines)> From 4f6e3955957beb5287e9d5a5d33b74725836e1ac Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 14:00:06 -0500> Subject: [PATCH 4/9] gnu: linux-boot: Refactor boot-system.>> The --root option can now be omitted, and inferred from the root file system> declaration instead.>> * gnu/build/linux-boot.scm (boot-system): Remove nested definitions for> root-fs-type, root-fs-flags and root-fs-options, and bind those inside the> let* instead. Make "--root" take precendence over the device field string> representation of the root file system.> * doc/guix.texi (Initial RAM Disk): Document that "--root" can be left> unspecified.
[...]
Toggle quote (9 lines)> @item --root=@var{root}> -Mount @var{root} as the root file system. @var{root} can be a> -device name like @code{/dev/sda1}, a file system label, or a file system> -UUID.> +Mount @var{root} as the root file system. @var{root} can be a device> +name like @code{/dev/sda1}, a file system label, or a file system UUID.> +When unspecified, the device name from the root file system of the> +operating system declaration is used.
Oh! Does it always work? That makes me wonder why we’ve been carrying‘--root’ and I’m not sure if I’m forgetting a good reason to do it thatway.
Toggle quote (24 lines)> (mount-essential-file-systems)> (let* ((args (linux-command-line))> (to-load (find-long-option "--load" args))> - (root (find-long-option "--root" args)))> + (root-fs (find root-mount-point? mounts))> + (root-fs-type (or (and=> root-fs file-system-type)> + "ext4"))> + (root-device (and=> root-fs file-system-device))> + (root-device-str (and=> root-device file-system-device->string))> + ;; --root takes precedence over the 'device' field of the root> + ;; <file-system> record.> + (root (or (find-long-option "--root" args)> + root-device-str))> + (root-fs-flags (mount-flags->bit-mask> + (or (and=> root-fs file-system-flags)> + '())))> + (root-fs-options (if root-fs> + (file-system-options root-fs)> + '()))> + (root-options (if (null? root-fs-options)> + #f> + (file-system-options->str> + root-fs-options))))
Since ‘file-system-device->string’ is lossy, I think we should do it theother way around: convert the ‘--root’ string to a <file-system>.Perhaps that bit can be moved to a separate procedure, like‘root-string->file-system’.
Also, the (or … "ext4") bit doesn’t sound great, but perhaps it’ll beunnecessary if we do with something as outlined above?
Toggle quote (19 lines)> From af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Wed, 25 Sep 2019 22:43:41 +0900> Subject: [PATCH 5/9] file-systems: Represent the file system options as an> alist.>> This allows accessing the parameter values easily, without having to parse a> string.>> * gnu/system/file-systems.scm (<file-system>): Update the default value of the> OPTIONS field, doc.> (%file-system-options): Field accessor renamed from `file-system-options'.> (file-system-options, file-system-options->string): New procedures.> * gnu/build/file-systems.scm (mount-file-system): Adapt.> * gnu/services/base.scm (file-system->fstab-entry): Likewise.> * tests/file-systems.scm: New tests.> * doc/guix.texi (File Systems): Document the modified default value of the> 'file-system-options' field.
The main issue I see with this change is that mount(2) takes raw stringsfor the options. There’s a convention to have those strings look like“KEY1=VALUE1,KEY2=VALUE2”, but it’s just a convention.
As a rule of thumb, I’d rather have our interface be as close aspossible to the actual mount(2) interface, which means taking strings.
Now, we can surely add helper procedures to parse options that followthe above conventions.
WDYT?
Toggle quote (9 lines)> + ;; Support the deprecated options format (a string).> + (define (options-string->options-list str)> + (let ((option-list (string-split str #\,)))> + (map (lambda (param)> + (if (string-contains param "=")> + (apply cons (string-split param #\=))> + param))> + option-list)))
I think we’d want to split only on the first ‘=’ sign, meaning we shoulduse ‘string-index’ etc. instead of ‘string-split’.
Toggle quote (11 lines)> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 14:14:36 -0500> Subject: [PATCH 6/9] gnu: linux-boot: Honor the "--root-options" kernel> argument.>> * gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernel> argument, and use it when calling `mount-root-file-system'. Update doc.> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options"> argument.
Hmm do we really need this extra option? :-)
(Also, in hindsight, I think it was a mistake to call them‘--something’. Following the common naming convention, we should rathercall these options ‘gnu.something’.)
Toggle quote (15 lines)> From cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 14:27:19 -0500> Subject: [PATCH 7/9] gnu: linux-boot: Filter out file system independent> options.>> This fixes an issue where options such as "defaults", which are understood by> the command line program "mount", are not understood by the system call of the> same name, which is used in the initial RAM disk.>> * gnu/system/file-systems.scm (%file-system-independent-mount-options): New variable.> (file-system-independent-mount-option?): New predicate.> * gnu/build/linux-boot.scm (boot-system): Use the above predicate to filter> out system independent mount options.
[...]
Toggle quote (8 lines)> +(define %file-system-independent-mount-options> + ;; Taken from 'man 8 mount'.> + '("async" "atime" "auto" "noatime" "noauto" "context" "defaults" "dev" "nodev"> + "diratime" "nodiratime" "dirsync" "exec" "noexec" "group" "iversion"> + "noiversion" "mand" "nomand" "_netdev" "nofail" "relatime" "norelatime"> + "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid"> + "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "users"))
I’d rather avoid it. In general, as much as possible, I think we shouldpass options to the kernel without trying to be “smart”. It’s often thesafe strategy.
WDYT?
Toggle quote (20 lines)> From 6cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Sun, 14 Jul 2019 20:50:23 +0900> Subject: [PATCH 8/9] bootloader: grub: Allow booting from a Btrfs subvolume.>> * gnu/bootloader/grub.scm (grub-configuration-file) [btrfs-subvolume-path]:> New parameter. When it is defined, prepend its value to the kernel and> initrd file paths.> * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.> * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.> * gnu/system/file-systems.scm (btrfs-subvolume?)> (btrfs-store-subvolume-path): New procedures.> * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs subvolume path> of the GNU store to the `operating-system-bootcfg' procedure, using the new> BTRFS-SUBVOLUME-PATH argument.> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of> subvolumes. Document the new `properties' field of the `<file-system>'> record.> * gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".
Neat!
Toggle quote (13 lines)> (define* (grub-configuration-file config entries> #:key> (system (%current-system))> - (old-entries '()))> + (old-entries '())> + btrfs-subvolume-path)> "Return the GRUB configuration file corresponding to CONFIG, a> <bootloader-configuration> object, and where the store is available at> STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu> -entries corresponding to old generations of the system."> +entries corresponding to old generations of the system. BTRFS-SUBVOLUME-PATH> +may be used to specify on which subvolume a Btrfs root file system resides."
(Nitpick: s/path/file name/ :-))
It’s a bit problematic that (1) GRUB needs explicit Btrfs support, and(2) other bootloaders will silently ignore the option, due to#:allow-other-keys.
I don’t have a better idea, but it’d be great if Btrfs support could bemade bootloader-independent, and if it could be somewhatnot-too-btrfs-specific, if that is possible at all.
Thoughts?
Toggle quote (18 lines)> + (properties file-system-properties ; list of name-value pairs> + (default '()))> (location file-system-location> (default (current-source-location))> (innate)))> @@ -582,4 +589,48 @@ system has the given TYPE."> (or (string-prefix-ci? "x-" option-name)> (member option-name %file-system-independent-mount-options))))> > +(define (btrfs-subvolume? fs)> + "Predicate to check if FS, a file-system object, is a Btrfs subvolume."> + (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))> + (option-keys (map (match-lambda> + ((key . value) key)> + (key key))> + (file-system-options fs))))> + (find (cut string-prefix? "subvol" <>) option-keys)))
I wonder if we can avoid special support in the <file-system> API forBtrfs.
Toggle quote (5 lines)> + (error "The store is on a Btrfs subvolume, but the \> +subvolume name is unknown.> +Hint: Define the \"btrfs-subvolume-path\" file system property or> +use the \"subvol\" Btrfs file system option."))))
Rather use ‘raise’ with ‘&message’ and ‘&fix-hint’ conditions.
Pheeew, that was a long patch series!
Perhaps we can split the continuation of this thread in sizable chunks!
Thanks for working on this,Ludo’.
M
M
Maxim Cournoyer wrote on 16 Feb 2020 06:36
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87blpzozz7.fsf@gmail.com
Hello!
Thanks for the prompt feedback.
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (35 lines)> Hi Maxim!>> Great to see Btrfs support improving; many people will love that!>> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:>>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Sun, 17 Nov 2019 06:01:00 +0900>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the system>> tests.>>>> When setting the GUIX_DEV_HACKS environment variable, the Guix package used>> inside the instrumented VMs recycles the binaries already found in the Guix>> checkout of the developer instead of rebuilding Guix from scratch. This>> brings the time required for this component from 20+ minutes down to 2-3>> minutes on an X200 machine.>>>> * gnu/packages/package-management.scm (current-guix/pre-built): New procedure.>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when>> GUIX_DEV_HACKS is defined.>> I understand the need, but I’d really like to avoid that; it’s too> fragile IMO.>> But I have good news! First, commit> 887fd835a7c90f720d36a211478012547feaead0 really improved things by> avoiding the full ‘guix’ package rebuild (and we’re only talking about> the installation tests; other tests are just fine.) Second, there are> improvements to Guile that will appear in 3.0.1/2.2.7 that make> compilation of big files roughly twice as fast.>> There’s still room for improvement, but I’d rather work in those> directions. WDYT?
With a little bit more love (inheriting from the Guix package from theinferior captured at build time), I don't see the hack being any lessfragile than the Guix checkout compiled and ran with ./pre-inst-env.
There's no arguing that it *is* a hack, but:
1) Being labeled as such (GUIX_DEV_HACKS)2) Being undocumented3) Only being enabled explicitly (through that GUIX_DEV_HACKSenvironment variable)4) Can be reverted easily in the future when the default, clean implementation isfast enough to obsolete it.
To me means its targeted to developers who understand the nature of thehack and is provided without any warranty.
And while it's exciting that Guile's compilation time is going to beimproved, no compiler's going to be as efficient as "no compilation";-).
Toggle quote (11 lines)>> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Tue, 11 Feb 2020 12:57:29 -0500>> Subject: [PATCH 2/9] gnu: linux-boot: Ensure volatile root is mounted>> read-only.>>>> * gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY is>> present among the root file system flags when VOLATILE-ROOT? is #t.>> (You can drop the “gnu:” prefix.)
Done.
I never know before looking at past logs (and then sometimes it's amixed bag). Is there any mechanical process for selecting the rightcommit prefix? :-)
Toggle quote (45 lines)> OK!>>> From e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Tue, 11 Feb 2020 23:56:45 -0500>> Subject: [PATCH 3/9] file-systems: Add a 'file-system-device->string'>> procedure.>>>> * gnu/system/file-systems.scm (file-system-device->string): New procedure.>> * gnu/system.scm (bootable-kernel-arguments): Use it.>> * gnu/system/vm.scm (operating-system-uuid): Likewise.>> * guix/scripts/system.scm (display-system-generation): Likewise.>> OK!>>> From 4f6e3955957beb5287e9d5a5d33b74725836e1ac Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Tue, 11 Feb 2020 14:00:06 -0500>> Subject: [PATCH 4/9] gnu: linux-boot: Refactor boot-system.>>>> The --root option can now be omitted, and inferred from the root file system>> declaration instead.>>>> * gnu/build/linux-boot.scm (boot-system): Remove nested definitions for>> root-fs-type, root-fs-flags and root-fs-options, and bind those inside the>> let* instead. Make "--root" take precendence over the device field string>> representation of the root file system.>> * doc/guix.texi (Initial RAM Disk): Document that "--root" can be left>> unspecified.>> [...]>>> @item --root=@var{root}>> -Mount @var{root} as the root file system. @var{root} can be a>> -device name like @code{/dev/sda1}, a file system label, or a file system>> -UUID.>> +Mount @var{root} as the root file system. @var{root} can be a device>> +name like @code{/dev/sda1}, a file system label, or a file system UUID.>> +When unspecified, the device name from the root file system of the>> +operating system declaration is used.>> Oh! Does it always work? That makes me wonder why we’ve been carrying> ‘--root’ and I’m not sure if I’m forgetting a good reason to do it that> way.
If the documentation is accurate, it should :-), given that --root getswritten as a string to the GRUB configuration file, and that the docsays it's possible to give it as a device name, label or UUID.
About why providing options such as --root or --root-options in thefirst place; I pondered about this as well, especially after making thefile systems from operating system able to be mounted with all their(file system independent -- more on that later) options. A reason Icame up with was that it allows to experiment at the GRUB command lineand change the root device, or perhaps the root options. One use casewould be debugging the right options to pass to a file system driver incase of a mistake in the operating system declaration.
Toggle quote (30 lines)>>> (mount-essential-file-systems)>> (let* ((args (linux-command-line))>> (to-load (find-long-option "--load" args))>> - (root (find-long-option "--root" args)))>> + (root-fs (find root-mount-point? mounts))>> + (root-fs-type (or (and=> root-fs file-system-type)>> + "ext4"))>> + (root-device (and=> root-fs file-system-device))>> + (root-device-str (and=> root-device file-system-device->string))>> + ;; --root takes precedence over the 'device' field of the root>> + ;; <file-system> record.>> + (root (or (find-long-option "--root" args)>> + root-device-str))>> + (root-fs-flags (mount-flags->bit-mask>> + (or (and=> root-fs file-system-flags)>> + '())))>> + (root-fs-options (if root-fs>> + (file-system-options root-fs)>> + '()))>> + (root-options (if (null? root-fs-options)>> + #f>> + (file-system-options->str>> + root-fs-options))))>> Since ‘file-system-device->string’ is lossy, I think we should do it the> other way around: convert the ‘--root’ string to a <file-system>.> Perhaps that bit can be moved to a separate procedure, like> ‘root-string->file-system’.
Done!
Toggle quote (3 lines)> Also, the (or … "ext4") bit doesn’t sound great, but perhaps it’ll be> unnecessary if we do with something as outlined above?
That bit was already there; it exists because we allow an operatingsystem definition to be made without any root file system (for use withthe 'guix system container' or 'guix system vm' commands IIRC). Whatcould be simpler would be to always require such information to beembedded in the operating system declaration: when an interactive usercommand would need to modify the root file system, it could create a newoperating-system object, inheriting from the original one.
Toggle quote (31 lines)>> From af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Wed, 25 Sep 2019 22:43:41 +0900>> Subject: [PATCH 5/9] file-systems: Represent the file system options as an>> alist.>>>> This allows accessing the parameter values easily, without having to parse a>> string.>>>> * gnu/system/file-systems.scm (<file-system>): Update the default value of the>> OPTIONS field, doc.>> (%file-system-options): Field accessor renamed from `file-system-options'.>> (file-system-options, file-system-options->string): New procedures.>> * gnu/build/file-systems.scm (mount-file-system): Adapt.>> * gnu/services/base.scm (file-system->fstab-entry): Likewise.>> * tests/file-systems.scm: New tests.>> * doc/guix.texi (File Systems): Document the modified default value of the>> 'file-system-options' field.>> The main issue I see with this change is that mount(2) takes raw strings> for the options. There’s a convention to have those strings look like> “KEY1=VALUE1,KEY2=VALUE2”, but it’s just a convention.>> As a rule of thumb, I’d rather have our interface be as close as> possible to the actual mount(2) interface, which means taking strings.>> Now, we can surely add helper procedures to parse options that follow> the above conventions.>> WDYT?
To me, it's an implementation detail that I'd rather abstract away (ormake optional, like in this patch). Just like we provide a higher levelconfiguration for services instead of requiring the user to input theconfiguration in the native format of the tool (or allowing for both).The idea for this format was taken from a discussion here:http://issues.guix.info/issue/33517#3.
Are we really targeting mount(2)? The commit9d3053819dfd834a1c29a03427c41d8524b8a7d5 (which you co-authored :-))mentions 'man 8 mount' for the file system options. This should bestressed in the manual, as someone attempting to pass file systemindependent options (perhaps taking their options line from a previous/etc/fstab config), could prevent the system from booting.
I mistakenly was under the impression that mount(8) was targeted, sincethe main interaction I observed between a file system object and mysystem was the /etc/fstab file getting produced.
Doesn't targeting mount(2) mean that it becomes impossible to give allthe options someone would possibly want to produce their /etc/fstabfile? Suppose you want the 'ro' option for one of your partition in/etc/fstab; that wouldn't fly currently, unless I'm missing something.It seems to me we should target mount(8), and internally translate thefile system independent mount(8) options into mount(2) flags orvice-versa but targeting the higher level and going down makes moresense to me.
Toggle quote (12 lines)>> + ;; Support the deprecated options format (a string).>> + (define (options-string->options-list str)>> + (let ((option-list (string-split str #\,)))>> + (map (lambda (param)>> + (if (string-contains param "=")>> + (apply cons (string-split param #\=))>> + param))>> + option-list)))>> I think we’d want to split only on the first ‘=’ sign, meaning we should> use ‘string-index’ etc. instead of ‘string-split’.
Good catch!
Toggle quote (13 lines)>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Tue, 11 Feb 2020 14:14:36 -0500>> Subject: [PATCH 6/9] gnu: linux-boot: Honor the "--root-options" kernel>> argument.>>>> * gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernel>> argument, and use it when calling `mount-root-file-system'. Update doc.>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options">> argument.>> Hmm do we really need this extra option? :-)
It is not strictly needed but allows the user to experiment/troubleshootwith the init RAM disk from GRUB as discussed earlier for --root. Doyou think it has enough value to be kept?
Toggle quote (4 lines)> (Also, in hindsight, I think it was a mistake to call them> ‘--something’. Following the common naming convention, we should rather> call these options ‘gnu.something’.)
Is this convention detailed somewhere? I haven't found it in 'Standards'.
Toggle quote (29 lines)>> From cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Tue, 11 Feb 2020 14:27:19 -0500>> Subject: [PATCH 7/9] gnu: linux-boot: Filter out file system independent>> options.>>>> This fixes an issue where options such as "defaults", which are understood by>> the command line program "mount", are not understood by the system call of the>> same name, which is used in the initial RAM disk.>>>> * gnu/system/file-systems.scm (%file-system-independent-mount-options): New variable.>> (file-system-independent-mount-option?): New predicate.>> * gnu/build/linux-boot.scm (boot-system): Use the above predicate to filter>> out system independent mount options.>> [...]>>> +(define %file-system-independent-mount-options>> + ;; Taken from 'man 8 mount'.>> + '("async" "atime" "auto" "noatime" "noauto" "context" "defaults" "dev" "nodev">> + "diratime" "nodiratime" "dirsync" "exec" "noexec" "group" "iversion">> + "noiversion" "mand" "nomand" "_netdev" "nofail" "relatime" "norelatime">> + "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid">> + "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "users"))>> I’d rather avoid it. In general, as much as possible, I think we should> pass options to the kernel without trying to be “smart”. It’s often the> safe strategy.
Let's revisit this topic after we've sorted the mount(8) vs mount(2)problem above.
I'll address the rest in a part 2.
Thank you for your time and patience!
Maxim
L
L
Ludovic Courtès wrote on 16 Feb 2020 12:11
Making system installation tests faster
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
8736ba3hxo.fsf_-_@gnu.org
Hi Maxim,
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (41 lines)> Ludovic Courtès <ludo@gnu.org> writes:>>> Hi Maxim!>>>> Great to see Btrfs support improving; many people will love that!>>>> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:>>>>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001>>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>>> Date: Sun, 17 Nov 2019 06:01:00 +0900>>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the system>>> tests.>>>>>> When setting the GUIX_DEV_HACKS environment variable, the Guix package used>>> inside the instrumented VMs recycles the binaries already found in the Guix>>> checkout of the developer instead of rebuilding Guix from scratch. This>>> brings the time required for this component from 20+ minutes down to 2-3>>> minutes on an X200 machine.>>>>>> * gnu/packages/package-management.scm (current-guix/pre-built): New procedure.>>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when>>> GUIX_DEV_HACKS is defined.>>>> I understand the need, but I’d really like to avoid that; it’s too>> fragile IMO.>>>> But I have good news! First, commit>> 887fd835a7c90f720d36a211478012547feaead0 really improved things by>> avoiding the full ‘guix’ package rebuild (and we’re only talking about>> the installation tests; other tests are just fine.) Second, there are>> improvements to Guile that will appear in 3.0.1/2.2.7 that make>> compilation of big files roughly twice as fast.>>>> There’s still room for improvement, but I’d rather work in those>> directions. WDYT?>> With a little bit more love (inheriting from the Guix package from the> inferior captured at build time), I don't see the hack being any less> fragile than the Guix checkout compiled and ran with ./pre-inst-env.
It’s grabbing files from the working tree, with heuristics to minimizethe changes in incorporating files that shouldn’t be there; I think it’sfragile. :-)
It also breaks that idea that things compiled by Guix are well undercontrol.
Toggle quote (16 lines)> There's no arguing that it *is* a hack, but:>> 1) Being labeled as such (GUIX_DEV_HACKS)> 2) Being undocumented> 3) Only being enabled explicitly (through that GUIX_DEV_HACKS> environment variable)> 4) Can be reverted easily in the future when the default, clean implementation is> fast enough to obsolete it.>> To me means its targeted to developers who understand the nature of the> hack and is provided without any warranty.>> And while it's exciting that Guile's compilation time is going to be> improved, no compiler's going to be as efficient as "no compilation"> ;-).
True! But still, we’d have to maintain that in the meantime and dealwith any “surprising” effects it has for those using it.
FWIW, when testing (gnu installer tests), I only have to rebuild“guix-system-tests.drv”, which is fast. And in fact, I can also notrebuild anything by doing:
(define operating-system-with-current-guix identity)
because in this particular case, I know it’s not necessary to have thecurrent ‘guix’ package.
I suppose this would also be an option in your case, when testing theBtrfs changes, no?
Perhaps we should make this case more easily accessible through anenvironment variable?
Thanks,Ludo’.
M
M
Maxim Cournoyer wrote on 18 Feb 2020 14:37
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87sgj8j9sf.fsf@gmail.com
Hi Ludovic,
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (49 lines)> Hi Maxim,>> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:>>> Ludovic Courtès <ludo@gnu.org> writes:>>>>> Hi Maxim!>>>>>> Great to see Btrfs support improving; many people will love that!>>>>>> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:>>>>>>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001>>>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>>>> Date: Sun, 17 Nov 2019 06:01:00 +0900>>>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the system>>>> tests.>>>>>>>> When setting the GUIX_DEV_HACKS environment variable, the Guix package used>>>> inside the instrumented VMs recycles the binaries already found in the Guix>>>> checkout of the developer instead of rebuilding Guix from scratch. This>>>> brings the time required for this component from 20+ minutes down to 2-3>>>> minutes on an X200 machine.>>>>>>>> * gnu/packages/package-management.scm (current-guix/pre-built): New procedure.>>>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when>>>> GUIX_DEV_HACKS is defined.>>>>>> I understand the need, but I’d really like to avoid that; it’s too>>> fragile IMO.>>>>>> But I have good news! First, commit>>> 887fd835a7c90f720d36a211478012547feaead0 really improved things by>>> avoiding the full ‘guix’ package rebuild (and we’re only talking about>>> the installation tests; other tests are just fine.) Second, there are>>> improvements to Guile that will appear in 3.0.1/2.2.7 that make>>> compilation of big files roughly twice as fast.>>>>>> There’s still room for improvement, but I’d rather work in those>>> directions. WDYT?>>>> With a little bit more love (inheriting from the Guix package from the>> inferior captured at build time), I don't see the hack being any less>> fragile than the Guix checkout compiled and ran with ./pre-inst-env.>> It’s grabbing files from the working tree, with heuristics to minimize> the changes in incorporating files that shouldn’t be there; I think it’s> fragile. :-)
Fragile or not, it's helped me getting this change tested much fasterthan I could have had otherwise, which is the point of that hack :-).Benchmarks below.
Toggle quote (22 lines)> It also breaks that idea that things compiled by Guix are well under> control.>>> There's no arguing that it *is* a hack, but:>>>> 1) Being labeled as such (GUIX_DEV_HACKS)>> 2) Being undocumented>> 3) Only being enabled explicitly (through that GUIX_DEV_HACKS>> environment variable)>> 4) Can be reverted easily in the future when the default, clean implementation is>> fast enough to obsolete it.>>>> To me means its targeted to developers who understand the nature of the>> hack and is provided without any warranty.>>>> And while it's exciting that Guile's compilation time is going to be>> improved, no compiler's going to be as efficient as "no compilation">> ;-).>> True! But still, we’d have to maintain that in the meantime and deal> with any “surprising” effects it has for those using it.
Yeah.
Toggle quote (12 lines)> FWIW, when testing (gnu installer tests), I only have to rebuild> “guix-system-tests.drv”, which is fast. And in fact, I can also not> rebuild anything by doing:>> (define operating-system-with-current-guix identity)>> because in this particular case, I know it’s not necessary to have the> current ‘guix’ package.>> I suppose this would also be an option in your case, when testing the> Btrfs changes, no?
I think it is important that the 'installer' image corresponds to the'current-guix' in my case, because it has to generate the correct GRUBconfiguration file at 'guix system init' time.
Below are some analysis of the derivations triggered in different scenarios.
Without the hack:
Toggle snippet (112 lines)./pre-inst-env make check-system TESTS=btrfs-root-on-subvolume-osCompiling Scheme modules...random seed for tests: 1581852580Computing Guix derivation for 'x86_64-linux'... \Running 1 system tests...substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%The following derivations will be built: /gnu/store/3g9bawa6c876lml0318g2knqdcv2ahv9-btrfs-root-on-subvolume-os.drv /gnu/store/vswbrzp8ab5wz0fyzrj9j72mqcbd6c4a-installation.drv /gnu/store/nf1wd5bgminylzvwq4mjs5293hpr1mmi-disk-image.drv /gnu/store/45334hsl3hs5yx13x7qz1b1sc83vkbzj-module-import-compiled.drv /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-import.drv /gnu/store/4cp5pqyn554rdmv9l4vfhnw7lgasv18q-raw-initrd.drv /gnu/store/vx147spsmrxkiy0qcmvxn341fpz4fmrv-init.drv /gnu/store/d6ri0lh953vaksiz5h8jx681h3i35vvm-module-import-compiled.drv /gnu/store/b0gv94llsbvrlzkxs3naz7crcv1glxy1-grub.cfg.drv /gnu/store/gcslrfymsqsp6kqckla41zkyaa7fy9in-raw-initrd.drv /gnu/store/m8bbfcdn1irn7a41syy9arl1yz34hbln-init.drv /gnu/store/hbfgqnralir92slqr9hhfw8cxqrlgv06-system.drv /gnu/store/0v4aq6yprk8az183rpdjx90jnxw3w838-parameters.drv /gnu/store/8daaamb92bbkpdwz96a19r81f7vnk40k-gc-roots.drv /gnu/store/f48dwgib52ciaq1nh06nhks6g7gvy7bx-system.drv /gnu/store/4ll7vvq5wxq8c2xl8qw5dbim7nrz0yda-raw-initrd.drv /gnu/store/mxdfkkfyy3ld6656a01z0lw7gxgjns25-init.drv /gnu/store/72fjlv3kp75629as4bc49yp9hgf80pv7-boot.drv /gnu/store/xra5iv1ayyiml1kvpcjg5rkrgjbzy6lb-activate.scm.drv /gnu/store/xww4xc7rpc1bw1xk9sn6vy3hazjk1gcq-module-import-compiled.drv /gnu/store/y8hd9wzr9ypn2pfcl5al0dckijzw36x6-shepherd.conf.drv /gnu/store/14mdcbdyqrihnl7x8lqygncxdbsvmhv0-shepherd-file-system--home.go.drv /gnu/store/clv6h5sxwgchw1kkf9cnafgvd5ms4p4r-shepherd-file-system--home.scm.drv /gnu/store/zc84ngrjdvbc4kibdvzipf9sxjj50rgz-module-import-compiled.drv /gnu/store/6cca3yng6k4zl812ysdgmj5lyw8lmwln-shepherd-file-system--gnu-store.go.drv /gnu/store/rplp3l38j9jm0fism0ka1iqbfhx7h3ir-shepherd-file-system--gnu-store.scm.drv /gnu/store/729f2ranwr6klr90rvrx5pfka30iwazr-shepherd-user-homes.go.drv /gnu/store/2cadf4viazfvzlazj996vmbpq3cw1hbr-shepherd-user-homes.scm.drv /gnu/store/7j784x4jpxqlcisikn8cin4s0n1vv7z7-shepherd-term-auto.go.drv /gnu/store/zgz6p1mss3jwra7d4vzh1dxy9b4llnlg-shepherd-term-auto.scm.drv /gnu/store/7n6y2ljl0gp4s568wqbj5iwdkw5hrhk6-shepherd-file-system--dev-shm.go.drv /gnu/store/apsplfgbzzq38b5q7p06jxjn37kx74b2-shepherd-file-system--dev-shm.scm.drv /gnu/store/qj459c7mlrls9imm1nw98lw9fgqh4yyy-shepherd-udev.go.drv /gnu/store/78klph6xipr232a938qjhm8v4qviacvd-shepherd-udev.scm.drv /gnu/store/z103dcbbvz3inx6ax7s966zxmy1s38hn-shepherd-file-system--dev-pts.go.drv /gnu/store/5ss1d8nwn4dv9vb69h1iyw884b61y487-shepherd-file-system--dev-pts.scm.drv /gnu/store/z1f6a7gfxxszaa0lm68xfl9hbglz48cw-parameters.drv /gnu/store/vvg05l3pgkyz1rky6f2cn0d1r2i1b6yr-system.drv /gnu/store/1k5k3kd11l3wabcc8sci8m04nvc6wllw-raw-initrd.drv /gnu/store/51ay1gi0ajsbrgm7wy6j1njyy6pcjlzb-init.drv /gnu/store/jjhnm39rqckl6r0jf7l43000nlydb2vj-parameters.drv /gnu/store/wdm0acks0pzl3hiam7knffl7n6xmyvrm-boot.drv /gnu/store/59mhndnjhsq6yspag4miv4b71rb8v683-activate.scm.drv /gnu/store/z0ik75q9nshaik97jsigd69vriyjijgp-shepherd.conf.drv /gnu/store/6pxsd37k5nl5viqadd57n0hah53nzcp7-shepherd-user-homes.go.drv /gnu/store/y9rj23r1xmyb5b4fwrh75pb5yr61clvp-shepherd-user-homes.scm.drv /gnu/store/h0xbdk4hw1i4byy8xnrnaqmlwnfgrswz-profile.drv /gnu/store/sxdgmvfjakapmbyqmxjgvarsaaxc2mw7-profile.drv /gnu/store/hxcadzr771dzl99kylz64d9qz2qai8wd-guix-000000000.drv /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drv /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drv /gnu/store/g6ggidnpaahws37qgx15mvkhfll0ns06-guix-daemon.drv /gnu/store/jpb2jfk00q5nh5fg3k3cf6hcyw49zz84-guix-command.drv /gnu/store/14zcma6hkqszaab37hda736i24r41rv4-guix-module-union.drv /gnu/store/sfzd86425cl744lr58yh877i7z5qbd68-guix-000000000-modules.drv /gnu/store/71a40hzi2d2wdn1vjl5amfq00caqlh3m-guix-system-tests-modules.drv /gnu/store/kc3zg69yabaglvllj4l7hzgs72v9mk26-guix-system-tests.drv /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv /gnu/store/d7df7qw5allqcm2qn75dn60wz1dg50cq-guix-system.drv /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv /gnu/store/xgpy1v810xi76w8ivpfi7gg5h7vg0ska-guix-cli.drv /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-modules.drv /gnu/store/j15kzs5m07pq3nmgqr5rr47cryq8arfs-guix-system-modules.drv /gnu/store/rhk9cknm5wbk30slzzrr52app8mfn4a2-guix-packages-modules.drv /gnu/store/x05mz632h3ph0k9n3s5y14m51qy3k929-guix-cli-modules.drv /gnu/store/fs2g9iin23iq4505jsxjnrjaxnxp1wzl-inferior-script.scm.drv /gnu/store/y4hv2s267zjz2gzja3cj428a7z1dln98-profile.drv /gnu/store/kx5h4kxkz28gahlgkxni02i0rf8558vd-boot.drv /gnu/store/nhi2s5zcyd5frjqag4jnp7fvhzbx6kd6-activate.scm.drv /gnu/store/qnchikcfqx8hn0a7cn45f0pnf664s0jk-shepherd.conf.drv /gnu/store/7n4cqlsbn7hywlwssxvax6j6b57gm1q4-shepherd-user-homes.go.drv /gnu/store/dl333r3dshzi5nb4qqrvcsp2hmk3hd9p-shepherd-user-homes.scm.drv /gnu/store/i96lsb7shixcczc62bfadbg1g73qp38l-shepherd-udev.go.drv /gnu/store/yv3maqmnqqpiqj2jk5ss574pzvgh9jin-shepherd-udev.scm.drv /gnu/store/s5w901l6zl0ql800bc9cndnskqdhnsxm-shepherd-file-system--tmp.go.drv /gnu/store/a5nb6vhs86g76ww5bmpphi398pggnga7-shepherd-file-system--tmp.scm.drv /gnu/store/sjn7zb56x72lh6i7arkh6gpd639g7d17-shepherd-guix-daemon.go.drv /gnu/store/rww6z6m3nz6s7h54xklwj3plylg1f0yc-shepherd-guix-daemon.scm.drv /gnu/store/lmbja82mymwsn3kmxwfy8g7s46xac443-linux-vm-loader.drv /gnu/store/z8y0v374himjlig4qwjisv1xa7rk7r0l-builder-in-linux-vm.drv /gnu/store/14bw0x4dq0g262vk4pjh3dlha6x3gz0s-module-import-compiled.drv /gnu/store/nbkfy5wjpia5y7hj1p9j5hmbv42j4zp5-module-import.drvThe following grafts will be made: /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drv /gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drvThe following profile hooks will be built: /gnu/store/96274clz8449s7s18a91sa31d1ilmi0p-fonts-dir.drv /gnu/store/30lvdbci7v9zqgn3nqjy1vgbpv5k4b98-ca-certificate-bundle.drv /gnu/store/b5dspr8576n0j3vl2cjsr7zrfdp380cw-guix-package-cache.drv /gnu/store/chjdvqjbrnb7cqla43n5rvqia5d4f4mg-fonts-dir.drv /gnu/store/kh7wixk3i5db2ym48ddyrdbggw8ccxp8-info-dir.drv /gnu/store/x3bp2acfy04w9r9l11w30l9z0hpsii5a-manual-database.drv /gnu/store/bhla9fihy35pgc3bwszfxvsfjir71v88-glib-schemas.drv /gnu/store/isb4444058amfr4sipqmffcrgisx75gs-ca-certificate-bundle.drv /gnu/store/l8qgqaxq1xcb8jk3lqmzzrfiv8hzpna1-xdg-desktop-database.drv /gnu/store/x0vhd98kg66pzfwffbi45f76126by816-xdg-mime-database.drv /gnu/store/xs4k7nmrpbjsy0a5k6lsbdxc2n4i23g4-info-dir.drv /gnu/store/zffqfc9w73sy815av7hwincbqpl7hbkr-manual-database.drvbuilding /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-import.drv...successfully built /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-import.drvbuilding /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drv...^Cmake: *** [Makefile:5711: check-system] Interrupt
With the hack:
Toggle snippet (82 lines)./pre-inst-env make check-system TESTS=btrfs-root-on-subvolume-os GUIX_DEV_HACKS=1Compiling Scheme modules...random seed for tests: 1581851372Running 1 system tests...The following derivations will be built: /gnu/store/l4z1363klr8a58qmm3pjzy2y5bxsr6bd-btrfs-root-on-subvolume-os.drv /gnu/store/zlg6gxml4awbkbs2s6n1b0z3ysrqvy0h-installation.drv /gnu/store/89vdpn33f47y0510im604snwfmbpswmm-disk-image.drv /gnu/store/45334hsl3hs5yx13x7qz1b1sc83vkbzj-module-import-compiled.drv /gnu/store/4cp5pqyn554rdmv9l4vfhnw7lgasv18q-raw-initrd.drv /gnu/store/vx147spsmrxkiy0qcmvxn341fpz4fmrv-init.drv /gnu/store/d6ri0lh953vaksiz5h8jx681h3i35vvm-module-import-compiled.drv /gnu/store/58912rdjjk4jdv767svb2axp0llmn8ch-linux-vm-loader.drv /gnu/store/hvcm9abi0br38plwpngqlvw1l0060fni-builder-in-linux-vm.drv /gnu/store/14bw0x4dq0g262vk4pjh3dlha6x3gz0s-module-import-compiled.drv /gnu/store/nbkfy5wjpia5y7hj1p9j5hmbv42j4zp5-module-import.drv /gnu/store/shc8hzzqi40pdpip0773i2g9x2apnn0h-grub.cfg.drv /gnu/store/gcslrfymsqsp6kqckla41zkyaa7fy9in-raw-initrd.drv /gnu/store/m8bbfcdn1irn7a41syy9arl1yz34hbln-init.drv /gnu/store/zifmvsbiw6x4gs15k29l1nvyzxkszafw-system.drv /gnu/store/0v4aq6yprk8az183rpdjx90jnxw3w838-parameters.drv /gnu/store/8daaamb92bbkpdwz96a19r81f7vnk40k-gc-roots.drv /gnu/store/f48dwgib52ciaq1nh06nhks6g7gvy7bx-system.drv /gnu/store/4ll7vvq5wxq8c2xl8qw5dbim7nrz0yda-raw-initrd.drv /gnu/store/mxdfkkfyy3ld6656a01z0lw7gxgjns25-init.drv /gnu/store/72fjlv3kp75629as4bc49yp9hgf80pv7-boot.drv /gnu/store/xra5iv1ayyiml1kvpcjg5rkrgjbzy6lb-activate.scm.drv /gnu/store/xww4xc7rpc1bw1xk9sn6vy3hazjk1gcq-module-import-compiled.drv /gnu/store/y8hd9wzr9ypn2pfcl5al0dckijzw36x6-shepherd.conf.drv /gnu/store/14mdcbdyqrihnl7x8lqygncxdbsvmhv0-shepherd-file-system--home.go.drv /gnu/store/clv6h5sxwgchw1kkf9cnafgvd5ms4p4r-shepherd-file-system--home.scm.drv /gnu/store/zc84ngrjdvbc4kibdvzipf9sxjj50rgz-module-import-compiled.drv /gnu/store/6cca3yng6k4zl812ysdgmj5lyw8lmwln-shepherd-file-system--gnu-store.go.drv /gnu/store/rplp3l38j9jm0fism0ka1iqbfhx7h3ir-shepherd-file-system--gnu-store.scm.drv /gnu/store/729f2ranwr6klr90rvrx5pfka30iwazr-shepherd-user-homes.go.drv /gnu/store/2cadf4viazfvzlazj996vmbpq3cw1hbr-shepherd-user-homes.scm.drv /gnu/store/7j784x4jpxqlcisikn8cin4s0n1vv7z7-shepherd-term-auto.go.drv /gnu/store/zgz6p1mss3jwra7d4vzh1dxy9b4llnlg-shepherd-term-auto.scm.drv /gnu/store/7n6y2ljl0gp4s568wqbj5iwdkw5hrhk6-shepherd-file-system--dev-shm.go.drv /gnu/store/apsplfgbzzq38b5q7p06jxjn37kx74b2-shepherd-file-system--dev-shm.scm.drv /gnu/store/qj459c7mlrls9imm1nw98lw9fgqh4yyy-shepherd-udev.go.drv /gnu/store/78klph6xipr232a938qjhm8v4qviacvd-shepherd-udev.scm.drv /gnu/store/z103dcbbvz3inx6ax7s966zxmy1s38hn-shepherd-file-system--dev-pts.go.drv /gnu/store/5ss1d8nwn4dv9vb69h1iyw884b61y487-shepherd-file-system--dev-pts.scm.drv /gnu/store/z1f6a7gfxxszaa0lm68xfl9hbglz48cw-parameters.drv /gnu/store/vvg05l3pgkyz1rky6f2cn0d1r2i1b6yr-system.drv /gnu/store/1k5k3kd11l3wabcc8sci8m04nvc6wllw-raw-initrd.drv /gnu/store/51ay1gi0ajsbrgm7wy6j1njyy6pcjlzb-init.drv /gnu/store/jjhnm39rqckl6r0jf7l43000nlydb2vj-parameters.drv /gnu/store/wdm0acks0pzl3hiam7knffl7n6xmyvrm-boot.drv /gnu/store/59mhndnjhsq6yspag4miv4b71rb8v683-activate.scm.drv /gnu/store/z0ik75q9nshaik97jsigd69vriyjijgp-shepherd.conf.drv /gnu/store/6pxsd37k5nl5viqadd57n0hah53nzcp7-shepherd-user-homes.go.drv /gnu/store/y9rj23r1xmyb5b4fwrh75pb5yr61clvp-shepherd-user-homes.scm.drv /gnu/store/kammkm5z0ihjqalg0ijn69ffhdyzki47-profile.drv /gnu/store/07kxlp8a99mvx2zidnlz6rm4ak2az8d0-guix-1.0.1-13.50299ad+.drv /gnu/store/m9783fc7m360dk582b3mv2wgrsdz6amk-boot.drv /gnu/store/3v1whxi5qkp9cyfc3vjpvziwc9ms7y7k-shepherd.conf.drv /gnu/store/50halfax0zbiwpy47z6374ybh1mq1d5r-shepherd-guix-daemon.go.drv /gnu/store/g4m4mqiz9z4yd2iwzmb6f81vidw0k4bg-shepherd-guix-daemon.scm.drv /gnu/store/7n4cqlsbn7hywlwssxvax6j6b57gm1q4-shepherd-user-homes.go.drv /gnu/store/dl333r3dshzi5nb4qqrvcsp2hmk3hd9p-shepherd-user-homes.scm.drv /gnu/store/i96lsb7shixcczc62bfadbg1g73qp38l-shepherd-udev.go.drv /gnu/store/yv3maqmnqqpiqj2jk5ss574pzvgh9jin-shepherd-udev.scm.drv /gnu/store/s5w901l6zl0ql800bc9cndnskqdhnsxm-shepherd-file-system--tmp.go.drv /gnu/store/a5nb6vhs86g76ww5bmpphi398pggnga7-shepherd-file-system--tmp.scm.drv /gnu/store/nhi2s5zcyd5frjqag4jnp7fvhzbx6kd6-activate.scm.drvThe following profile hooks will be built: /gnu/store/4j2hrilvx5rfycqs1sccd39jy5yjhxy0-xdg-mime-database.drv /gnu/store/4rdg1bi6xxn85zq5cjqc3bdfksx14913-info-dir.drv /gnu/store/c59p1krnc51qlbr5vnxjx6bg3rrixca4-glib-schemas.drv /gnu/store/drf1pi6m91b6qra3p6hrknfzh7gcd51z-fonts-dir.drv /gnu/store/fwal8vsrjzpbwljnihvv66k9ikkfx2ma-xdg-desktop-database.drv /gnu/store/jzp4ps09ipy0kcc6ybx5967vi3xlq7aa-manual-database.drv /gnu/store/m7yl2xvk07l37l19wp2hfbvhzl3583ji-ca-certificate-bundle.drvbuilding /gnu/store/45334hsl3hs5yx13x7qz1b1sc83vkbzj-module-import-compiled.drv...process 21756 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 0.0 (normalized: 0.0)building /gnu/store/07kxlp8a99mvx2zidnlz6rm4ak2az8d0-guix-1.0.1-13.50299ad+.drv...^Cmake: *** [Makefile:5711: check-system] Interrupt
The diff between those two looks like:
Toggle snippet (100 lines)--- /tmp/ediffD0RQCf 2020-02-16 12:10:53.643411325 -0500+++ /tmp/ediffKmWrdZ 2020-02-16 12:10:53.647411377 -0500@@ -1,15 +1,18 @@- /gnu/store/3g9bawa6c876lml0318g2knqdcv2ahv9-btrfs-root-on-subvolume-os.drv- /gnu/store/vswbrzp8ab5wz0fyzrj9j72mqcbd6c4a-installation.drv- /gnu/store/nf1wd5bgminylzvwq4mjs5293hpr1mmi-disk-image.drv+ /gnu/store/l4z1363klr8a58qmm3pjzy2y5bxsr6bd-btrfs-root-on-subvolume-os.drv+ /gnu/store/zlg6gxml4awbkbs2s6n1b0z3ysrqvy0h-installation.drv+ /gnu/store/89vdpn33f47y0510im604snwfmbpswmm-disk-image.drv /gnu/store/45334hsl3hs5yx13x7qz1b1sc83vkbzj-module-import-compiled.drv- /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-import.drv /gnu/store/4cp5pqyn554rdmv9l4vfhnw7lgasv18q-raw-initrd.drv /gnu/store/vx147spsmrxkiy0qcmvxn341fpz4fmrv-init.drv /gnu/store/d6ri0lh953vaksiz5h8jx681h3i35vvm-module-import-compiled.drv- /gnu/store/b0gv94llsbvrlzkxs3naz7crcv1glxy1-grub.cfg.drv+ /gnu/store/58912rdjjk4jdv767svb2axp0llmn8ch-linux-vm-loader.drv+ /gnu/store/hvcm9abi0br38plwpngqlvw1l0060fni-builder-in-linux-vm.drv+ /gnu/store/14bw0x4dq0g262vk4pjh3dlha6x3gz0s-module-import-compiled.drv+ /gnu/store/nbkfy5wjpia5y7hj1p9j5hmbv42j4zp5-module-import.drv+ /gnu/store/shc8hzzqi40pdpip0773i2g9x2apnn0h-grub.cfg.drv /gnu/store/gcslrfymsqsp6kqckla41zkyaa7fy9in-raw-initrd.drv /gnu/store/m8bbfcdn1irn7a41syy9arl1yz34hbln-init.drv- /gnu/store/hbfgqnralir92slqr9hhfw8cxqrlgv06-system.drv+ /gnu/store/zifmvsbiw6x4gs15k29l1nvyzxkszafw-system.drv /gnu/store/0v4aq6yprk8az183rpdjx90jnxw3w838-parameters.drv /gnu/store/8daaamb92bbkpdwz96a19r81f7vnk40k-gc-roots.drv /gnu/store/f48dwgib52ciaq1nh06nhks6g7gvy7bx-system.drv@@ -44,56 +47,24 @@ /gnu/store/z0ik75q9nshaik97jsigd69vriyjijgp-shepherd.conf.drv /gnu/store/6pxsd37k5nl5viqadd57n0hah53nzcp7-shepherd-user-homes.go.drv /gnu/store/y9rj23r1xmyb5b4fwrh75pb5yr61clvp-shepherd-user-homes.scm.drv- /gnu/store/h0xbdk4hw1i4byy8xnrnaqmlwnfgrswz-profile.drv- /gnu/store/sxdgmvfjakapmbyqmxjgvarsaaxc2mw7-profile.drv- /gnu/store/hxcadzr771dzl99kylz64d9qz2qai8wd-guix-000000000.drv- /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drv- /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drv- /gnu/store/g6ggidnpaahws37qgx15mvkhfll0ns06-guix-daemon.drv- /gnu/store/jpb2jfk00q5nh5fg3k3cf6hcyw49zz84-guix-command.drv- /gnu/store/14zcma6hkqszaab37hda736i24r41rv4-guix-module-union.drv- /gnu/store/sfzd86425cl744lr58yh877i7z5qbd68-guix-000000000-modules.drv- /gnu/store/71a40hzi2d2wdn1vjl5amfq00caqlh3m-guix-system-tests-modules.drv- /gnu/store/kc3zg69yabaglvllj4l7hzgs72v9mk26-guix-system-tests.drv- /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv- /gnu/store/d7df7qw5allqcm2qn75dn60wz1dg50cq-guix-system.drv- /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv- /gnu/store/xgpy1v810xi76w8ivpfi7gg5h7vg0ska-guix-cli.drv- /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-modules.drv- /gnu/store/j15kzs5m07pq3nmgqr5rr47cryq8arfs-guix-system-modules.drv- /gnu/store/rhk9cknm5wbk30slzzrr52app8mfn4a2-guix-packages-modules.drv- /gnu/store/x05mz632h3ph0k9n3s5y14m51qy3k929-guix-cli-modules.drv- /gnu/store/fs2g9iin23iq4505jsxjnrjaxnxp1wzl-inferior-script.scm.drv- /gnu/store/y4hv2s267zjz2gzja3cj428a7z1dln98-profile.drv- /gnu/store/kx5h4kxkz28gahlgkxni02i0rf8558vd-boot.drv- /gnu/store/nhi2s5zcyd5frjqag4jnp7fvhzbx6kd6-activate.scm.drv- /gnu/store/qnchikcfqx8hn0a7cn45f0pnf664s0jk-shepherd.conf.drv+ /gnu/store/kammkm5z0ihjqalg0ijn69ffhdyzki47-profile.drv+ /gnu/store/07kxlp8a99mvx2zidnlz6rm4ak2az8d0-guix-1.0.1-13.50299ad+.drv+ /gnu/store/m9783fc7m360dk582b3mv2wgrsdz6amk-boot.drv+ /gnu/store/3v1whxi5qkp9cyfc3vjpvziwc9ms7y7k-shepherd.conf.drv+ /gnu/store/50halfax0zbiwpy47z6374ybh1mq1d5r-shepherd-guix-daemon.go.drv+ /gnu/store/g4m4mqiz9z4yd2iwzmb6f81vidw0k4bg-shepherd-guix-daemon.scm.drv /gnu/store/7n4cqlsbn7hywlwssxvax6j6b57gm1q4-shepherd-user-homes.go.drv /gnu/store/dl333r3dshzi5nb4qqrvcsp2hmk3hd9p-shepherd-user-homes.scm.drv /gnu/store/i96lsb7shixcczc62bfadbg1g73qp38l-shepherd-udev.go.drv /gnu/store/yv3maqmnqqpiqj2jk5ss574pzvgh9jin-shepherd-udev.scm.drv /gnu/store/s5w901l6zl0ql800bc9cndnskqdhnsxm-shepherd-file-system--tmp.go.drv /gnu/store/a5nb6vhs86g76ww5bmpphi398pggnga7-shepherd-file-system--tmp.scm.drv- /gnu/store/sjn7zb56x72lh6i7arkh6gpd639g7d17-shepherd-guix-daemon.go.drv- /gnu/store/rww6z6m3nz6s7h54xklwj3plylg1f0yc-shepherd-guix-daemon.scm.drv- /gnu/store/lmbja82mymwsn3kmxwfy8g7s46xac443-linux-vm-loader.drv- /gnu/store/z8y0v374himjlig4qwjisv1xa7rk7r0l-builder-in-linux-vm.drv- /gnu/store/14bw0x4dq0g262vk4pjh3dlha6x3gz0s-module-import-compiled.drv- /gnu/store/nbkfy5wjpia5y7hj1p9j5hmbv42j4zp5-module-import.drv-The following grafts will be made:- /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drv- /gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drv+ /gnu/store/nhi2s5zcyd5frjqag4jnp7fvhzbx6kd6-activate.scm.drv The following profile hooks will be built:- /gnu/store/96274clz8449s7s18a91sa31d1ilmi0p-fonts-dir.drv- /gnu/store/30lvdbci7v9zqgn3nqjy1vgbpv5k4b98-ca-certificate-bundle.drv- /gnu/store/b5dspr8576n0j3vl2cjsr7zrfdp380cw-guix-package-cache.drv- /gnu/store/chjdvqjbrnb7cqla43n5rvqia5d4f4mg-fonts-dir.drv- /gnu/store/kh7wixk3i5db2ym48ddyrdbggw8ccxp8-info-dir.drv- /gnu/store/x3bp2acfy04w9r9l11w30l9z0hpsii5a-manual-database.drv- /gnu/store/bhla9fihy35pgc3bwszfxvsfjir71v88-glib-schemas.drv- /gnu/store/isb4444058amfr4sipqmffcrgisx75gs-ca-certificate-bundle.drv- /gnu/store/l8qgqaxq1xcb8jk3lqmzzrfiv8hzpna1-xdg-desktop-database.drv- /gnu/store/x0vhd98kg66pzfwffbi45f76126by816-xdg-mime-database.drv- /gnu/store/xs4k7nmrpbjsy0a5k6lsbdxc2n4i23g4-info-dir.drv- /gnu/store/zffqfc9w73sy815av7hwincbqpl7hbkr-manual-database.drv-building /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-import.drv...+ /gnu/store/4j2hrilvx5rfycqs1sccd39jy5yjhxy0-xdg-mime-database.drv+ /gnu/store/4rdg1bi6xxn85zq5cjqc3bdfksx14913-info-dir.drv+ /gnu/store/c59p1krnc51qlbr5vnxjx6bg3rrixca4-glib-schemas.drv+ /gnu/store/drf1pi6m91b6qra3p6hrknfzh7gcd51z-fonts-dir.drv+ /gnu/store/fwal8vsrjzpbwljnihvv66k9ikkfx2ma-xdg-desktop-database.drv+ /gnu/store/jzp4ps09ipy0kcc6ybx5967vi3xlq7aa-manual-database.drv+ /gnu/store/m7yl2xvk07l37l19wp2hfbvhzl3583ji-ca-certificate-bundle.drv
So, we can see there would me many guix-* things to build without thehack.
Just building the OS using guix-current/pre-built, vs oldguix-current', vs the modern guix-current used for system tests:
guix-current/pre-built:
Toggle snippet (7 lines)time ./pre-inst-env guix system build -e '(begin (use-modules (gnu packages package-management)) (parameterize ((current-guix-package (current-guix/pre-built))) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-on-subvolume-os))))'[...]real 12m23.259suser 0m9.124ssys 0m0.986s
old guix-current:
Toggle snippet (7 lines)time ./pre-inst-env guix system build -e '(begin (use-modules (gnu packages package-management)) (parameterize ((current-guix-package (current-guix))) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-on-subvolume-os))))'[...]real 45m45.572suser 0m10.428ssys 0m1.279s
And with the new "guix-current", computed with (guix self):
Toggle snippet (340 lines)time ./pre-inst-env guix system build -e '(begin> (use-modules ((gnu ci) #:select (channel-instance->package))> (guix monads)> (guix channels)> (guix store)> ((guix status) #:select (with-status-verbosity))> ((guix git-download) #:select (git-predicate))> (guix utils)> (gnu packages package-management))> (with-store store> (with-status-verbosity 2> (run-with-store store> (mlet* %store-monad> ((source-dir -> "/home/maxim/src/guix")> (source (interned-file source-dir> "guix-source"> #:recursive? #t> #:select? (or (git-predicate> source-dir)> (const #t))))> (instance -> (checkout->channel-instance source))> (new-guix-current -> (channel-instance->package instance)))> (return (parameterize ((current-guix-package new-guix-current))> ((@@ (gnu tests install) operating-system-with-current-guix)> (@@ (gnu tests install) %btrfs-root-on-subvolume-os)))))))))'
substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%The following file will be downloaded: /gnu/store/7r7lbghps6qcl10qb6m321a3bgpr72fi-compute-guix-derivationsubstituting /gnu/store/7r7lbghps6qcl10qb6m321a3bgpr72fi-compute-guix-derivation...downloading from http://10.42.0.199/nar/gzip/7r7lbghps6qcl10qb6m321a3bgpr72fi-compute-guix-derivation... compute-guix-derivation 124KiB/s 00:00 | 881B transferred
substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%\substitute: updating substitutes from 'http://10.42.0.199:80'... 100.0%substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%The following derivations will be built: /gnu/store/1kmbdnkdip0xbdi4h09jj44nccmpmxh6-system.drv /gnu/store/a2dl48yn635qqbga72gwkqnypd45lxaf-profile.drv /gnu/store/3rqfd301xgwlaacwppswdxshlc13ky7p-profile.drv /gnu/store/2hd5a6klgq8zz22rsm3jd4wqw6cbcmbq-profile.drv /gnu/store/hb87zw934jkgxwkgbbfykwaq55p6pzlq-guix-000000000.drv /gnu/store/65dva2y1zq173i93z57xzffn34rmfbgw-guix-daemon.drv /gnu/store/cjzvm56h61zhwd56g1ksi91spq567b4b-guix-command.drv /gnu/store/flii6im368mj1mlwb1xmnvwhibll0acg-guix-module-union.drv /gnu/store/mx5kd00k1axs9xrgwn5hibiidbxshy3g-guix-000000000-modules.drv /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-modules.drv /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv /gnu/store/rhk9cknm5wbk30slzzrr52app8mfn4a2-guix-packages-modules.drv /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv /gnu/store/ybxk6d3bccnz52d2s55gcang7795cy3l-guix-cli-modules.drv /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv /gnu/store/ysr4d2bqhs4c4viwyk9pvcjcnwv4pnr8-guix-system-tests-modules.drv /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv /gnu/store/z3mzdfm2x2jrab7g3yhcg06lrgpq2ijz-guix-system-modules.drv /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drv /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drv /gnu/store/zdqspx48gmwa9xv2ibn993qfswq9zgkf-inferior-script.scm.drv /gnu/store/ixk9m5hqwj42kdzh88vwy06alk9bw811-boot.drv /gnu/store/jp62bqlvch38sqcqkxk3ddwih84qz8ka-shepherd.conf.drv /gnu/store/7wkb1al9lxp5k84k9b1i5v7h69x9p3wr-shepherd-guix-daemon.go.drv /gnu/store/5688khnjjabnh8bnn4hc41j05h1larh9-shepherd-guix-daemon.scm.drvThe following grafts will be made: /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drv /gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drvThe following profile hooks will be built: /gnu/store/1li6nkn0p7zikf5y36ljir2n53rf81cg-fonts-dir.drv /gnu/store/841rih0j6iskwdxvay7cm94l3vn4idl7-guix-package-cache.drv /gnu/store/8k7vn4fbwqvlmhsv604v7zkgils5j0f4-manual-database.drv /gnu/store/qc53qlnzwxlhlm01fxp45ppdnrzw0lfz-info-dir.drv /gnu/store/qpcnvr43c5rl6bgpsj7l3m38r6xndz7j-ca-certificate-bundle.drv /gnu/store/scm0rsny7n5kmryffp081hdh6rh2659l-fonts-dir.drv /gnu/store/44wi6c2lq0mpkmx940wsi56fmxr8fjh4-ca-certificate-bundle.drv /gnu/store/d80j7mvj59m6h33m3c72mwfckb9xrn7r-info-dir.drv /gnu/store/x1cfgs17hpiw33fpq8gj51ldykf8wd25-manual-database.drvbuilding /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drv...Your input po file ./guix-manual.de.po seems outdated (The amount of entries differ between files: 7994 is not 8473). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.de.po seems outdated (The amount of entries differ between files: 7994 is not 281). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.es.po seems outdated (The amount of entries differ between files: 7994 is not 8473). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.es.po seems outdated (The amount of entries differ between files: 7994 is not 281). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.fr.po seems outdated (The amount of entries differ between files: 7994 is not 8473). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.fr.po seems outdated (The amount of entries differ between files: 7994 is not 281). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.ru.po seems outdated (The amount of entries differ between files: 7994 is not 8473). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.ru.po seems outdated (The amount of entries differ between files: 7994 is not 281). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.zh_CN.po seems outdated (The amount of entries differ between files: 7994 is not 8473). Please consider running po4a-updatepo to refresh it.Your input po file ./guix-manual.zh_CN.po seems outdated (The amount of entries differ between files: 7994 is not 281). Please consider running po4a-updatepo to refresh it.successfully built /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinfo.drvapplying 2 grafts for /gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drv...grafting '/gnu/store/mqlwm1gfp1wz7i74z2rifv51hscl2201-libgit2-0.28.4' -> '/gnu/store/7ymrcgnz6v4x1krljh60za1fx0wz57ny-libgit2-0.28.4'...successfully built /gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drvbuilding /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drv..../guix.de.texi:2286: warning: @node name should not contain `,': Tastaturbelegung, Netzwerkanbindung und Partitionierung./guix.de.texi:29751: warning: @node name should not contain `,': Vorbereitung, um die Bootstrap-Bin�rdateien zu verwenden./guix.ru.texi:932: warning: accent command `@,' must not be followed by whitespaceWide character in warn at /gnu/store/irj21yhgls637jhhkb5yr79s76c96maq-texinfo-6.6/bin/makeinfo line 656../guix.ru.texi:3977: warning: `.' or `,' must follow @xref, not дsuccessfully built /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drvapplying 1 graft for /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drv...grafting '/gnu/store/qi80syzn4dhxbwwwlqlww5v042kfkmx3-guile3.0-git-0.3.0' -> '/gnu/store/1hapil0ym1k3cii3j95pmabgnxi7c9m0-guile3.0-git-0.3.0'...successfully built /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drvprocess 5055 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 0.0 (normalized: 0.0)building /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv...sending 23 store items (54 MiB) to '10.42.0.199'...exporting path `/gnu/store/c2mxnc0dvi88dq5iacq78xchlcp6f2d2-guix-packages-base-source'exporting path `/gnu/store/d3s80rm5pyggyqk71mwrsqzqahjc8jqr-guix-packages-base-builder'exporting path `/gnu/store/4rjdijy36w6zx99bgqlb40nawipcm4w1-libgit2-0.28.4-guile-builder'exporting path `/gnu/store/w7xwnvv15b6s062jfaqkwnry7padw936-http-parser-2.9.3-checkout.drv'exporting path `/gnu/store/v6p9i2alpmsldsbjnq2g46rrnn2kwvvg-http-parser-2.9.3.drv'exporting path `/gnu/store/29l03448v04pniv0rjlmclag9ga66yj6-libgit2-0.28.4.drv'exporting path `/gnu/store/j823iyw1c851wmmlfbb8vxyy4hcvqcdz-libgit2-0.28.4-guile-builder'exporting path `/gnu/store/dnl877iincgcw7lw493h5nd4llxqjw7a-libgit2-0.28.4.drv'exporting path `/gnu/store/i63fzcsg2qrzkj53ri3jglzg1jqxcg6q-guile3.0-git-0.3.0-guile-builder'exporting path `/gnu/store/ls7zbcnzl4khfqb64nm9nd9yri1x4mwi-guile3.0-git-0.3.0-guile-builder'exporting path `/gnu/store/rp09b776n1a98fbpy1cbw6v7np66x3b6-guile3.0-git-0.3.0.drv'exporting path `/gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-git-0.3.0.drv'exporting path `/gnu/store/rsc33ni89kzqbjwv2drm1w7qyyqzvw8g-guix-extra-source'exporting path `/gnu/store/0szskn0spa0gkf36p9fkrl9b4r7x67vc-guix-extra-builder'exporting path `/gnu/store/vg4zq88aw4y1skaljyd092yricg0krj0-guix-extra.drv'exporting path `/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv'exporting path `/gnu/store/7ymrcgnz6v4x1krljh60za1fx0wz57ny-libgit2-0.28.4'exporting path `/gnu/store/1hapil0ym1k3cii3j95pmabgnxi7c9m0-guile3.0-git-0.3.0'exporting path `/gnu/store/32569wrdn5wfq864iz889fv3hrz0a35c-guix-extra'exporting path `/gnu/store/bgwcdqnrb3zqs91hgm4vsxprqmnxb6z0-guix-core'exporting path `/gnu/store/gdkb4vs4i1pbaifihdnkgvw3bklcdafq-config.scm'exporting path `/gnu/store/grfziyz24rkbal06ba8kb6d47zhv5m8i-guix-core-source'offloading '/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv' to '10.42.0.199'...offloading build of /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv to '10.42.0.199'substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%@ build-started /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv - x86_64-linux /var/log/guix/drvs/5z//hgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv.bz2 12591[546/546] compiling... 100.0% of 273 files@ build-succeeded /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv -retrieving 1 store item from '10.42.0.199'...importing file or directory '/gnu/store/60yrpv6cfzl9pzw4sgawfw0b8bx679js-guix-packages-base'...found valid signature for '/gnu/store/60yrpv6cfzl9pzw4sgawfw0b8bx679js-guix-packages-base'done with offloaded '/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drv'successfully built /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.drvbuilding /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-modules.drv...process 5174 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.24 (normalized: 2.24)waiting for locks or build slots...successfully built /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-modules.drvprocess 5174 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 1.97 (normalized: 1.97)building /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv...sending 4 store items (5 MiB) to '10.42.0.199'...exporting path `/gnu/store/37ljzr1akxh64fbwf7rhn5qdsxs62zh5-guix-packages-builder'exporting path `/gnu/store/qymkn55sgl7ln68cmkp60xx4h6kckg7p-guix-packages-source'exporting path `/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv'offloading '/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv' to '10.42.0.199'...offloading build of /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv to '10.42.0.199'substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%@ build-started /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv - x86_64-linux /var/log/guix/drvs/il//y3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv.bz2 12691[422/422] compiling... 100.0% of 211 files@ build-succeeded /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv -retrieving 1 store item from '10.42.0.199'...importing file or directory '/gnu/store/d5bz30n1r7fg8xybqip2prrxmfy07jz1-guix-packages'...found valid signature for '/gnu/store/d5bz30n1r7fg8xybqip2prrxmfy07jz1-guix-packages'done with offloaded '/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv'successfully built /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drvbuilding /gnu/store/rhk9cknm5wbk30slzzrr52app8mfn4a2-guix-packages-modules.drv...process 5205 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.73 (normalized: 2.73)waiting for locks or build slots...successfully built /gnu/store/rhk9cknm5wbk30slzzrr52app8mfn4a2-guix-packages-modules.drvprocess 5205 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.52 (normalized: 2.52)process 5205 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.31 (normalized: 2.31)process 5205 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.13 (normalized: 2.13)process 5205 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 1.96 (normalized: 1.96)building /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv...sending 4 store items (2 MiB) to '10.42.0.199'...exporting path `/gnu/store/c5f1649rxrhfdb5vfr4s6i7yb4yqhidr-guix-system-source'exporting path `/gnu/store/nw9kr3wkgfks44wrf8zw9y0l50bnzg77-guix-system-builder'exporting path `/gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv'offloading '/gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv' to '10.42.0.199'...offloading build of /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv to '10.42.0.199'substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%@ build-started /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv - x86_64-linux /var/log/guix/drvs/if//qlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv.bz2 12805[156/156] compiling... 100.0% of 78 files@ build-succeeded /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv -retrieving 1 store item from '10.42.0.199'...importing file or directory '/gnu/store/6swg1fk14gw145ihh0ml1549cdqvq9n1-guix-system'...found valid signature for '/gnu/store/6swg1fk14gw145ihh0ml1549cdqvq9n1-guix-system'done with offloaded '/gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drv'successfully built /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.drvprocess 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 3.05 (normalized: 3.05)building /gnu/store/z3mzdfm2x2jrab7g3yhcg06lrgpq2ijz-guix-system-modules.drv...waiting for locks or build slots...successfully built /gnu/store/z3mzdfm2x2jrab7g3yhcg06lrgpq2ijz-guix-system-modules.drvprocess 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.81 (normalized: 2.81)process 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.58 (normalized: 2.58)process 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.37 (normalized: 2.37)process 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.18 (normalized: 2.18)process 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.01 (normalized: 2.01)process 5266 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 1.85 (normalized: 1.85)building /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv...sending 4 store items (1 MiB) to '10.42.0.199'...exporting path `/gnu/store/nlrwldyvnmbih5qzcv8xhby5jcnnr5gn-guix-cli-source'exporting path `/gnu/store/z8dgrdv8vqxwn2p8480q6x5fwiyc9f0q-guix-cli-builder'exporting path `/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv'offloading '/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv' to '10.42.0.199'...offloading build of /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv to '10.42.0.199'substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%@ build-started /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv - x86_64-linux /var/log/guix/drvs/6m//dpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv.bz2 12943[106/106] compiling... 100.0% of 53 files@ build-succeeded /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv -retrieving 1 store item from '10.42.0.199'...importing file or directory '/gnu/store/7gh81jn54ak2qw3ahq4nb9dc0zzn0h4v-guix-cli'...found valid signature for '/gnu/store/7gh81jn54ak2qw3ahq4nb9dc0zzn0h4v-guix-cli'done with offloaded '/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv'successfully built /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drvbuilding /gnu/store/ybxk6d3bccnz52d2s55gcang7795cy3l-guix-cli-modules.drv...process 5300 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.28 (normalized: 2.28)waiting for locks or build slots...successfully built /gnu/store/ybxk6d3bccnz52d2s55gcang7795cy3l-guix-cli-modules.drvprocess 5300 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 2.1 (normalized: 2.1)process 5300 acquired build slot '/var/guix/offload/10.42.0.199:22/0'load on machine '10.42.0.199' is 1.93 (normalized: 1.93)building /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv...sending 4 store items (0 MiB) to '10.42.0.199'...exporting path `/gnu/store/k4vp8f9prcfc29lqmzpygrsx8qxmmzs3-guix-system-tests-builder'exporting path `/gnu/store/sbrl1022yphyzdcjilpabfgq102rxxkc-guix-system-tests-source'exporting path `/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv'offloading '/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv' to '10.42.0.199'...offloading build of /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv to '10.42.0.199'substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%@ build-started /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv - x86_64-linux /var/log/guix/drvs/fw//r4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv.bz2 13042[ 5/ 46] loading... 21.7% of 23 filesrandom seed for tests: 1582005862[ 46/ 46] compiling... 100.0% of 23 files@ build-succeeded /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv -retrieving 1 store item from '10.42.0.199'...importing file or directory '/gnu/store/c98xnkcbm1bd3j69k08kr3d8msm5zg94-guix-system-tests'...found valid signature for '/gnu/store/c98xnkcbm1bd3j69k08kr3d8msm5zg94-guix-system-tests'done with offloaded '/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drv'successfully built /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.drvbuilding /gnu/store/ysr4d2bqhs4c4viwyk9pvcjcnwv4pnr8-guix-system-tests-modules.drv...successfully built /gnu/store/ysr4d2bqhs4c4viwyk9pvcjcnwv4pnr8-guix-system-tests-modules.drvbuilding /gnu/store/mx5kd00k1axs9xrgwn5hibiidbxshy3g-guix-000000000-modules.drv...successfully built /gnu/store/mx5kd00k1axs9xrgwn5hibiidbxshy3g-guix-000000000-modules.drvbuilding /gnu/store/flii6im368mj1mlwb1xmnvwhibll0acg-guix-module-union.drv...successfully built /gnu/store/flii6im368mj1mlwb1xmnvwhibll0acg-guix-module-union.drvbuilding /gnu/store/cjzvm56h61zhwd56g1ksi91spq567b4b-guix-command.drv...successfully built /gnu/store/cjzvm56h61zhwd56g1ksi91spq567b4b-guix-command.drvbuilding /gnu/store/65dva2y1zq173i93z57xzffn34rmfbgw-guix-daemon.drv...successfully built /gnu/store/65dva2y1zq173i93z57xzffn34rmfbgw-guix-daemon.drvbuilding /gnu/store/hb87zw934jkgxwkgbbfykwaq55p6pzlq-guix-000000000.drv...successfully built /gnu/store/hb87zw934jkgxwkgbbfykwaq55p6pzlq-guix-000000000.drvbuilding CA certificate bundle...successfully built /gnu/store/qpcnvr43c5rl6bgpsj7l3m38r6xndz7j-ca-certificate-bundle.drvbuilding fonts directory...successfully built /gnu/store/scm0rsny7n5kmryffp081hdh6rh2659l-fonts-dir.drvbuilding directory of Info manuals...successfully built /gnu/store/qc53qlnzwxlhlm01fxp45ppdnrzw0lfz-info-dir.drvbuilding database for manual pages...Creating manual page database...[ 1/ 1] building list of man-db entries...0 entries processed in 0.0 ssuccessfully built /gnu/store/8k7vn4fbwqvlmhsv604v7zkgils5j0f4-manual-database.drvbuilding /gnu/store/2hd5a6klgq8zz22rsm3jd4wqw6cbcmbq-profile.drv...successfully built /gnu/store/2hd5a6klgq8zz22rsm3jd4wqw6cbcmbq-profile.drvbuilding /gnu/store/zdqspx48gmwa9xv2ibn993qfswq9zgkf-inferior-script.scm.drv...successfully built /gnu/store/zdqspx48gmwa9xv2ibn993qfswq9zgkf-inferior-script.scm.drvbuilding package cache...(repl-version 0 0)Generating package cache for '/gnu/store/lxl90crn49lgnmxd13ljka6w6dz6vm9p-profile'...(values (value "/gnu/store/ckyfrrsk8fdx9lzkiwvf0a3p79ll2gfg-guix-package-cache/lib/guix/package.cache"))successfully built /gnu/store/841rih0j6iskwdxvay7cm94l3vn4idl7-guix-package-cache.drvbuilding /gnu/store/3rqfd301xgwlaacwppswdxshlc13ky7p-profile.drv...successfully built /gnu/store/3rqfd301xgwlaacwppswdxshlc13ky7p-profile.drvbuilding CA certificate bundle...successfully built /gnu/store/44wi6c2lq0mpkmx940wsi56fmxr8fjh4-ca-certificate-bundle.drvbuilding fonts directory...successfully built /gnu/store/1li6nkn0p7zikf5y36ljir2n53rf81cg-fonts-dir.drvbuilding directory of Info manuals...successfully built /gnu/store/d80j7mvj59m6h33m3c72mwfckb9xrn7r-info-dir.drvbuilding database for manual pages...Creating manual page database...[ 45/ 45] building list of man-db entries...1039 entries processed in 3.2 ssuccessfully built /gnu/store/x1cfgs17hpiw33fpq8gj51ldykf8wd25-manual-database.drvbuilding /gnu/store/5688khnjjabnh8bnn4hc41j05h1larh9-shepherd-guix-daemon.scm.drv...successfully built /gnu/store/5688khnjjabnh8bnn4hc41j05h1larh9-shepherd-guix-daemon.scm.drvbuilding /gnu/store/a2dl48yn635qqbga72gwkqnypd45lxaf-profile.drv...
warning: collision encountered: /gnu/store/zg26g1i42sfn26ll4k5i3wb20zmwmpah-info-dir/share/info/dir /gnu/store/ma7ccwpzsypkxp88j2jlr4vq1gad06vd-profile/share/info/dirwarning: choosing /gnu/store/zg26g1i42sfn26ll4k5i3wb20zmwmpah-info-dir/share/info/dir
warning: collision encountered: /gnu/store/5al8wjz7522q8rqzyfmz46mlbzm70jzj-manual-database/share/man/index.db /gnu/store/ma7ccwpzsypkxp88j2jlr4vq1gad06vd-profile/share/man/index.dbwarning: choosing /gnu/store/5al8wjz7522q8rqzyfmz46mlbzm70jzj-manual-database/share/man/index.dbsuccessfully built /gnu/store/a2dl48yn635qqbga72gwkqnypd45lxaf-profile.drvbuilding /gnu/store/7wkb1al9lxp5k84k9b1i5v7h69x9p3wr-shepherd-guix-daemon.go.drv...successfully built /gnu/store/7wkb1al9lxp5k84k9b1i5v7h69x9p3wr-shepherd-guix-daemon.go.drvbuilding /gnu/store/jp62bqlvch38sqcqkxk3ddwih84qz8ka-shepherd.conf.drv...successfully built /gnu/store/jp62bqlvch38sqcqkxk3ddwih84qz8ka-shepherd.conf.drvbuilding /gnu/store/ixk9m5hqwj42kdzh88vwy06alk9bw811-boot.drv...successfully built /gnu/store/ixk9m5hqwj42kdzh88vwy06alk9bw811-boot.drvbuilding /gnu/store/1kmbdnkdip0xbdi4h09jj44nccmpmxh6-system.drv...successfully built /gnu/store/1kmbdnkdip0xbdi4h09jj44nccmpmxh6-system.drv/gnu/store/mv1c4cv6c1wws712zi4wz8l6ab8gwn85-system
real 58m19.825suser 3m42.533ssys 0m1.936s
I've left the full log because it did most poorly, at nearly an hour.
Next I'll try to verify if this long build is triggered amongst thecommits of this change set.
Maxim
M
M
Maxim Cournoyer wrote on 18 Feb 2020 22:27
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87sgj7wpqa.fsf@gmail.com
Hello Ludovic!
I have more benchmark results. Not to be compared with the previousresults, as these were executed on a much faster machine (24 cores vs 4cores), with an SSD instead of a rotative disk.

Commands used:
current-guix/pre-built:
Toggle snippet (15 lines)time ./pre-inst-env guix system build -e \'(begin (use-modules (gnu packages package-management)) (parameterize ((current-guix-package (current-guix/pre-built))) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-os))))'
current-guix (old fashionned):
Toggle snippet (15 lines)time ./pre-inst-env guix system build -e \'(begin (use-modules (gnu packages package-management)) (parameterize ((current-guix-package (current-guix))) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-os))))'
new current-guix (guix self):
Toggle snippet (27 lines)time ./pre-inst-env guix system build -e \'(begin (use-modules ((gnu ci) #:select (channel-instance->package)) (guix monads) (guix channels) (guix store) ((guix status) #:select (with-status-verbosity)) ((guix git-download) #:select (git-predicate)) (guix utils) (gnu packages package-management)) (with-store store (with-status-verbosity 2 (run-with-store store (mlet* %store-monad ((source-dir -> "/home/mcournoyer/src/guix") (source (interned-file source-dir "guix-source" #:recursive? #t #:select? (or (git-predicate source-dir) (const #t)))) (instance -> (checkout->channel-instance source)) (new-guix-current -> (channel-instance->package instance))) (return (parameterize ((current-guix-package new-guix-current)) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-os)))))))))'
Methodology:1. Break at each commit of the current change set, run make, and run the three above commands in the order they appear.2. Record the "real" component of the time results of each commit/command in the table below.
| Commit | current-guix/pre-built | old current-guix | new current-guix ||--------------------------------------------------------------+------------------------+------------------+------------------|| linux-boot: Ensure volatile root is mounted read-only. | 2m2.245s | 13m39.669s | 3m47.066s || file-systems: Add a 'file-system-device->string' procedure. | 2m12.576s | 13m42.906s | 3m43.212s || gnu: linux-boot: Refactor boot-system. | 1m53.928s | 13m48.825s | 9m53.133s || file-systems: Represent the file system options as an alist. | 2m12.530s | "" | 10m3.523s || gnu: linux-boot: Honor the "--root-options" kernel argument. | "" | "" | 11m10.448s || gnu: linux-boot: Filter out file system independent options. | "" | "" | 5m4.997s || bootloader: grub: Allow booting from a Btrfs subvolume. | 2m13.375s | 13m44.671s | 3m38.815s ||--------------------------------------------------------------+------------------------+------------------+------------------|
This machine appears to be 5 times faster (at this task) than theprevious one used, to give an idea of the time someone would have towait just to build the operating system to test. An x200 would be evenslightly slower that than.
One of the things that seems costly is rebuilding the documentation.
Maxim
M
M
Maxim Cournoyer wrote on 19 Feb 2020 03:52
Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
875zg2xtsb.fsf@gmail.com
Hello Ludovic,
Here comes part 2!
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (37 lines)>> From 6cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Sun, 14 Jul 2019 20:50:23 +0900>> Subject: [PATCH 8/9] bootloader: grub: Allow booting from a Btrfs subvolume.>>>> * gnu/bootloader/grub.scm (grub-configuration-file) [btrfs-subvolume-path]:>> New parameter. When it is defined, prepend its value to the kernel and>> initrd file paths.>> * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.>> * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.>> * gnu/system/file-systems.scm (btrfs-subvolume?)>> (btrfs-store-subvolume-path): New procedures.>> * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs subvolume path>> of the GNU store to the `operating-system-bootcfg' procedure, using the new>> BTRFS-SUBVOLUME-PATH argument.>> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of>> subvolumes. Document the new `properties' field of the `<file-system>'>> record.>> * gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".>> Neat!>>> (define* (grub-configuration-file config entries>> #:key>> (system (%current-system))>> - (old-entries '()))>> + (old-entries '())>> + btrfs-subvolume-path)>> "Return the GRUB configuration file corresponding to CONFIG, a>> <bootloader-configuration> object, and where the store is available at>> STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu>> -entries corresponding to old generations of the system.">> +entries corresponding to old generations of the system. BTRFS-SUBVOLUME-PATH>> +may be used to specify on which subvolume a Btrfs root file system resides.">> (Nitpick: s/path/file name/ :-))
I stand corrected! From '(Standards)GNU Manuals':
Please do not use the term "pathname" that is used in Unix documentation; use "file name" (two words) instead. We use the term "path" only for search paths, which are lists of directory names.
Toggle quote (10 lines)> It’s a bit problematic that (1) GRUB needs explicit Btrfs support, and> (2) other bootloaders will silently ignore the option, due to> #:allow-other-keys.>> I don’t have a better idea, but it’d be great if Btrfs support could be> made bootloader-independent, and if it could be somewhat> not-too-btrfs-specific, if that is possible at all.>> Thoughts?
I have no idea how Btrfs subvolumes are handled (if at all) on U-Boot orother bootloaders than GRUB. All I know is that for GRUB they need tohandle subvolumes in a special manner in their own grub-mkconfig tool(which we bypass).
Also, I'm afraid subvolumes are very Btrfs specific :-). It doesn'texist in traditional file systems like EXT4. I think ZFS must havesomething similar, though.
Toggle quote (28 lines)>> + (properties file-system-properties ; list of name-value pairs>> + (default '()))>> (location file-system-location>> (default (current-source-location))>> (innate)))>> @@ -582,4 +589,48 @@ system has the given TYPE.">> (or (string-prefix-ci? "x-" option-name)>> (member option-name %file-system-independent-mount-options))))>>>> +(define (btrfs-subvolume? fs)>> + "Predicate to check if FS, a file-system object, is a Btrfs subvolume.">> + (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))>> + (option-keys (map (match-lambda>> + ((key . value) key)>> + (key key))>> + (file-system-options fs))))>> + (find (cut string-prefix? "subvol" <>) option-keys)))>> I wonder if we can avoid special support in the <file-system> API for> Btrfs.>>> + (error "The store is on a Btrfs subvolume, but the \>> +subvolume name is unknown.>> +Hint: Define the \"btrfs-subvolume-path\" file system property or>> +use the \"subvol\" Btrfs file system option."))))
> Rather use ‘raise’ with ‘&message’ and ‘&fix-hint’ conditions.
I tried this, but importing (guix utils) to acces &fix-hint caused the initRAM disk to fail mysteriously:
Toggle snippet (63 lines)[ 0.614503] Run /init as init processGC Warning: pthread_getattr_np or pthread_attr_getstack failed for main threadGC Warning: Couldn't read /proc/statBacktrace:In ice-9/boot-9.scm: 222:29 19 (map1 (((ice-9 match)) ((rnrs bytevectors)) ((srfi 222:29 18 (map1 (((rnrs bytevectors)) ((srfi srfi-1)) ((srfi 222:29 17 (map1 (((srfi srfi-1)) ((srfi srfi-2)) ((srfi #)) (#) 222:29 16 (map1 (((srfi srfi-2)) ((srfi srfi-9)) ((srfi #)) (#) 222:29 15 (map1 (((srfi srfi-9)) ((srfi srfi-26)) ((srfi #)) (#) 222:29 14 (map1 (((srfi srfi-26)) ((srfi srfi-35)) ((srfi # #)) 222:29 13 (map1 (((srfi srfi-35)) ((srfi srfi-9 gnu)) ((guix ))[ 0.657578] random: fast init done 222:29 12 (map1 (((srfi srfi-9 gnu)) ((guix records)) ((guix 222:29 11 (map1 (((guix records)) ((guix utils)) ((gnu system )))) 222:17 10 (map1 (((guix utils)) ((gnu system uuid)))) 2800:17 9 (resolve-interface (guix utils) #:select _ #:hide _ # _ In ice-9/threads.scm: 390:8 8 (_ _)In ice-9/boot-9.scm: 2726:13 7 (_)In ice-9/threads.scm: 390:8 6 (_ _)In ice-9/boot-9.scm: 2994:20 5 (_) 2312:4 4 (save-module-excursion #<procedure 7f455b6d48d0 at ice- 3014:26 3 (_)In unknown file: 2 (primitive-load-path "guix/utils" #<procedure 7f455b8fdIn guix/utils.scm: 508:24 1 (_)In unknown file: 0 (dynamic-func "strverscmp" #<dynamic-object #f>)ERROR: In procedure dynamic-func:In procedure dynamic-pointer: Symbol not found: strverscmp[ 0.697002] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100[ 0.697894] CPU: 0 PID: 1 Comm: init Not tainted 5.4.18-gnu #1[ 0.698592] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014[ 0.699938] Call Trace:[ 0.700240] dump_stack+0x6d/0x8d[ 0.700640] panic+0x10b/0x2f4[ 0.701010] do_exit+0x7e2/0xb80[ 0.701398] ? wake_up_state+0x1f/0x30[ 0.701847] ? signal_wake_up_state+0x24/0x40[ 0.702374] do_group_exit+0x44/0xa0[ 0.702805] __x64_sys_exit_group+0x1c/0x20[ 0.703306] do_syscall_64+0x5a/0x190[ 0.703748] entry_SYSCALL_64_after_hwframe+0x44/0xa9[ 0.704347] RIP: 0033:0x5df9c6[ 0.704716] Code: 00 00 00 be 3c 00 00 00 eb 19 66 2e 0f 1f 84 00 00 00 00 00 89 d7 89 f0 0f 05 48 3d 00 f0 ff ff 77 22 f4 89 d7 44 89 c0 0f 05 <48> 3d 00 f0 ff ff 76 e2 f7 d8 64 41 89 01 eb da 66 2e 0f 1f 84 00[ 0.706919] RSP: 002b:00007ffd9fa65228 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7[ 0.707808] RAX: ffffffffffffffda RBX: 00000000007c51f0 RCX: 00000000005df9c6[ 0.708643] RDX: 0000000000000001 RSI: 000000000000003c RDI: 0000000000000001[ 0.709482] RBP: 0000000000000001 R08: 00000000000000e7 R09: ffffffffffffffb0[ 0.710328] R10: 0000000000436340 R11: 0000000000000246 R12: 00000000007c51f0[ 0.711166] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000003[ 0.712026] Kernel Offset: 0x13000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)[ 0.713288] Rebooting in 1 seconds..file-size: /gnu/store/zfi66vny0h10d180xajgm4pq2vnvmc2z-nss-certs-3.49.1/etc/ssl/certs/NetLock_Arany_=Class_Gold=_F??tan??s??tv??ny:2.6.73.65.44.228.0.16.pem: No such file or directoryfile-size: /gnu/store/04xpkgf9zlhcngyr6gnhl4rb8g6v6i1i-profile/etc/ssl/certs/NetLock_Arany_=Class_Gold=_F??tan??s??tv??ny:2.6.73.65.44.228.0.16.pem: No such file or directory
The exception I had refactored to use with &fix-hint looked like:
Toggle snippet (10 lines)(raise (condition (&message (message "The store is on a Btrfs subvolume, \but the subvolume name is unknown.")) (&fix-hint (hint "Define the \"btrfs-subvolume-file-name\" \file system property or use the \"subvol\" Btrfs file systemoption."))))
So, I ended up using just a &message condition with the hint embedded in it.The attached patch (v3) incorporate the agreed changes so far.
The btrfs-root-on-subvolume-os test still passes.
Thank you for your patience,
Maxim
From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 17 Nov 2019 06:01:00 +0900Subject: [PATCH 1/8] gnu: tests: Reduce the time required to run the system tests.
When setting the GUIX_DEV_HACKS environment variable, the Guix package usedinside the instrumented VMs recycles the binaries already found in the Guixcheckout of the developer instead of rebuilding Guix from scratch. Thisbrings the time required for this component from 20+ minutes down to 2-3minutes on an X200 machine.
* gnu/packages/package-management.scm (current-guix/pre-built): New procedure.* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, whenGUIX_DEV_HACKS is defined.--- build-aux/run-system-tests.scm | 11 ++++- gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
Toggle diff (108 lines)diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scmindex b0cb3bd2bf..04b6fa29c3 100644--- a/build-aux/run-system-tests.scm+++ b/build-aux/run-system-tests.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -58,8 +59,16 @@ instance." ;; of tests to run in the usual way: ;; ;; make check-system TESTS=installed-os++ ;; When the GUIX_DEV_HACKS environment variable is defined, override the+ ;; package returned by `current-guix' with a flavor that saves recompiling+ ;; Guix from scratch and reuse the developer's checkout binaries. The+ ;; override "builds" about 20 times faster than the regular `current-guix'+ ;; package, which can help speed iterative development. (parameterize ((current-guix-package- (channel-instance->package instance)))+ (if (getenv "GUIX_DEV_HACKS")+ (current-guix/pre-built)+ (channel-instance->package instance)))) (match (getenv "TESTS") (#f (all-system-tests))diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scmindex 422d4f1959..bd2ed85189 100644--- a/gnu/packages/package-management.scm+++ b/gnu/packages/package-management.scm@@ -468,6 +468,72 @@ out) and returning a package that uses that as its 'source'." #:recursive? #t #:select? (force select?)))))))) +(define-public (current-guix/pre-built)+ "Similar to `current-guix', but with a modified build procedure that+reuses the existing byte compiled artifacts to save recompilation time."++ (let* ( ;; The `current-source-directory' macro doesn't work from the REPL.+ ;; For testing, you can replace it with a static string pointing to+ ;; your Guix checkout directory.+ (repository-root (delay (canonicalize-path+ (string-append (current-source-directory)+ "/../.."))))+ (select? (lambda (file stat)+ (match (basename file)+ ((or ".git"+ "configure" "autom4te.cache"+ "config.log" "config.status"+ "stamp-1" "stamp-2" "stamp-3" "stamp-4" "stamp-5"+ "stamp-h1" "stamp-vti"+ "Makefile" "Makefile.in" ".libs"+ ".deps" ".dirstamp"+ "test-tmp"+ ) #f)+ (_ #t)))))+ (package+ (inherit guix)+ (version (string-append (package-version guix) "+"))+ (source (local-file (force repository-root) "guix-current"+ #:recursive? #t+ #:select? select?))+ (arguments+ (substitute-keyword-arguments (package-arguments guix)+ ((#:phases phases)+ `(modify-phases ,phases+ ;; XXX: References to tools such as 'mkdir' and 'install' are+ ;; captured in Makefile.in when 'autoconf' is run. It'd be nicer+ ;; to find those at configuration time.+ (delete 'copy-bootstrap-guile)+ (delete 'check)+ (delete 'disable-failing-tests)+ (delete 'strip) ;can't strip .go files anyway+ (replace 'build+ (lambda _+ ;; Set the write permission bit on some files that need to be+ ;; touched.+ (chmod "nix" #o777)+ (for-each (lambda (f)+ (chmod f #o666))+ (cons* "guix-daemon"+ (find-files "." ".*\\.(a|o)$")))++ ;; The following prevent 'make install' from rebuilding the+ ;; daemon and the documentation.+ (invoke "make" "--touch" "info"+ ;; TODO: Currently we must rebuild the daemon as it+ ;; was linked against external dependencies that+ ;; depend on the provenance of the profile (or+ ;; environment) that was used to build it.++ ;; If we could query the provenance of any profile,+ ;; we could make this package inherit from the guix+ ;; inferior that was used to provide such+ ;; dependencies. The most reliable way would+ ;; probably be to record that provenance at build+ ;; time (as a make target).+ ;"guix-daemon"+ ))))))))))+ ;;; ;;; Other tools.-- 2.25.0
From c6e00c0eb8b2ed0c758e9c1be28c6e93f4795a64 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 12:57:29 -0500Subject: [PATCH 2/8] linux-boot: Ensure volatile root is mounted read-only.
* gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY ispresent among the root file system flags when VOLATILE-ROOT? is #t.--- gnu/build/linux-boot.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Toggle diff (21 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 3d40a7d05d..4fb711b8f2 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -362,12 +362,12 @@ the last argument of `mknod'." "Mount the root file system of type TYPE at device ROOT. If VOLATILE-ROOT? is true, mount ROOT read-only and make it an overlay with a writable tmpfs using the kernel built-in overlayfs. FLAGS and OPTIONS indicates the options to use-to mount ROOT."+to mount ROOT, and behave the same as for the `mount' procedure." (if volatile-root? (begin (mkdir-p "/real-root")- (mount root "/real-root" type MS_RDONLY options)+ (mount root "/real-root" type (logior MS_RDONLY flags) options) (mkdir-p "/rw-root") (mount "none" "/rw-root" "tmpfs") -- 2.25.0
From c367fc7efeb8ff15c22a98f32098bbcdbf1457b6 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 23:56:45 -0500Subject: [PATCH 3/8] file-systems: Add a 'file-system-device->string' procedure.
* gnu/system/file-systems.scm (file-system-device->string): New procedure.* gnu/system.scm (bootable-kernel-arguments): Use it.* gnu/system/vm.scm (operating-system-uuid): Likewise.* guix/scripts/system.scm (display-system-generation): Likewise.--- gnu/system.scm | 15 +++++---------- gnu/system/file-systems.scm | 15 +++++++++++++++ gnu/system/vm.scm | 8 +------- guix/scripts/system.scm | 7 +------ 4 files changed, 22 insertions(+), 23 deletions(-)
Toggle diff (98 lines)diff --git a/gnu/system.scm b/gnu/system.scmindex 01baa248a2..2e6d03272d 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -142,16 +142,11 @@ (define (bootable-kernel-arguments system root-device) "Return a list of kernel arguments (gexps) to boot SYSTEM from ROOT-DEVICE." (list (string-append "--root="- (cond ((uuid? root-device)-- ;; Note: Always use the DCE format because that's- ;; what (gnu build linux-boot) expects for the- ;; '--root' kernel command-line option.- (uuid->string (uuid-bytevector root-device)- 'dce))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else root-device)))+ ;; Note: Always use the DCE format because that's what+ ;; (gnu build linux-boot) expects for the '--root'+ ;; kernel command-line option.+ (file-system-device->string root-device+ #:uuid-type 'dce)) #~(string-append "--system=" #$system) #~(string-append "--load=" #$system "/boot"))) diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex d47a514b66..3b599efa8e 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -30,6 +30,7 @@ #:export (file-system file-system? file-system-device+ file-system-device->string file-system-title ;deprecated file-system-mount-point file-system-type@@ -235,6 +236,20 @@ where both FILE1 and FILE2 are absolute file name. For example: (() #f))))))) +(define* (file-system-device->string device #:key uuid-type)+ "Return the string representations of the DEVICE field of a <file-system>+record. When the device is a UUID, its representation is chosen depending on+UUID-TYPE, a symbol such as 'dce or 'iso9660."+ (match device+ ((? file-system-label?)+ (file-system-label->string device))+ ((? uuid?)+ (if uuid-type+ (uuid->string (uuid-bytevector device) uuid-type)+ (uuid->string device)))+ ((? string?)+ device)))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/gnu/system/vm.scm b/gnu/system/vm.scmindex 81b2e06ba2..03a511cdde 100644--- a/gnu/system/vm.scm+++ b/gnu/system/vm.scm@@ -609,13 +609,7 @@ TYPE (one of 'iso9660 or 'dce). Return a UUID object." (let ((device (file-system-device fs))) (list (file-system-mount-point fs) (file-system-type fs)- (cond ((file-system-label? device)- (file-system-label->string device))- ((uuid? device)- (uuid->string device))- ((string? device)- device)- (else #f))+ (file-system-device->string device) (file-system-options fs)))) (if (eq? type 'iso9660)diff --git a/guix/scripts/system.scm b/guix/scripts/system.scmindex e69a3b6c97..b0386a1392 100644--- a/guix/scripts/system.scm+++ b/guix/scripts/system.scm@@ -517,12 +517,7 @@ list of services." (cond ((uuid? root-device) 0) ((file-system-label? root-device) 1) (else 2))- (cond ((uuid? root-device)- (uuid->string root-device))- ((file-system-label? root-device)- (file-system-label->string root-device))- (else- root-device)))+ (file-system-device->string root-device)) (format #t (G_ " kernel: ~a~%") kernel) -- 2.25.0
From 7593b5dfeb180acf51dd7f586f31b1c8c671f1fa Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:00:06 -0500Subject: [PATCH 4/8] linux-boot: Refactor boot-system.
The --root option can now be omitted, and inferred from the root file systemdeclaration instead.
* gnu/build/linux-boot.scm (boot-system): Remove nested definitions forroot-fs-type, root-fs-flags and root-fs-options, and bind those inside thelet* instead. Make "--root" take precedence over the device field stringrepresentation of the root file system.* doc/guix.texi (Initial RAM Disk): Document that "--root" can be leftunspecified.--- doc/guix.texi | 7 +++-- gnu/build/linux-boot.scm | 66 +++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 35 deletions(-)
Toggle diff (111 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 42d7cfa2e8..85cfabc2f3 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25917,9 +25917,10 @@ service activation programs and then spawns the GNU@tie{}Shepherd, the initialization system. @item --root=@var{root}-Mount @var{root} as the root file system. @var{root} can be a-device name like @code{/dev/sda1}, a file system label, or a file system-UUID.+Mount @var{root} as the root file system. @var{root} can be a device+name like @code{/dev/sda1}, a file system label, or a file system UUID.+When unspecified, the device name from the root file system of the+operating system declaration is used. @item --system=@var{system} Have @file{/run/booted-system} and @file{/run/current-system} point todiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 4fb711b8f2..c3229fa292 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -467,25 +467,13 @@ upon error." (define (root-mount-point? fs) (string=? (file-system-mount-point fs) "/")) - (define root-fs-type- (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-type fs)))- mounts)- "ext4"))-- (define root-fs-flags- (mount-flags->bit-mask (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-flags fs)))- mounts)- '())))-- (define root-fs-options- (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-options fs)))- mounts))+ (define (device-string->file-system-device device-string)+ ;; The "--root=SPEC" kernel command-line option always provides a+ ;; string, but the string can represent a device, a UUID, or a+ ;; label. So check for all three.+ (cond ((string-prefix? "/" device-string) device-string)+ ((uuid device-string) => identity)+ (else (file-system-label device-string)))) (display "Welcome, this is GNU's early boot Guile.\n") (display "Use '--repl' for an initrd REPL.\n\n")@@ -495,7 +483,27 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root-fs (find root-mount-point? mounts))+ (root-fs-type (or (and=> root-fs file-system-type)+ "ext4"))+ (root-fs-device (and=> root-fs file-system-device))+ (root-fs-flags (mount-flags->bit-mask+ (or (and=> root-fs file-system-flags)+ '())))+ (root-fs-options (if root-fs+ (file-system-options root-fs)+ '()))+ ;; --root takes precedence over the 'device' field of the root+ ;; <file-system> record.+ ;; TODO: Add options for the root file system type and the root+ ;; file system flags as well.+ (root-device (or (and=> (find-long-option "--root" args)+ device-string->file-system-device)+ root-fs-device))+ (root-options (if (null? root-fs-options)+ #f+ (file-system-options->string+ root-fs-options)))) (when (member "--repl" args) (start-repl))@@ -530,18 +538,12 @@ upon error." (setenv "EXT2FS_NO_MTAB_OK" "1") - (if root- ;; The "--root=SPEC" kernel command-line option always provides a- ;; string, but the string can represent a device, a UUID, or a- ;; label. So check for all three.- (let ((root (cond ((string-prefix? "/" root) root)- ((uuid root) => identity)- (else (file-system-label root)))))- (mount-root-file-system (canonicalize-device-spec root)- root-fs-type- #:volatile-root? volatile-root?- #:flags root-fs-flags- #:options root-fs-options))+ (if root-device+ (mount-root-file-system (canonicalize-device-spec root-device)+ root-fs-type+ #:volatile-root? volatile-root?+ #:flags root-fs-flags+ #:options root-options) (mount "none" "/root" "tmpfs")) ;; Mount the specified file systems.-- 2.25.0
From a9b65ec0b4aa80c99c544aad41ec19ab64b295b0 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 25 Sep 2019 22:43:41 +0900Subject: [PATCH 5/8] file-systems: Represent the file system options as an alist.
This allows accessing the parameter values easily, without having to parse astring.
* gnu/system/file-systems.scm (<file-system>): Update the default value of theOPTIONS field, doc.(%file-system-options): Field accessor renamed from `file-system-options'.(file-system-options, file-system-options->string): New procedures.* gnu/build/file-systems.scm (mount-file-system): Adapt.* gnu/services/base.scm (file-system->fstab-entry): Likewise.* tests/file-systems.scm: New tests.* doc/guix.texi (File Systems): Document the modified default value of the'file-system-options' field.--- doc/guix.texi | 11 ++++++----- gnu/build/file-systems.scm | 15 +++++++++------ gnu/services/base.scm | 35 +++++++++++++++++++---------------- gnu/system/file-systems.scm | 37 +++++++++++++++++++++++++++++++++++-- tests/file-systems.scm | 24 ++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 29 deletions(-)
Toggle diff (203 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 85cfabc2f3..5d526b1aee 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11405,11 +11405,12 @@ update time on the in-memory version of the file inode), and @xref{Mount-Unmount-Remount,,, libc, The GNU C Library Reference Manual}, for more information on these flags. -@item @code{options} (default: @code{#f})-This is either @code{#f}, or a string denoting mount options passed to the-file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library-Reference Manual}, for details and run @command{man 8 mount} for options for-various file systems.+@item @code{options} (default: @code{'()})+A list of parameters and/or of pairs of parameter name and values, as+strings. Those represent the mount options that are passed to the file+system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library+Reference Manual}, for details and run @command{man 8 mount} for options+for various file systems. @item @code{mount?} (default: @code{#t}) This value indicates whether to automatically mount the file system whendiff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scmindex ee6375515f..cfa3898f83 100644--- a/gnu/build/file-systems.scm+++ b/gnu/build/file-systems.scm@@ -662,12 +662,15 @@ corresponds to the symbols listed in FLAGS." (if options (string-append "," options) "")))))- (let ((type (file-system-type fs))- (options (file-system-options fs))- (source (canonicalize-device-spec (file-system-device fs)))- (mount-point (string-append root "/"- (file-system-mount-point fs)))- (flags (mount-flags->bit-mask (file-system-flags fs))))+ (let* ((type (file-system-type fs))+ (fs-options (file-system-options fs))+ (options (if (null? fs-options)+ #f+ (file-system-options->string fs-options)))+ (source (canonicalize-device-spec (file-system-device fs)))+ (mount-point (string-append root "/"+ (file-system-mount-point fs)))+ (flags (mount-flags->bit-mask (file-system-flags fs)))) (when (file-system-check? fs) (check-file-system source type)) diff --git a/gnu/services/base.scm b/gnu/services/base.scmindex 0c154d1c4e..6104b47870 100644--- a/gnu/services/base.scm+++ b/gnu/services/base.scm@@ -313,22 +313,25 @@ seconds after @code{SIGTERM} has been sent are terminated with (define (file-system->fstab-entry file-system) "Return a @file{/etc/fstab} entry for @var{file-system}."- (string-append (match (file-system-device file-system)- ((? file-system-label? label)- (string-append "LABEL="- (file-system-label->string label)))- ((? uuid? uuid)- (string-append "UUID=" (uuid->string uuid)))- ((? string? device)- device))- "\t"- (file-system-mount-point file-system) "\t"- (file-system-type file-system) "\t"- (or (file-system-options file-system) "defaults") "\t"-- ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we- ;; don't have anything sensible to put in there.- ))+ (let ((options (file-system-options file-system)))+ (string-append (match (file-system-device file-system)+ ((? file-system-label? label)+ (string-append "LABEL="+ (file-system-label->string label)))+ ((? uuid? uuid)+ (string-append "UUID=" (uuid->string uuid)))+ ((? string? device)+ device))+ "\t"+ (file-system-mount-point file-system) "\t"+ (file-system-type file-system) "\t"+ (if (null? options)+ "defaults"+ (file-system-options->string options)) "\t"++ ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields because we+ ;; don't have anything sensible to put in there.+ ))) (define (file-systems->fstab file-systems) "Return a @file{/etc} entry for an @file{fstab} describingdiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 3b599efa8e..c205feae70 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -37,6 +38,7 @@ file-system-needed-for-boot? file-system-flags file-system-options+ file-system-options->string file-system-mount? file-system-check? file-system-create-mount-point?@@ -97,8 +99,8 @@ (type file-system-type) ; string (flags file-system-flags ; list of symbols (default '()))- (options file-system-options ; string or #f- (default #f))+ (options %file-system-options ; list of strings and/or+ (default '())) ; pair of strings (mount? file-system-mount? ; Boolean (default #t)) (needed-for-boot? %file-system-needed-for-boot? ; Boolean@@ -250,6 +252,37 @@ UUID-TYPE, a symbol such as 'dce or 'iso9660." ((? string?) device))) +(define (file-system-options fs)+ "Return the options of a <file-system> record, as a list of options or+option/value pairs."++ ;; Support the deprecated options format (a string).+ (define (string->options str)+ (let ((options (string-split str #\,)))+ (map (lambda (param)+ (let ((=index (string-index param #\=)))+ (if =index+ (cons (string-take param =index)+ (string-drop param (1+ =index)))+ param)))+ options)))++ (let ((fs-options (%file-system-options fs)))+ (if (string? fs-options)+ (string->options fs-options)+ fs-options)))++(define (file-system-options->string options)+ "Return the string representation of the OPTIONS field of a <file-system>+record"+ (string-join (map (match-lambda+ ((key . value)+ (string-append key "=" value))+ (key+ key))+ options)+ ","))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 4c28d0ebc5..b9f4f50aad 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -64,4 +65,27 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(define %fs-with-deprecated-options-string+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (type "btrfs")+ (options "autodefrag,subvol=home,compress=lzo")))++(define %fs+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/root")+ (type "btrfs")+ (options '("autodefrag" ("subvol" . "root") ("compress" . "lzo")))))++(test-equal "<file-system> options given as a string (deprecated)"+ '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))+ (file-system-options %fs-with-deprecated-options-string))++(test-equal "<file-system> options conversion to string"+ "autodefrag,subvol=root,compress=lzo"+ (file-system-options->string+ (file-system-options %fs)))+ (test-end)-- 2.25.0
From 9e988968566f004f887080b02712043520d9327e Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:14:36 -0500Subject: [PATCH 6/8] linux-boot: Honor the "--root-options" kernel argument.
* gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernelargument, and use it when calling `mount-root-file-system'. Update doc.* doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options"argument.--- doc/guix.texi | 10 ++++++++++ gnu/build/linux-boot.scm | 16 +++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-)
Toggle diff (71 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 5d526b1aee..d6bfbd7b55 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @command{modprobe} command must be a comma-separated list of module names---e.g., @code{usbkbd,9pnet}. +@item --root-options=@var{options}@dots{}+@cindex mount options for the root file system, passed to initrd+@cindex rootflags, initrd+@cindex root-options, initrd+This argument allows passing one or multiple file system specific mount+options used by the initrd to mount the root file system. @var{options}+must be a comma-separated list of option names or option-value pairs.+When unspecified, the value of the options field of the root file system+of the operating system declaration is used.+ @item --repl Start a read-eval-print loop (REPL) from the initial RAM disk before it tries to load kernel modules and to mount the root file system. Ourdiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex c3229fa292..063daa4ca4 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -2,6 +2,7 @@ ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Guillaume Le Vaillant <glv@posteo.net>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE with 'loadkeys' (if KEYMAP-FILE is true), then setting up QEMU guest networking if QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file systems specified in MOUNTS, and finally booting into the new root if any. The initrd-supports kernel command-line options '--load', '--root', and '--repl'.+supports kernel command-line options '--load', '--root', '--root-options' and+'--repl'. Mount the root file system, specified by the '--root' command-line argument, if any.@@ -493,6 +495,7 @@ upon error." (root-fs-options (if root-fs (file-system-options root-fs) '()))+ ;; --root takes precedence over the 'device' field of the root ;; <file-system> record. ;; TODO: Add options for the root file system type and the root@@ -500,10 +503,13 @@ upon error." (root-device (or (and=> (find-long-option "--root" args) device-string->file-system-device) root-fs-device))- (root-options (if (null? root-fs-options)- #f- (file-system-options->string- root-fs-options))))+ ;; --root-options takes precedence over the 'options' field of the+ ;; root <file-system> record.+ (root-options (or (find-long-option "--root-options" args)+ (if (null? root-fs-options)+ #f+ (file-system-options->string+ root-fs-options))))) (when (member "--repl" args) (start-repl))-- 2.25.0
From 2cc5b27defbd2b9fd75c70482ac2ecf045b880e3 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:27:19 -0500Subject: [PATCH 7/8] linux-boot: Filter out file system independent options.
This fixes an issue where options such as "defaults", which are understood bythe command line program "mount", are not understood by the system call of thesame name, which is used in the initial RAM disk.
* gnu/system/file-systems.scm (%file-system-independent-mount-options): New variable.(file-system-independent-mount-option?): New predicate.* gnu/build/linux-boot.scm (boot-system): Use the above predicate to filterout system independent mount options.--- gnu/build/linux-boot.scm | 3 ++- gnu/system/file-systems.scm | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-)
Toggle diff (49 lines)diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 063daa4ca4..f77eeecbe3 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -493,7 +493,8 @@ upon error." (or (and=> root-fs file-system-flags) '()))) (root-fs-options (if root-fs- (file-system-options root-fs)+ (remove file-system-independent-mount-option?+ (file-system-options root-fs)) '())) ;; --root takes precedence over the 'device' field of the rootdiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex c205feae70..4f0c5ad99e 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -46,6 +46,7 @@ file-system-location file-system-type-predicate+ file-system-independent-mount-option? file-system-label file-system-label?@@ -567,4 +568,20 @@ system has the given TYPE." (lambda (fs) (string=? (file-system-type fs) type))) +(define %file-system-independent-mount-options+ ;; Taken from 'man 8 mount'.+ '("async" "atime" "auto" "noatime" "noauto" "context" "defaults" "dev" "nodev"+ "diratime" "nodiratime" "dirsync" "exec" "noexec" "group" "iversion"+ "noiversion" "mand" "nomand" "_netdev" "nofail" "relatime" "norelatime"+ "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid"+ "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "users"))++(define (file-system-independent-mount-option? option)+ "Predicate to check if a <file-system> option is file system independent."+ (let ((option-name (if (pair? option)+ (car option)+ option)))+ (or (string-prefix-ci? "x-" option-name)+ (member option-name %file-system-independent-mount-options))))+ ;;; file-systems.scm ends here-- 2.25.0
From e73112a8a476f89a4728a865576dab7e8042bb47 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH 8/8] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (grub-configuration-file)[btrfs-subvolume-file-name]: New parameter. When it is defined,prepend its value to the kernel and initrd file names.* gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.* gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.* gnu/system/file-systems.scm (btrfs-subvolume?)(btrfs-store-subvolume-file-name): New procedures.* gnu/system.scm (operating-system-bootcfg): Specify the Btrfssubvolume file name the store resides on to the`operating-system-bootcfg' procedure, using the newBTRFS-SUBVOLUME-FILE-NAME argument.* doc/guix.texi (File Systems): Add a Btrfs subsection to document the use ofsubvolumes. Document the new `properties' field of the `<file-system>'record.* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".--- doc/guix.texi | 114 +++++++++++++++++++++++++++++++++ gnu/bootloader/depthcharge.scm | 3 +- gnu/bootloader/extlinux.scm | 3 +- gnu/bootloader/grub.scm | 45 ++++++++----- gnu/system.scm | 9 ++- gnu/system/file-systems.scm | 58 +++++++++++++++++ gnu/tests/install.scm | 96 +++++++++++++++++++++++++++ 7 files changed, 308 insertions(+), 20 deletions(-)
Toggle diff (482 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex d6bfbd7b55..f0956f965a 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and Another example is a file system that depends on a mapped device, for example for an encrypted partition (@pxref{Mapped Devices}).++@item @code{properties} (default: @code{'()})+This is a list of key-value pairs that can be used to specify properties+not captured by other fields. For example, the top level path of a+Btrfs subvolume within its Btrfs pool can be specified using the+@code{btrfs-subvolume-path} property (@pxref{Btrfs file system}).+ @end table @end deftp @@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems. This requires the @code{fuse.ko} kernel module to be loaded. @end defvr +@node Btrfs file system+@subsection Btrfs file system++The Btrfs has special features, such as subvolumes, that merit being+explained in more details. The following section attempts to cover+basic as well as complex uses of a Btrfs file system with the Guix+System.++In its simplest usage, a Btrfs file system can be described, for+example, by:++@lisp+(file-system+ (mount-point "/home")+ (type "btrfs")+ (device (file-system-label "my-home")))+@end lisp++The example below is more complex, as it makes use of a Btrfs+subvolume, named @code{rootfs}. The parent Btrfs file system is labeled+@code{my-btrfs-pool}, and is located on an encrypted device (hence the+dependency on @code{mapped-devices}):++@example+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options '("defaults" ("subvol" . "rootfs"))+ (dependencies mapped-devices))+@end example++Some bootloaders, for example GRUB, only mount a Btrfs partition at its+top level during the early boot, and rely on their configuration to+refer to the correct subvolume path within that top level. The+bootloaders operating in this way typically produce their configuration+on a running system where the Btrfs partitions are already mounted and+where the subvolume information is readily available. As an example,+@command{grub-mkconfig}, the configuration generator command shipped+with GRUB, reads @file{/proc/self/mountinfo} to determine the top-level+path of a subvolume.++The Guix System produces a bootloader configuration using the operating+system configuration as its sole input; it is therefore necessary to+extract the subvolume name on which @file{/gnu/store} lives (if any)+from that operating system configuration. To better illustrate,+consider a subvolume named 'rootfs' which contains the root file system+data. In such situation, the GRUB bootloader would only see the top+level of the root Btrfs partition, e.g.:++@example+/ (top level)+├── rootfs (subvolume directory)+ ├── gnu (normal directory)+ ├── store (normal directory)+[...]+@end example++Thus, the subvolume name must be prepended to the @file{/gnu/store} path+of the kernel and initrd binaries in the GRUB configuration in order for+those to be found.++The next example shows a nested hierarchy of subvolumes and+directories:++@example+/ (top level)+├── rootfs (subvolume)+ ├── gnu (normal directory)+ ├── store (subvolume)+[...]+@end example++This scenario would work without mounting the 'store' subvolume.+Mounting 'rootfs' is sufficient, since the subvolume name matches its+intended mount point in the file system hierarchy.++Finally, a more contrived example of nested subvolumes:++@example+/ (top level)+├── root-snapshots (subvolume)+ ├── root-current (subvolume)+ ├── guix-store (subvolume)+[...]+@end example++Here, the 'guix-store' module name doesn't match its intended mount+point, so it is necessary to mount it. The layout cannot simply be+described by the <file-system> record, so it is required to specify the+exact path at which the subvolume exists within the top level of its+parent file system. This can be achieved by attaching a+@code{btrfs-subvolume-path} property to the corresponding file system+record:++@lisp+(file-system+ ...+ (properties '((btrfs-subvolume-path+ . "/root-snapshots/root-current/guix-store"))))+@end lisp++The default behavior of Guix is to assume that a subvolume exists+directly at the root of the top volume hierarchy. When this is not the+case, the above property must be used for the system to boot correctly+when using a GRUB based bootloader.+ @node Mapped Devices @section Mapped Devices diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scmindex 58cc3f3932..0a50374bd9 100644--- a/gnu/bootloader/depthcharge.scm+++ b/gnu/bootloader/depthcharge.scm@@ -82,7 +82,8 @@ (define* (depthcharge-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) (match entries ((entry) (let ((kernel (menu-entry-linux entry))diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scmindex 5b4dd84965..6b5ff298e7 100644--- a/gnu/bootloader/extlinux.scm+++ b/gnu/bootloader/extlinux.scm@@ -28,7 +28,8 @@ (define* (extlinux-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) "Return the U-Boot configuration file corresponding to CONFIG, a <u-boot-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu entriesdiff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex b99f5fa4f4..3ec960abd8 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -4,6 +4,7 @@ ;;; Copyright © 2017 Leo Famulari <leo@famulari.name> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -327,35 +328,47 @@ code." (define* (grub-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ btrfs-subvolume-file-name) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at-STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu-entries corresponding to old generations of the system."+STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list+of menu entries corresponding to old generations of the system.+BTRFS-SUBVOLUME-FILE-NAME may be used to specify on which subvolume a+Btrfs root file system resides." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (arguments (menu-entry-linux-arguments entry))+ (kernel* (strip-mount-point+ device-mount-point (menu-entry-linux entry)))+ (initrd* (strip-mount-point+ device-mount-point (menu-entry-initrd entry)))+ (kernel (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name #$kernel*)+ kernel*))+ (initrd (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name #$initrd*)+ initrd*))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))- #~(format port "menuentry ~s {++ ;; When BTRFS-SUBVOLUME-FILE-NAME is defined, prepend it the kernel and+ ;; initrd paths, to allow booting from a Btrfs subvolume.+ #~(format port "menuentry ~s { ~a linux ~a ~a initrd ~a }~%"- #$label- #$(grub-root-search device kernel)- #$kernel (string-join (list #$@arguments))- #$initrd))))+ #$label+ #$(grub-root-search device kernel)+ #$kernel (string-join (list #$@arguments))+ #$initrd))) (define sugar (eye-candy config (menu-entry-device (first all-entries))diff --git a/gnu/system.scm b/gnu/system.scmindex 2e6d03272d..59c3526098 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -5,6 +5,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Meiyo Peng <meiyo.peng@gmail.com>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -992,19 +993,23 @@ entry." (define* (operating-system-bootcfg os #:optional (old-entries '())) "Return the bootloader configuration file for OS. Use OLD-ENTRIES, a list of <menu-entry>, to populate the \"old entries\" menu."- (let* ((root-fs (operating-system-root-file-system os))+ (let* ((file-systems (operating-system-file-systems os))+ (root-fs (operating-system-root-file-system os)) (root-device (file-system-device root-fs)) (params (operating-system-boot-parameters os root-device #:system-kernel-arguments? #t)) (entry (boot-parameters->menu-entry params)) (bootloader-conf (operating-system-bootloader os)))+ (define generate-config-file (bootloader-configuration-file-generator (bootloader-configuration-bootloader bootloader-conf))) (generate-config-file bootloader-conf (list entry)- #:old-entries old-entries)))+ #:old-entries old-entries+ #:btrfs-subvolume-file-name+ (btrfs-store-subvolume-file-name file-systems)))) (define* (operating-system-boot-parameters os root-device #:key system-kernel-arguments?)diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 4f0c5ad99e..7b78731524 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -21,7 +21,10 @@ #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-35) #:use-module (srfi srfi-9 gnu) #:use-module (guix records) #:use-module (gnu system uuid)@@ -44,9 +47,12 @@ file-system-create-mount-point? file-system-dependencies file-system-location+ file-system-properties file-system-type-predicate file-system-independent-mount-option?+ btrfs-subvolume?+ btrfs-store-subvolume-file-name file-system-label file-system-label?@@ -112,6 +118,8 @@ (default #f)) (dependencies file-system-dependencies ; list of <file-system> (default '())) ; or <mapped-device>+ (properties file-system-properties ; list of name-value pairs+ (default '())) (location file-system-location (default (current-source-location)) (innate)))@@ -584,4 +592,54 @@ system has the given TYPE." (or (string-prefix-ci? "x-" option-name) (member option-name %file-system-independent-mount-options)))) +(define (btrfs-subvolume? fs)+ "Predicate to check if FS, a file-system object, is a Btrfs subvolume."+ (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))+ (option-keys (map (match-lambda+ ((key . value) key)+ (key key))+ (file-system-options fs))))+ (find (cut string-prefix? "subvol" <>) option-keys)))++(define (btrfs-store-subvolume-file-name file-systems)+ "Return the subvolume file name within the Btrfs top level onto+which the store is located. When the BTRFS-SUBVOLUME-FILE-NAME file+system property is not set, it is assumed that the store subvolume+file name is located at the root of the top level of the file system."++ (define (find-mount-point-fs mount-point file-systems)+ (find (lambda (fs)+ (string= mount-point (file-system-mount-point fs)))+ file-systems))++ ;; Find a subvolume mounted at either /gnu/store, /gnu, or /.+ (let loop ((mount-point (%store-prefix)))+ (let ((mount-point-fs (find-mount-point-fs mount-point file-systems)))+ (cond+ ((string-null? mount-point)+ #f) ;store is not on a Btrfs subvolume+ ((and=> mount-point-fs btrfs-subvolume?)+ (let* ((fs-options (file-system-options mount-point-fs))+ (subvolid (assoc-ref fs-options "subvolid"))+ (subvol (assoc-ref fs-options "subvol")))+ (or (assoc-ref (file-system-properties mount-point-fs)+ "btrfs-subvolume-file-name")+ (and=> subvol (cut string-append "/" <>))+ ;; XXX: Importing (guix utils) and using &fix-hint causes the+ ;; following error when booting the init RAM disk: "ERROR: In+ ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol+ ;; not found: strverscmp", so we just embed the hint in the+ ;; message.+ (raise (condition+ (&message+ (message "The store is on a Btrfs subvolume, but the \+subvolume name is unknown.\nHint: Define the \"btrfs-subvolume-file-name\" \+file system property or use the \"subvol\" Btrfs file system")))))))+ (else+ (loop+ (cond ((string-suffix? "/" mount-point)+ (string-drop-right mount-point 1))+ ((string-take mount-point+ (1+ (string-index-right mount-point #\/)))))))))))+ ;;; file-systems.scm ends herediff --git a/gnu/tests/install.scm b/gnu/tests/install.scmindex d475bda2c7..82e2b46e3e 100644--- a/gnu/tests/install.scm+++ b/gnu/tests/install.scm@@ -44,6 +44,7 @@ %test-raid-root-os %test-encrypted-root-os %test-btrfs-root-os+ %test-btrfs-root-on-subvolume-os %test-jfs-root-os)) ;;; Commentary:@@ -811,6 +812,101 @@ build (current-guix) and then store a couple of full system images.") (command (qemu-command/writable-image image))) (run-basic-test %btrfs-root-os command "btrfs-root-os"))))) + +;;;+;;; Btrfs root file system on a subvolume.+;;;++(define-os-with-source (%btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source)+ ;; The OS we want to install.+ (use-modules (gnu) (gnu tests) (srfi srfi-1))++ (operating-system+ (host-name "hurd")+ (timezone "America/Montreal")+ (locale "en_US.UTF-8")+ (bootloader (bootloader-configuration+ (bootloader grub-bootloader)+ (target "/dev/vdb")))+ (kernel-arguments '("console=ttyS0"))+ (file-systems (cons* (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (options '(("subvol" . "rootfs")+ ("compress" . "zstd")))+ (type "btrfs"))+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (options '(("subvol" . "homefs")+ ("compress" . "lzo")))+ (type "btrfs"))+ %base-file-systems))+ (users (cons (user-account+ (name "charlie")+ (group "users")+ (supplementary-groups '("wheel" "audio" "video")))+ %base-user-accounts))+ (services (cons (service marionette-service-type+ (marionette-configuration+ (imported-modules '((gnu services herd)+ (guix combinators)))))+ %base-services))))++(define %btrfs-root-on-subvolume-installation-script+ ;; Shell script of a simple installation.+ "\+. /etc/profile+set -e -x+guix --version++export GUIX_BUILD_OPTIONS=--no-grafts+ls -l /run/current-system/gc-roots+parted --script /dev/vdb mklabel gpt \\+ mkpart primary ext2 1M 3M \\+ mkpart primary ext2 3M 2G \\+ set 1 boot on \\+ set 1 bios_grub on++# Setup the top level Btrfs file system with its subvolume.+mkfs.btrfs -L btrfs-pool /dev/vdb2+mount /dev/vdb2 /mnt+btrfs subvolume create /mnt/rootfs+btrfs subvolume create /mnt/homefs+umount /dev/vdb2++# Mount the subvolumes, ready for installation.+mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt+mkdir /mnt/home+mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home++herd start cow-store /mnt+mkdir /mnt/etc+cp /etc/target-config.scm /mnt/etc/config.scm+guix system build /mnt/etc/config.scm+guix system init /mnt/etc/config.scm /mnt --no-substitutes+sync+reboot\n")++(define %test-btrfs-root-on-subvolume-os+ (system-test+ (name "btrfs-root-on-subvolume-os")+ (description+ "Test basic functionality of an OS installed like one would do by hand.+This test is expensive in terms of CPU and storage usage since we need to+build (current-guix) and then store a couple of full system images.")+ (value+ (mlet* %store-monad+ ((image+ (run-install %btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source+ #:script+ %btrfs-root-on-subvolume-installation-script))+ (command (qemu-command/writable-image image)))+ (run-basic-test %btrfs-root-on-subvolume-os command+ "btrfs-root-on-subvolume-os")))))+ ;;; ;;; JFS root file system.-- 2.25.0
L
L
Ludovic Courtès wrote on 20 Feb 2020 10:55
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
87lfoxbn2e.fsf@gnu.org
Hi Maxim,
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (10 lines)>>> + (error "The store is on a Btrfs subvolume, but the \>>> +subvolume name is unknown.>>> +Hint: Define the \"btrfs-subvolume-path\" file system property or>>> +use the \"subvol\" Btrfs file system option."))))>>> Rather use ‘raise’ with ‘&message’ and ‘&fix-hint’ conditions.>> I tried this, but importing (guix utils) to acces &fix-hint caused the init> RAM disk to fail mysteriously:
Oh, my bad. We should move ‘&fix-hint’ to (guix diagnostics)eventually.
In the meantime, I’d say just raise a ‘&message’ and leave the hint as acomment (it’s not supposed to be a user-facing interface). Or maybe youcould define a specific error condition type for this?
Thanks,Ludo’.
PS: I’ll comment on the other bits ASAP!
M
M
Maxim Cournoyer wrote on 24 Feb 2020 15:23
Re: [bug#37305] [PATCH V3] Allow booting from a Btrfs subvolume.
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
871rqkf4ix.fsf_-_@gmail.com
I've added a `normalize-file' procedure to the attached patch, whichsimplify producing correct store references in the GRUB configurationfile generated.
This fixed the GRUB video mode issues reported in a another issue.
Thanks!
Maxim
From 1c0aafd5d0e013387a8f9bede3c42622b85957c5 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.(normalize-file): Add procedure.(grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. Whendefined, prepend its value to the kernel and initrd file names, using theNORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass theBTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.(eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along withthe NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nestedvariables. Adjust doc.* gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.* gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.* gnu/system/file-systems.scm (btrfs-subvolume?)(btrfs-store-subvolume-file-name): New procedures.* gnu/system.scm (operating-system-bootcfg): Specify the Btrfssubvolume file name the store resides on to the`operating-system-bootcfg' procedure, using the newBTRFS-SUBVOLUME-FILE-NAME argument.* doc/guix.texi (File Systems): Add a Btrfs subsection to document the use ofsubvolumes. Document the new `properties' field of the `<file-system>'record.* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".--- doc/guix.texi | 114 ++++++++++++++++++++++++++++++ gnu/bootloader/depthcharge.scm | 3 +- gnu/bootloader/extlinux.scm | 3 +- gnu/bootloader/grub.scm | 123 +++++++++++++++++++++------------ gnu/system.scm | 9 ++- gnu/system/file-systems.scm | 58 ++++++++++++++++ gnu/tests/install.scm | 96 +++++++++++++++++++++++++ 7 files changed, 356 insertions(+), 50 deletions(-)
Toggle diff (600 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex d6bfbd7b55..f0956f965a 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and Another example is a file system that depends on a mapped device, for example for an encrypted partition (@pxref{Mapped Devices}).++@item @code{properties} (default: @code{'()})+This is a list of key-value pairs that can be used to specify properties+not captured by other fields. For example, the top level path of a+Btrfs subvolume within its Btrfs pool can be specified using the+@code{btrfs-subvolume-path} property (@pxref{Btrfs file system}).+ @end table @end deftp @@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems. This requires the @code{fuse.ko} kernel module to be loaded. @end defvr +@node Btrfs file system+@subsection Btrfs file system++The Btrfs has special features, such as subvolumes, that merit being+explained in more details. The following section attempts to cover+basic as well as complex uses of a Btrfs file system with the Guix+System.++In its simplest usage, a Btrfs file system can be described, for+example, by:++@lisp+(file-system+ (mount-point "/home")+ (type "btrfs")+ (device (file-system-label "my-home")))+@end lisp++The example below is more complex, as it makes use of a Btrfs+subvolume, named @code{rootfs}. The parent Btrfs file system is labeled+@code{my-btrfs-pool}, and is located on an encrypted device (hence the+dependency on @code{mapped-devices}):++@example+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options '("defaults" ("subvol" . "rootfs"))+ (dependencies mapped-devices))+@end example++Some bootloaders, for example GRUB, only mount a Btrfs partition at its+top level during the early boot, and rely on their configuration to+refer to the correct subvolume path within that top level. The+bootloaders operating in this way typically produce their configuration+on a running system where the Btrfs partitions are already mounted and+where the subvolume information is readily available. As an example,+@command{grub-mkconfig}, the configuration generator command shipped+with GRUB, reads @file{/proc/self/mountinfo} to determine the top-level+path of a subvolume.++The Guix System produces a bootloader configuration using the operating+system configuration as its sole input; it is therefore necessary to+extract the subvolume name on which @file{/gnu/store} lives (if any)+from that operating system configuration. To better illustrate,+consider a subvolume named 'rootfs' which contains the root file system+data. In such situation, the GRUB bootloader would only see the top+level of the root Btrfs partition, e.g.:++@example+/ (top level)+├── rootfs (subvolume directory)+ ├── gnu (normal directory)+ ├── store (normal directory)+[...]+@end example++Thus, the subvolume name must be prepended to the @file{/gnu/store} path+of the kernel and initrd binaries in the GRUB configuration in order for+those to be found.++The next example shows a nested hierarchy of subvolumes and+directories:++@example+/ (top level)+├── rootfs (subvolume)+ ├── gnu (normal directory)+ ├── store (subvolume)+[...]+@end example++This scenario would work without mounting the 'store' subvolume.+Mounting 'rootfs' is sufficient, since the subvolume name matches its+intended mount point in the file system hierarchy.++Finally, a more contrived example of nested subvolumes:++@example+/ (top level)+├── root-snapshots (subvolume)+ ├── root-current (subvolume)+ ├── guix-store (subvolume)+[...]+@end example++Here, the 'guix-store' module name doesn't match its intended mount+point, so it is necessary to mount it. The layout cannot simply be+described by the <file-system> record, so it is required to specify the+exact path at which the subvolume exists within the top level of its+parent file system. This can be achieved by attaching a+@code{btrfs-subvolume-path} property to the corresponding file system+record:++@lisp+(file-system+ ...+ (properties '((btrfs-subvolume-path+ . "/root-snapshots/root-current/guix-store"))))+@end lisp++The default behavior of Guix is to assume that a subvolume exists+directly at the root of the top volume hierarchy. When this is not the+case, the above property must be used for the system to boot correctly+when using a GRUB based bootloader.+ @node Mapped Devices @section Mapped Devices diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scmindex 58cc3f3932..0a50374bd9 100644--- a/gnu/bootloader/depthcharge.scm+++ b/gnu/bootloader/depthcharge.scm@@ -82,7 +82,8 @@ (define* (depthcharge-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) (match entries ((entry) (let ((kernel (menu-entry-linux entry))diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scmindex 5b4dd84965..6b5ff298e7 100644--- a/gnu/bootloader/extlinux.scm+++ b/gnu/bootloader/extlinux.scm@@ -28,7 +28,8 @@ (define* (extlinux-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) "Return the U-Boot configuration file corresponding to CONFIG, a <u-boot-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu entriesdiff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex b99f5fa4f4..99cb42c4a2 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -4,6 +4,7 @@ ;;; Copyright © 2017 Leo Famulari <leo@famulari.name> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -61,18 +62,29 @@ ;;; ;;; Code: -(define (strip-mount-point mount-point file)- "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable object-denoting a file name."- (match mount-point- ((? string? mount-point)- (if (string=? mount-point "/")- file- #~(let ((file #$file))- (if (string-prefix? #$mount-point file)- (substring #$file #$(string-length mount-point))- file))))- (#f file)))+(define* (normalize-file file mount-point btrfs-subvolume-file-name)+ "Strip MOUNT-POINT and prepend BTRFS-SUBVOLUME-FILE-NAME to FILE, a+G-expression or other lowerable object denoting a file name."++ (define (strip-mount-point mount-point file)+ (if mount-point+ (if (string=? mount-point "/")+ file+ #~(let ((file #$file))+ (if (string-prefix? #$mount-point file)+ (substring #$file #$(string-length mount-point))+ file)))+ file))++ (define (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name file)+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name #$file)+ file))++ (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name+ (strip-mount-point mount-point file)))++ (define-record-type* <grub-image> grub-image make-grub-image@@ -140,13 +152,15 @@ WIDTH/HEIGHT, or #f if none was found." #:width width #:height height)))) (define* (eye-candy config store-device store-mount-point+ btrfs-store-subvolume-file-name #:key system port)- "Return a gexp that writes to PORT (a port-valued gexp) the-'grub.cfg' part concerned with graphics mode, background images, colors, and-all that. STORE-DEVICE designates the device holding the store, and-STORE-MOUNT-POINT is its mount point; these are used to determine where the-background image and fonts must be searched for. SYSTEM must be the target-system string---e.g., \"x86_64-linux\"."+ "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part+concerned with graphics mode, background images, colors, and all that.+STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POINT is+its mount point; these are used to determine where the background image and+fonts must be searched for. SYSTEM must be the target system string---e.g.,+\"x86_64-linux\". BTRFS-STORE-SUBVOLUME-FILE-NAME is the file name of the+Btrfs subvolume, to be prefixed to any store path, if any." (define setup-gfxterm-body ;; Intel and EFI systems need to be switched into graphics mode, whereas ;; most other modern architectures have no other mode and therefore don't@@ -194,11 +208,14 @@ fi~%" #$font-file) (symbol->string (assoc-ref colors 'bg))))) (define font-file- (strip-mount-point store-mount-point- (file-append grub "/share/grub/unicode.pf2")))+ (normalize-file (file-append grub "/share/grub/unicode.pf2")+ store-mount-point+ btrfs-store-subvolume-file-name)) (define image- (grub-background-image config))+ (normalize-file (grub-background-image config)+ store-mount-point+ btrfs-store-subvolume-file-name)) (and image #~(format #$port "@@ -223,7 +240,7 @@ fi~%" #$(setup-gfxterm config font-file) #$(grub-setup-io config) - #$(strip-mount-point store-mount-point image)+ #$image #$(theme-colors grub-theme-color-normal) #$(theme-colors grub-theme-color-highlight)))) @@ -327,52 +344,66 @@ code." (define* (grub-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ btrfs-subvolume-file-name) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at-STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu-entries corresponding to old generations of the system."+STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list+of menu entries corresponding to old generations of the system.+BTRFS-SUBVOLUME-FILE-NAME may be used to specify on which subvolume a+Btrfs root file system resides." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (arguments (menu-entry-linux-arguments entry))+ (kernel (normalize-file (menu-entry-linux entry)+ device-mount-point+ btrfs-subvolume-file-name))+ (initrd (normalize-file (menu-entry-initrd entry)+ device-mount-point+ btrfs-subvolume-file-name))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))- #~(format port "menuentry ~s {++ ;; When BTRFS-SUBVOLUME-FILE-NAME is defined, prepend it the kernel and+ ;; initrd paths, to allow booting from a Btrfs subvolume.+ #~(format port "menuentry ~s { ~a linux ~a ~a initrd ~a }~%"- #$label- #$(grub-root-search device kernel)- #$kernel (string-join (list #$@arguments))- #$initrd))))+ #$label+ #$(grub-root-search device kernel)+ #$kernel (string-join (list #$@arguments))+ #$initrd))) (define sugar (eye-candy config (menu-entry-device (first all-entries)) (menu-entry-device-mount-point (first all-entries))+ btrfs-subvolume-file-name #:system system #:port #~port)) (define keyboard-layout-config- (let ((layout (bootloader-configuration-keyboard-layout config))- (grub (bootloader-package- (bootloader-configuration-bootloader config))))- #~(let ((keymap #$(and layout- (keyboard-layout-file layout #:grub grub))))- (when keymap- (format port "\+ (let* ((layout (bootloader-configuration-keyboard-layout config))+ (grub (bootloader-package+ (bootloader-configuration-bootloader config)))+ (keymap* (and layout+ (keyboard-layout-file layout #:grub grub)))+ (keymap (and keymap*+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name+ #$keymap*)+ keymap*))))+ #~(when #$keymap+ (format port "\ insmod keylayouts-keymap ~a~%" keymap)))))+keymap ~a~%" #$keymap)))) (define builder #~(call-with-output-file #$outputdiff --git a/gnu/system.scm b/gnu/system.scmindex 2e6d03272d..59c3526098 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -5,6 +5,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Meiyo Peng <meiyo.peng@gmail.com>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -992,19 +993,23 @@ entry." (define* (operating-system-bootcfg os #:optional (old-entries '())) "Return the bootloader configuration file for OS. Use OLD-ENTRIES, a list of <menu-entry>, to populate the \"old entries\" menu."- (let* ((root-fs (operating-system-root-file-system os))+ (let* ((file-systems (operating-system-file-systems os))+ (root-fs (operating-system-root-file-system os)) (root-device (file-system-device root-fs)) (params (operating-system-boot-parameters os root-device #:system-kernel-arguments? #t)) (entry (boot-parameters->menu-entry params)) (bootloader-conf (operating-system-bootloader os)))+ (define generate-config-file (bootloader-configuration-file-generator (bootloader-configuration-bootloader bootloader-conf))) (generate-config-file bootloader-conf (list entry)- #:old-entries old-entries)))+ #:old-entries old-entries+ #:btrfs-subvolume-file-name+ (btrfs-store-subvolume-file-name file-systems)))) (define* (operating-system-boot-parameters os root-device #:key system-kernel-arguments?)diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 4f0c5ad99e..7b78731524 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -21,7 +21,10 @@ #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-35) #:use-module (srfi srfi-9 gnu) #:use-module (guix records) #:use-module (gnu system uuid)@@ -44,9 +47,12 @@ file-system-create-mount-point? file-system-dependencies file-system-location+ file-system-properties file-system-type-predicate file-system-independent-mount-option?+ btrfs-subvolume?+ btrfs-store-subvolume-file-name file-system-label file-system-label?@@ -112,6 +118,8 @@ (default #f)) (dependencies file-system-dependencies ; list of <file-system> (default '())) ; or <mapped-device>+ (properties file-system-properties ; list of name-value pairs+ (default '())) (location file-system-location (default (current-source-location)) (innate)))@@ -584,4 +592,54 @@ system has the given TYPE." (or (string-prefix-ci? "x-" option-name) (member option-name %file-system-independent-mount-options)))) +(define (btrfs-subvolume? fs)+ "Predicate to check if FS, a file-system object, is a Btrfs subvolume."+ (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))+ (option-keys (map (match-lambda+ ((key . value) key)+ (key key))+ (file-system-options fs))))+ (find (cut string-prefix? "subvol" <>) option-keys)))++(define (btrfs-store-subvolume-file-name file-systems)+ "Return the subvolume file name within the Btrfs top level onto+which the store is located. When the BTRFS-SUBVOLUME-FILE-NAME file+system property is not set, it is assumed that the store subvolume+file name is located at the root of the top level of the file system."++ (define (find-mount-point-fs mount-point file-systems)+ (find (lambda (fs)+ (string= mount-point (file-system-mount-point fs)))+ file-systems))++ ;; Find a subvolume mounted at either /gnu/store, /gnu, or /.+ (let loop ((mount-point (%store-prefix)))+ (let ((mount-point-fs (find-mount-point-fs mount-point file-systems)))+ (cond+ ((string-null? mount-point)+ #f) ;store is not on a Btrfs subvolume+ ((and=> mount-point-fs btrfs-subvolume?)+ (let* ((fs-options (file-system-options mount-point-fs))+ (subvolid (assoc-ref fs-options "subvolid"))+ (subvol (assoc-ref fs-options "subvol")))+ (or (assoc-ref (file-system-properties mount-point-fs)+ "btrfs-subvolume-file-name")+ (and=> subvol (cut string-append "/" <>))+ ;; XXX: Importing (guix utils) and using &fix-hint causes the+ ;; following error when booting the init RAM disk: "ERROR: In+ ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol+ ;; not found: strverscmp", so we just embed the hint in the+ ;; message.+ (raise (condition+ (&message+ (message "The store is on a Btrfs subvolume, but the \+subvolume name is unknown.\nHint: Define the \"btrfs-subvolume-file-name\" \+file system property or use the \"subvol\" Btrfs file system")))))))+ (else+ (loop+ (cond ((string-suffix? "/" mount-point)+ (string-drop-right mount-point 1))+ ((string-take mount-point+ (1+ (string-index-right mount-point #\/)))))))))))+ ;;; file-systems.scm ends herediff --git a/gnu/tests/install.scm b/gnu/tests/install.scmindex d475bda2c7..82e2b46e3e 100644--- a/gnu/tests/install.scm+++ b/gnu/tests/install.scm@@ -44,6 +44,7 @@ %test-raid-root-os %test-encrypted-root-os %test-btrfs-root-os+ %test-btrfs-root-on-subvolume-os %test-jfs-root-os)) ;;; Commentary:@@ -811,6 +812,101 @@ build (current-guix) and then store a couple of full system images.") (command (qemu-command/writable-image image))) (run-basic-test %btrfs-root-os command "btrfs-root-os"))))) + +;;;+;;; Btrfs root file system on a subvolume.+;;;++(define-os-with-source (%btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source)+ ;; The OS we want to install.+ (use-modules (gnu) (gnu tests) (srfi srfi-1))++ (operating-system+ (host-name "hurd")+ (timezone "America/Montreal")+ (locale "en_US.UTF-8")+ (bootloader (bootloader-configuration+ (bootloader grub-bootloader)+ (target "/dev/vdb")))+ (kernel-arguments '("console=ttyS0"))+ (file-systems (cons* (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (options '(("subvol" . "rootfs")+ ("compress" . "zstd")))+ (type "btrfs"))+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (options '(("subvol" . "homefs")+ ("compress" . "lzo")))+ (type "btrfs"))+ %base-file-systems))+ (users (cons (user-account+ (name "charlie")+ (group "users")+ (supplementary-groups '("wheel" "audio" "video")))+ %base-user-accounts))+ (services (cons (service marionette-service-type+ (marionette-configuration+ (imported-modules '((gnu services herd)+ (guix combinators)))))+ %base-services))))++(define %btrfs-root-on-subvolume-installation-script+ ;; Shell script of a simple installation.+ "\+. /etc/profile+set -e -x+guix --version++export GUIX_BUILD_OPTIONS=--no-grafts+ls -l /run/current-system/gc-roots+parted --script /dev/vdb mklabel gpt \\+ mkpart primary ext2 1M 3M \\+ mkpart primary ext2 3M 2G \\+ set 1 boot on \\+ set 1 bios_grub on++# Setup the top level Btrfs file system with its subvolume.+mkfs.btrfs -L btrfs-pool /dev/vdb2+mount /dev/vdb2 /mnt+btrfs subvolume create /mnt/rootfs+btrfs subvolume create /mnt/homefs+umount /dev/vdb2++# Mount the subvolumes, ready for installation.+mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt+mkdir /mnt/home+mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home++herd start cow-store /mnt+mkdir /mnt/etc+cp /etc/target-config.scm /mnt/etc/config.scm+guix system build /mnt/etc/config.scm+guix system init /mnt/etc/config.scm /mnt --no-substitutes+sync+reboot\n")++(define %test-btrfs-root-on-subvolume-os+ (system-test+ (name "btrfs-root-on-subvolume-os")+ (description+ "Test basic functionality of an OS installed like one would do by hand.+This test is expensive in terms of CPU and storage usage since we need to+build (current-guix) and then store a couple of full system images.")+ (value+ (mlet* %store-monad+ ((image+ (run-install %btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source+ #:script+ %btrfs-root-on-subvolume-installation-script))+ (command (qemu-command/writable-image image)))+ (run-basic-test %btrfs-root-on-subvolume-os command+ "btrfs-root-on-subvolume-os")))))+ ;;; ;;; JFS root file system.-- 2.25.0
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl5T3FYACgkQEmDkZILmNWIFGw/9HAUn9ZQml2lUXmMGFGPKJJpvPKQIgKSxmOk8w/1SmTmKCCrEF10kCQsVrrhz/rifZXI7M24zmGJX6N0yqdbbj3EdyKvqPoGANUtEfj2Pz3AFph3DLgFGMJ5DSj8O4xJVlQ1V6TAeSmtRXwZeOQ3n6yGFxypoeDmHRgVyT+MV/uC3bYV64s1kLgWMpetBRUAvoipU9q8Jw/uXvySMUTbZXr7+MPYWQcC67JxjhU2SnrJhmJxCb7Wi8kQmNFiWkOv9Ou1x2a552NjLyMW1dqsJJDbHfepdv8MfVo+cYAukB8FzdfzMZT1V4WkLvCKiSNdRZlF8+jp61F1UC2hD1DVaMkDofd1yFlzboIE6q+IVILzDzDm4u0ThoAcg5n6HAIDKRiQBc/5iXKlzQfABRSGaMlNxYgVUnMqkONGFp6JyAAgOpwiZTjmHjxIz5nxzgikGSFyT5wNiTZcR6pBSiSGHuCTdYAdtpmoog0QWuhkv6K4TllgdURlp8vfOQJZAQd+MsX58AE8U0UVBYb3MmY6pM7Y722J5Khpr9+OxLCuECF+83h/k0GmVazdfh6aC9P4S+d8+/RbjwygASCC4ngJur4xWVLGJZlZoeIVEazYv1bTVlwjPzaLg2/f7zZR++xezmszteLZ1M13JZpP4WCC8zkTPxATyhk+an14QTOlyAHQ==Op9E-----END PGP SIGNATURE-----
L
L
Ludovic Courtès wrote on 24 Feb 2020 17:02
Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)(address . 37305@debbugs.gnu.org)
87imjwkm6u.fsf@gnu.org
Hi Maxim,
Resuming review of this series… Sorry for the delay!
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (17 lines)>>> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001>>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>>> Date: Tue, 11 Feb 2020 12:57:29 -0500>>> Subject: [PATCH 2/9] gnu: linux-boot: Ensure volatile root is mounted>>> read-only.>>>>>> * gnu/build/linux-boot.scm (mount-root-file-system): Ensure MS_RDONLY is>>> present among the root file system flags when VOLATILE-ROOT? is #t.>>>> (You can drop the “gnu:” prefix.)>> Done.>> I never know before looking at past logs (and then sometimes it's a> mixed bag). Is there any mechanical process for selecting the right> commit prefix? :-)
“gnu:” is for changes to (gnu packages). The idea is that the prefixshould reflect what subsystem the commit is modifying. But yeah,looking at ‘git log’ can be inspiring. :-)
Toggle quote (17 lines)>>> @item --root=@var{root}>>> -Mount @var{root} as the root file system. @var{root} can be a>>> -device name like @code{/dev/sda1}, a file system label, or a file system>>> -UUID.>>> +Mount @var{root} as the root file system. @var{root} can be a device>>> +name like @code{/dev/sda1}, a file system label, or a file system UUID.>>> +When unspecified, the device name from the root file system of the>>> +operating system declaration is used.>>>> Oh! Does it always work? That makes me wonder why we’ve been carrying>> ‘--root’ and I’m not sure if I’m forgetting a good reason to do it that>> way.>> If the documentation is accurate, it should :-), given that --root gets> written as a string to the GRUB configuration file, and that the doc> says it's possible to give it as a device name, label or UUID.
Yes, ‘--root’ can resolve labels and UUIDs; my question was more aboutwhy we have it in the first place.
Toggle quote (9 lines)> About why providing options such as --root or --root-options in the> first place; I pondered about this as well, especially after making the> file systems from operating system able to be mounted with all their> (file system independent -- more on that later) options. A reason I> came up with was that it allows to experiment at the GRUB command line> and change the root device, or perhaps the root options. One use case> would be debugging the right options to pass to a file system driver in> case of a mistake in the operating system declaration.
Yes, that makes sense. It’s certainly useful to have ‘--root’ at leastas an option.
Toggle quote (23 lines)>> The main issue I see with this change is that mount(2) takes raw strings>> for the options. There’s a convention to have those strings look like>> “KEY1=VALUE1,KEY2=VALUE2”, but it’s just a convention.>>>> As a rule of thumb, I’d rather have our interface be as close as>> possible to the actual mount(2) interface, which means taking strings.>>>> Now, we can surely add helper procedures to parse options that follow>> the above conventions.>>>> WDYT?>> To me, it's an implementation detail that I'd rather abstract away (or> make optional, like in this patch). Just like we provide a higher level> configuration for services instead of requiring the user to input the> configuration in the native format of the tool (or allowing for both).> The idea for this format was taken from a discussion here:> http://issues.guix.info/issue/33517#3.>> Are we really targeting mount(2)? The commit> 9d3053819dfd834a1c29a03427c41d8524b8a7d5 (which you co-authored :-))> mentions 'man 8 mount' for the file system options.
Right, mount(8) documents file system options that can be passed tomount(2).
What does it mean to target mount(8) vs. mount(2)? To me, mount(8) is aCLI to mount(2) that provides additional features to make the CLI moreconvenient: the “defaults” option, a way to pass mount(2) flags asoptions (like “ro”, “remount”, “bind”), /etc/fstab handling, etc.
Guix System handles /etc/fstab differently and “defaults” makes littlesense in our API (one can just use leave the default value of the‘options’ field.)
I think mount(8) is actually a good illustration of what not to do. Itends up mixing things that are separate in the mount(2) API, and thatdoesn’t improve clarity and future-proof-ness (what if a file system hasa “bind” option, etc.).
But again, I think the helper procedures that you propose to move backand forth between the string and the alist representations are verywelcome. I just wouldn’t hard-code that directly in our API.
WDYT?
Toggle quote (17 lines)>>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001>>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>>> Date: Tue, 11 Feb 2020 14:14:36 -0500>>> Subject: [PATCH 6/9] gnu: linux-boot: Honor the "--root-options" kernel>>> argument.>>>>>> * gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernel>>> argument, and use it when calling `mount-root-file-system'. Update doc.>>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options">>> argument.>>>> Hmm do we really need this extra option? :-)>> It is not strictly needed but allows the user to experiment/troubleshoot> with the init RAM disk from GRUB as discussed earlier for --root. Do> you think it has enough value to be kept?
I’d rather avoid it for now. Less code is better. :-)
Toggle quote (6 lines)>> (Also, in hindsight, I think it was a mistake to call them>> ‘--something’. Following the common naming convention, we should rather>> call these options ‘gnu.something’.)>> Is this convention detailed somewhere? I haven't found it in 'Standards'.
It’s a convention of the Linux kernel, I don’t know if it’s documented.
That’s it!
Ludo’.
M
M
Maxim Cournoyer wrote on 3 Mar 2020 06:00
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87y2sijane.fsf@gmail.com
Hello Ludovic!
Resuming review; I hope I'll be able to bring this series to completionthis time.
[...]
Toggle quote (4 lines)> “gnu:” is for changes to (gnu packages). The idea is that the prefix> should reflect what subsystem the commit is modifying. But yeah,> looking at ‘git log’ can be inspiring. :-)
OK. Makes sense. Thanks for taking the time to explain!
[...]
Toggle quote (24 lines)>> About why providing options such as --root or --root-options in the>> first place; I pondered about this as well, especially after making the>> file systems from operating system able to be mounted with all their>> (file system independent -- more on that later) options. A reason I>> came up with was that it allows to experiment at the GRUB command line>> and change the root device, or perhaps the root options. One use case>> would be debugging the right options to pass to a file system driver in>> case of a mistake in the operating system declaration.>> Yes, that makes sense. It’s certainly useful to have ‘--root’ at least> as an option.>>>> The main issue I see with this change is that mount(2) takes raw strings>>> for the options. There’s a convention to have those strings look like>>> “KEY1=VALUE1,KEY2=VALUE2”, but it’s just a convention.>>>>>> As a rule of thumb, I’d rather have our interface be as close as>>> possible to the actual mount(2) interface, which means taking strings.>>>>>> Now, we can surely add helper procedures to parse options that follow>>> the above conventions.>>>>>> WDYT?
I don't feel too strongly about it, so I will adapt to your preference.
[...]
Toggle quote (21 lines)>> Are we really targeting mount(2)? The commit>> 9d3053819dfd834a1c29a03427c41d8524b8a7d5 (which you co-authored :-))>> mentions 'man 8 mount' for the file system options.>> Right, mount(8) documents file system options that can be passed to> mount(2).>> What does it mean to target mount(8) vs. mount(2)? To me, mount(8) is a> CLI to mount(2) that provides additional features to make the CLI more> convenient: the “defaults” option, a way to pass mount(2) flags as> options (like “ro”, “remount”, “bind”), /etc/fstab handling, etc.>> Guix System handles /etc/fstab differently and “defaults” makes little> sense in our API (one can just use leave the default value of the> ‘options’ field.)>> I think mount(8) is actually a good illustration of what not to do. It> ends up mixing things that are separate in the mount(2) API, and that> doesn’t improve clarity and future-proof-ness (what if a file system has> a “bind” option, etc.).
I think I agree. It may be cleaner to use the API of mount(2), whilemapping the low level stuff (binary flags?) to saner symbols, like it'salready done.
Toggle quote (4 lines)> But again, I think the helper procedures that you propose to move back> and forth between the string and the alist representations are very> welcome. I just wouldn’t hard-code that directly in our API.
Okay. I'll keep them around in (gnu system file-systems); they're handywhen we need to check the presence of an option in the option string.
Toggle quote (21 lines)> WDYT?>>>>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001>>>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>>>> Date: Tue, 11 Feb 2020 14:14:36 -0500>>>> Subject: [PATCH 6/9] gnu: linux-boot: Honor the "--root-options" kernel>>>> argument.>>>>>>>> * gnu/build/linux-boot.scm (boot-system): Parse the "--root-options" kernel>>>> argument, and use it when calling `mount-root-file-system'. Update doc.>>>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-options">>>> argument.>>>>>> Hmm do we really need this extra option? :-)>>>> It is not strictly needed but allows the user to experiment/troubleshoot>> with the init RAM disk from GRUB as discussed earlier for --root. Do>> you think it has enough value to be kept?>> I’d rather avoid it for now. Less code is better. :-)
Done!
Toggle quote (8 lines)>>> (Also, in hindsight, I think it was a mistake to call them>>> ‘--something’. Following the common naming convention, we should rather>>> call these options ‘gnu.something’.)>>>> Is this convention detailed somewhere? I haven't found it in 'Standards'.>> It’s a convention of the Linux kernel, I don’t know if it’s documented.
Well, with Hurd support coming, perhaps the standards used for aparticular kernel are not too relevant? :-)
One last thing that I'll try to understand before considering thisfinished: I think adding a special properties field to the file systemrecord might not be necessary, as it seems that the subvol option cantake an absolute path as well as a relative path (I thought it onlyaccepted subvolume *names*.)
Will send the 3rd revision soon.
Thank you!
Maxim
M
M
Maxim Cournoyer wrote on 7 Mar 2020 05:01
Re: [bug#37305] Making system installation tests faster
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 37305@debbugs.gnu.org)
87eeu4ke45.fsf@gmail.com
Hello, this is a small update, to reflect recent changes to the codebase.
Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:
Toggle quote (71 lines)> Hello Ludovic!>> I have more benchmark results. Not to be compared with the previous> results, as these were executed on a much faster machine (24 cores vs 4> cores), with an SSD instead of a rotative disk.>>> Commands used:>> current-guix/pre-built:>> time ./pre-inst-env guix system build -e \> '(begin> (use-modules> (gnu packages package-management))> (parameterize> ((current-guix-package> (current-guix/pre-built)))> ((@@> (gnu tests install)> operating-system-with-current-guix)> (@@> (gnu tests install)> %btrfs-root-os))))'>>> current-guix (old fashionned):>> time ./pre-inst-env guix system build -e \> '(begin> (use-modules> (gnu packages package-management))> (parameterize> ((current-guix-package> (current-guix)))> ((@@> (gnu tests install)> operating-system-with-current-guix)> (@@> (gnu tests install)> %btrfs-root-os))))'>>> new current-guix (guix self):>> time ./pre-inst-env guix system build -e \> '(begin> (use-modules ((gnu ci) #:select (channel-instance->package))> (guix monads)> (guix channels)> (guix store)> ((guix status) #:select (with-status-verbosity))> ((guix git-download) #:select (git-predicate))> (guix utils)> (gnu packages package-management))> (with-store store> (with-status-verbosity 2> (run-with-store store> (mlet* %store-monad> ((source-dir -> "/home/mcournoyer/src/guix")> (source (interned-file source-dir> "guix-source"> #:recursive? #t> #:select? (or (git-predicate source-dir)> (const #t))))> (instance -> (checkout->channel-instance source))> (new-guix-current -> (channel-instance->package instance)))> (return (parameterize ((current-guix-package new-guix-current))> ((@@ (gnu tests install) operating-system-with-current-guix)> (@@ (gnu tests install) %btrfs-root-os)))))))))'
There have been some changes made to the modules used in the benchmark codeabove. Here's an updated version:
Toggle snippet (27 lines)time ./pre-inst-env guix system build -e \'(begin (use-modules ((gnu ci) #:select (channel-source->package)) (guix monads) (guix channels) (guix store) ((guix status) #:select (with-status-verbosity)) ((guix git-download) #:select (git-predicate)) (guix utils) (gnu packages package-management)) (with-store store (with-status-verbosity 2 (run-with-store store (mlet* %store-monad ((source-dir -> "/home/mcournoyer/src/guix") (source (interned-file source-dir "guix-source" #:recursive? #t #:select? (or (git-predicate source-dir) (const #t)))) (instance -> (checkout->channel-instance source)) (new-guix-current -> (channel-source->package instance))) (return (parameterize ((current-guix-package new-guix-current)) ((@@ (gnu tests install) operating-system-with-current-guix) (@@ (gnu tests install) %btrfs-root-os)))))))))'
Time taken:
real 7m39.912suser 0m57.129ssys 0m0.499s
Compared to recycling the Guix development copy from the work tree:
real 0m48.297suser 0m2.516ssys 0m0.229s
Maxim
M
M
maxim.cournoyer wrote on 18 Mar 2020 16:27
Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
(name . Ludovic Courtès)(address . ludo@gnu.org)
87v9n1pts1.fsf@raisin.i-did-not-set--mail-host-address--so-tickle-me
Hi Ludovic,
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (26 lines)> Hi Maxim,>> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:>>>>> + (error "The store is on a Btrfs subvolume, but the \>>>> +subvolume name is unknown.>>>> +Hint: Define the \"btrfs-subvolume-path\" file system property or>>>> +use the \"subvol\" Btrfs file system option."))))>>>>> Rather use ‘raise’ with ‘&message’ and ‘&fix-hint’ conditions.>>>> I tried this, but importing (guix utils) to acces &fix-hint caused the init>> RAM disk to fail mysteriously:>> Oh, my bad. We should move ‘&fix-hint’ to (guix diagnostics)> eventually.>> In the meantime, I’d say just raise a ‘&message’ and leave the hint as a> comment (it’s not supposed to be a user-facing interface). Or maybe you> could define a specific error condition type for this?>> Thanks,> Ludo’.>> PS: I’ll comment on the other bits ASAP!
The remaining, reworked patches for this series are attached below. Ifyou don't want to merge the 0001 for now (speeding up tests), I don'tmind too much (though it still provides value to me, when using oldhardware).
Thanks for your patience :-)
Maxim
From 62bb442870864a8e867023f95d814dc1b389512a Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 17 Nov 2019 06:01:00 +0900Subject: [PATCH 1/5] gnu: tests: Reduce the time required to run the system tests.
When setting the GUIX_DEV_HACKS environment variable, the Guix package usedinside the instrumented VMs recycles the binaries already found in the Guixcheckout of the developer instead of rebuilding Guix from scratch. Thisbrings the time required for this component from 20+ minutes down to 2-3minutes on an X200 machine.
* gnu/packages/package-management.scm (current-guix/pre-built): New procedure.* etc/system-tests.scm (tests-for-channel-instance): Use it, whenGUIX_DEV_HACKS is defined.--- etc/system-tests.scm | 5 ++- gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-)
Toggle diff (101 lines)diff --git a/etc/system-tests.scm b/etc/system-tests.scmindex ab2827e70a..5fc5d91ea3 100644--- a/etc/system-tests.scm+++ b/etc/system-tests.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -49,7 +50,9 @@ instance." ;; ;; make check-system TESTS=installed-os (parameterize ((current-guix-package- (channel-source->package source #:commit commit)))+ (if (getenv "GUIX_DEV_HACKS")+ (current-guix/pre-built)+ (channel-source->package source #:commit commit)))) (match (getenv "TESTS") (#f (all-system-tests))diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scmindex b0457ba87a..4788358e5a 100644--- a/gnu/packages/package-management.scm+++ b/gnu/packages/package-management.scm@@ -468,6 +468,72 @@ out) and returning a package that uses that as its 'source'." #:recursive? #t #:select? (force select?)))))))) +(define-public (current-guix/pre-built)+ "Similar to `current-guix', but with a modified build procedure that+reuses the existing byte compiled artifacts to save recompilation time."++ (let* ( ;; The `current-source-directory' macro doesn't work from the REPL.+ ;; For testing, you can replace it with a static string pointing to+ ;; your Guix checkout directory.+ (repository-root (delay (canonicalize-path+ (string-append (current-source-directory)+ "/../.."))))+ (select? (lambda (file stat)+ (match (basename file)+ ((or ".git"+ "configure" "autom4te.cache"+ "config.log" "config.status"+ "stamp-1" "stamp-2" "stamp-3" "stamp-4" "stamp-5"+ "stamp-h1" "stamp-vti"+ "Makefile" "Makefile.in" ".libs"+ ".deps" ".dirstamp"+ "test-tmp"+ ) #f)+ (_ #t)))))+ (package+ (inherit guix)+ (version (string-append (package-version guix) "+"))+ (source (local-file (force repository-root) "guix-current"+ #:recursive? #t+ #:select? select?))+ (arguments+ (substitute-keyword-arguments (package-arguments guix)+ ((#:phases phases)+ `(modify-phases ,phases+ ;; XXX: References to tools such as 'mkdir' and 'install' are+ ;; captured in Makefile.in when 'autoconf' is run. It'd be nicer+ ;; to find those at configuration time.+ (delete 'copy-bootstrap-guile)+ (delete 'check)+ (delete 'disable-failing-tests)+ (delete 'strip) ;can't strip .go files anyway+ (replace 'build+ (lambda _+ ;; Set the write permission bit on some files that need to be+ ;; touched.+ (chmod "nix" #o777)+ (for-each (lambda (f)+ (chmod f #o666))+ (cons* "guix-daemon"+ (find-files "." ".*\\.(a|o)$")))++ ;; The following prevent 'make install' from rebuilding the+ ;; daemon and the documentation.+ (invoke "make" "--touch" "info"+ ;; TODO: Currently we must rebuild the daemon as it+ ;; was linked against external dependencies that+ ;; depend on the provenance of the profile (or+ ;; environment) that was used to build it.++ ;; If we could query the provenance of any profile,+ ;; we could make this package inherit from the guix+ ;; inferior that was used to provide such+ ;; dependencies. The most reliable way would+ ;; probably be to record that provenance at build+ ;; time (as a make target).+ ;"guix-daemon"+ ))))))))))+ ;;; ;;; Other tools.-- 2.25.1
From c60913505af32c2005ffc9bb3ea7078de5379c54 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:00:06 -0500Subject: [PATCH 2/5] linux-boot: Refactor boot-system.
The --root option can now be omitted, and inferred from the root file systemdeclaration instead.
* gnu/build/linux-boot.scm (boot-system): Remove nested definitions forroot-fs-type, root-fs-flags and root-fs-options, and bind those inside thelet* instead. Make "--root" take precedence over the device field stringrepresentation of the root file system.* doc/guix.texi (Initial RAM Disk): Document that "--root" can be leftunspecified.--- doc/guix.texi | 7 +++-- gnu/build/linux-boot.scm | 60 +++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 35 deletions(-)
Toggle diff (105 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex d1fa8d033a..11b6884cab 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -26058,9 +26058,10 @@ service activation programs and then spawns the GNU@tie{}Shepherd, the initialization system. @item --root=@var{root}-Mount @var{root} as the root file system. @var{root} can be a-device name like @code{/dev/sda1}, a file system label, or a file system-UUID.+Mount @var{root} as the root file system. @var{root} can be a device+name like @code{/dev/sda1}, a file system label, or a file system UUID.+When unspecified, the device name from the root file system of the+operating system declaration is used. @item --system=@var{system} Have @file{/run/booted-system} and @file{/run/current-system} point todiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex 4fb711b8f2..3a9c761a69 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -467,25 +467,13 @@ upon error." (define (root-mount-point? fs) (string=? (file-system-mount-point fs) "/")) - (define root-fs-type- (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-type fs)))- mounts)- "ext4"))-- (define root-fs-flags- (mount-flags->bit-mask (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-flags fs)))- mounts)- '())))-- (define root-fs-options- (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-options fs)))- mounts))+ (define (device-string->file-system-device device-string)+ ;; The "--root=SPEC" kernel command-line option always provides a+ ;; string, but the string can represent a device, a UUID, or a+ ;; label. So check for all three.+ (cond ((string-prefix? "/" device-string) device-string)+ ((uuid device-string) => identity)+ (else (file-system-label device-string)))) (display "Welcome, this is GNU's early boot Guile.\n") (display "Use '--repl' for an initrd REPL.\n\n")@@ -495,7 +483,21 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root-fs (find root-mount-point? mounts))+ (root-fs-type (or (and=> root-fs file-system-type)+ "ext4"))+ (root-fs-device (and=> root-fs file-system-device))+ (root-fs-flags (mount-flags->bit-mask+ (or (and=> root-fs file-system-flags)+ '())))+ (root-options (if root-fs+ (file-system-options root-fs)+ #f))+ ;; --root takes precedence over the 'device' field of the root+ ;; <file-system> record.+ (root-device (or (and=> (find-long-option "--root" args)+ device-string->file-system-device)+ root-fs-device))) (when (member "--repl" args) (start-repl))@@ -530,18 +532,12 @@ upon error." (setenv "EXT2FS_NO_MTAB_OK" "1") - (if root- ;; The "--root=SPEC" kernel command-line option always provides a- ;; string, but the string can represent a device, a UUID, or a- ;; label. So check for all three.- (let ((root (cond ((string-prefix? "/" root) root)- ((uuid root) => identity)- (else (file-system-label root)))))- (mount-root-file-system (canonicalize-device-spec root)- root-fs-type- #:volatile-root? volatile-root?- #:flags root-fs-flags- #:options root-fs-options))+ (if root-device+ (mount-root-file-system (canonicalize-device-spec root-device)+ root-fs-type+ #:volatile-root? volatile-root?+ #:flags root-fs-flags+ #:options root-options) (mount "none" "/root" "tmpfs")) ;; Mount the specified file systems.-- 2.25.1
From 62f62a1b49adbe13a1d401ac16f56d58fda2af78 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 25 Sep 2019 22:43:41 +0900Subject: [PATCH 3/5] file-systems: Add helpers for parsing the options string into an alist.
* gnu/system/file-systems.scm (file-system-options->alist)(alist->file-system-options): New procedures.* tests/file-systems.scm: New tests.* doc/guix.texi (File Systems): Add note about the newly added procedures.--- doc/guix.texi | 12 ++++++++---- gnu/system/file-systems.scm | 31 +++++++++++++++++++++++++++++++ tests/file-systems.scm | 19 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-)
Toggle diff (114 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 11b6884cab..f55098cfd5 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11501,10 +11501,14 @@ update time on the in-memory version of the file inode), and Manual}, for more information on these flags. @item @code{options} (default: @code{#f})-This is either @code{#f}, or a string denoting mount options passed to the-file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library-Reference Manual}, for details and run @command{man 8 mount} for options for-various file systems.+This is either @code{#f}, or a string denoting mount options passed to+the file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C+Library Reference Manual}, for details and run @command{man 8 mount} for+options for various file systems. Note that the+@code{file-system-options->alist} and @code{alist->file-system-options}+procedures from @code{(gnu system file-systems)} can be used to convert+file system options given as an association list to the string+representation, and vice-versa. @item @code{mount?} (default: @code{#t}) This value indicates whether to automatically mount the file system whendiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 3b599efa8e..bde2b93702 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -37,6 +38,9 @@ file-system-needed-for-boot? file-system-flags file-system-options+ file-system-options->alist+ alist->file-system-options+ file-system-mount? file-system-check? file-system-create-mount-point?@@ -250,6 +254,33 @@ UUID-TYPE, a symbol such as 'dce or 'iso9660." ((? string?) device))) +(define (file-system-options->alist string)+ "Translate the option string format of a <file-system> record into an+association list of options or option/value pairs."+ (if string+ (let ((options (string-split string #\,)))+ (map (lambda (param)+ (let ((=index (string-index param #\=)))+ (if =index+ (cons (string-take param =index)+ (string-drop param (1+ =index)))+ param)))+ options))+ '()))++(define (alist->file-system-options options)+ "Return the string representation of OPTIONS, an association list. The+string obtained can be used as the option field of a <file-system> record."+ (if (null? options)+ #f+ (string-join (map (match-lambda+ ((key . value)+ (string-append key "=" value))+ (key+ key))+ options)+ ",")))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 4c28d0ebc5..41f1021067 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -64,4 +65,22 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(test-equal "file-system-options->alist"+ '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))+ (file-system-options->alist "autodefrag,subvol=home,compress=lzo"))++(test-equal "file-system-options->alist (#f)"+ '()+ (file-system-options->alist #f))++(test-equal "alist->file-system-options"+ "autodefrag,subvol=root,compress=lzo"+ (alist->file-system-options '("autodefrag"+ ("subvol" . "root")+ ("compress" . "lzo"))))++(test-equal "alist->file-system-options (null)"+ #f+ (alist->file-system-options '()))+ (test-end)-- 2.25.1
From 12e7ca2628a7e16a1afacfd8953bd6bcfe5c10bd Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH 4/5] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.(normalize-file): Add procedure.(grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. Whendefined, prepend its value to the kernel and initrd file names, using theNORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass theBTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.(eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along withthe NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nestedvariables. Adjust doc.* gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.* gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.* gnu/system/file-systems.scm (btrfs-subvolume?)(btrfs-store-subvolume-file-name): New procedures.* gnu/system.scm (operating-system-bootcfg): Specify the Btrfssubvolume file name the store resides on to the`operating-system-bootcfg' procedure, using the newBTRFS-SUBVOLUME-FILE-NAME argument.* doc/guix.texi (File Systems): Add a Btrfs subsection to document the use ofsubvolumes.* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".--- doc/guix.texi | 104 ++++++++++++++++++++++++++++ gnu/bootloader/depthcharge.scm | 3 +- gnu/bootloader/extlinux.scm | 3 +- gnu/bootloader/grub.scm | 122 ++++++++++++++++++++------------- gnu/system.scm | 9 ++- gnu/system/file-systems.scm | 58 ++++++++++++++++ gnu/tests/install.scm | 94 +++++++++++++++++++++++++ tests/file-systems.scm | 45 ++++++++++++ 8 files changed, 388 insertions(+), 50 deletions(-)
Toggle diff (617 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex f55098cfd5..5dfd62d02f 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11589,6 +11589,110 @@ and unmount user-space FUSE file systems. This requires the @code{fuse.ko} kernel module to be loaded. @end defvr +@node Btrfs file system+@subsection Btrfs file system++The Btrfs has special features, such as subvolumes, that merit being+explained in more details. The following section attempts to cover+basic as well as complex uses of a Btrfs file system with the Guix+System.++In its simplest usage, a Btrfs file system can be described, for+example, by:++@lisp+(file-system+ (mount-point "/home")+ (type "btrfs")+ (device (file-system-label "my-home")))+@end lisp++The example below is more complex, as it makes use of a Btrfs+subvolume, named @code{rootfs}. The parent Btrfs file system is labeled+@code{my-btrfs-pool}, and is located on an encrypted device (hence the+dependency on @code{mapped-devices}):++@lisp+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options "subvol=rootfs")+ (dependencies mapped-devices))+@end lisp++Some bootloaders, for example GRUB, only mount a Btrfs partition at its+top level during the early boot, and rely on their configuration to+refer to the correct subvolume path within that top level. The+bootloaders operating in this way typically produce their configuration+on a running system where the Btrfs partitions are already mounted and+where the subvolume information is readily available. As an example,+@command{grub-mkconfig}, the configuration generator command shipped+with GRUB, reads @file{/proc/self/mountinfo} to determine the top-level+path of a subvolume.++The Guix System produces a bootloader configuration using the operating+system configuration as its sole input; it is therefore necessary to+extract the subvolume name on which @file{/gnu/store} lives (if any)+from that operating system configuration. To better illustrate,+consider a subvolume named 'rootfs' which contains the root file system+data. In such situation, the GRUB bootloader would only see the top+level of the root Btrfs partition, e.g.:++@example+/ (top level)+├── rootfs (subvolume directory)+ ├── gnu (normal directory)+ ├── store (normal directory)+[...]+@end example++Thus, the subvolume name must be prepended to the @file{/gnu/store} path+of the kernel, initrd binaries and any other files referred to in the+GRUB configuration that must be found during the early boot.++The next example shows a nested hierarchy of subvolumes and+directories:++@example+/ (top level)+├── rootfs (subvolume)+ ├── gnu (normal directory)+ ├── store (subvolume)+[...]+@end example++This scenario would work without mounting the 'store' subvolume.+Mounting 'rootfs' is sufficient, since the subvolume name matches its+intended mount point in the file system hierarchy. Alternatively, the+'store' subvolume could be referred to by setting the @code{subvol}+option to either @code{/rootfs/gnu/store} or @code{rootfs/gnu/store}.++Finally, a more contrived example of nested subvolumes:++@example+/ (top level)+├── root-snapshots (subvolume)+ ├── root-current (subvolume)+ ├── guix-store (subvolume)+[...]+@end example++Here, the 'guix-store' subvolume doesn't match its intended mount point,+so it is necessary to mount it. The subvolume must be fully specified,+by passing its file name to the @code{subvol} option. To illustrate,+the 'guix-store' subvolume could be mounted on @file{/gnu/store} by using+a file system declaration such as:++@lisp+(file-system+ (device (file-system-label "btrfs-pool-1"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvol=root-snapshots/root-current/guix-store"+ ("compress" . "zstd")))+@end lisp+ @node Mapped Devices @section Mapped Devices diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scmindex 58cc3f3932..0a50374bd9 100644--- a/gnu/bootloader/depthcharge.scm+++ b/gnu/bootloader/depthcharge.scm@@ -82,7 +82,8 @@ (define* (depthcharge-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) (match entries ((entry) (let ((kernel (menu-entry-linux entry))diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scmindex 5b4dd84965..6b5ff298e7 100644--- a/gnu/bootloader/extlinux.scm+++ b/gnu/bootloader/extlinux.scm@@ -28,7 +28,8 @@ (define* (extlinux-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) "Return the U-Boot configuration file corresponding to CONFIG, a <u-boot-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu entriesdiff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex 28e6cb1f5f..e7a6f928c6 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -63,18 +63,29 @@ ;;; ;;; Code: -(define (strip-mount-point mount-point file)- "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable object-denoting a file name."- (match mount-point- ((? string? mount-point)- (if (string=? mount-point "/")- file- #~(let ((file #$file))- (if (string-prefix? #$mount-point file)- (substring #$file #$(string-length mount-point))- file))))- (#f file)))+(define* (normalize-file file mount-point btrfs-subvolume-file-name)+ "Strip MOUNT-POINT and prepend BTRFS-SUBVOLUME-FILE-NAME to FILE, a+G-expression or other lowerable object denoting a file name."++ (define (strip-mount-point mount-point file)+ (if mount-point+ (if (string=? mount-point "/")+ file+ #~(let ((file #$file))+ (if (string-prefix? #$mount-point file)+ (substring #$file #$(string-length mount-point))+ file)))+ file))++ (define (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name file)+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name #$file)+ file))++ (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name+ (strip-mount-point mount-point file)))++ (define-record-type* <grub-image> grub-image make-grub-image@@ -142,13 +153,15 @@ WIDTH/HEIGHT, or #f if none was found." #:width width #:height height)))) (define* (eye-candy config store-device store-mount-point+ btrfs-store-subvolume-file-name #:key system port)- "Return a gexp that writes to PORT (a port-valued gexp) the-'grub.cfg' part concerned with graphics mode, background images, colors, and-all that. STORE-DEVICE designates the device holding the store, and-STORE-MOUNT-POINT is its mount point; these are used to determine where the-background image and fonts must be searched for. SYSTEM must be the target-system string---e.g., \"x86_64-linux\"."+ "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part+concerned with graphics mode, background images, colors, and all that.+STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POINT is+its mount point; these are used to determine where the background image and+fonts must be searched for. SYSTEM must be the target system string---e.g.,+\"x86_64-linux\". BTRFS-STORE-SUBVOLUME-FILE-NAME is the file name of the+Btrfs subvolume, to be prepended to any store path, if any." (define setup-gfxterm-body (let ((gfxmode (or (and-let* ((theme (bootloader-configuration-theme config))@@ -185,11 +198,14 @@ fi~%" #$font-file) (symbol->string (assoc-ref colors 'bg))))) (define font-file- (strip-mount-point store-mount-point- (file-append grub "/share/grub/unicode.pf2")))+ (normalize-file (file-append grub "/share/grub/unicode.pf2")+ store-mount-point+ btrfs-store-subvolume-file-name)) (define image- (grub-background-image config))+ (normalize-file (grub-background-image config)+ store-mount-point+ btrfs-store-subvolume-file-name)) (and image #~(format #$port "@@ -214,7 +230,7 @@ fi~%" #$(setup-gfxterm config font-file) #$(grub-setup-io config) - #$(strip-mount-point store-mount-point image)+ #$image #$(theme-colors grub-theme-color-normal) #$(theme-colors grub-theme-color-highlight)))) @@ -318,52 +334,66 @@ code." (define* (grub-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ btrfs-subvolume-file-name) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at-STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu-entries corresponding to old generations of the system."+STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list+of menu entries corresponding to old generations of the system.+BTRFS-SUBVOLUME-FILE-NAME may be used to specify on which subvolume a+Btrfs root file system resides." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (arguments (menu-entry-linux-arguments entry))+ (kernel (normalize-file (menu-entry-linux entry)+ device-mount-point+ btrfs-subvolume-file-name))+ (initrd (normalize-file (menu-entry-initrd entry)+ device-mount-point+ btrfs-subvolume-file-name))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))- #~(format port "menuentry ~s {++ ;; When BTRFS-SUBVOLUME-FILE-NAME is defined, prepend it the kernel and+ ;; initrd paths, to allow booting from a Btrfs subvolume.+ #~(format port "menuentry ~s { ~a linux ~a ~a initrd ~a }~%"- #$label- #$(grub-root-search device kernel)- #$kernel (string-join (list #$@arguments))- #$initrd))))+ #$label+ #$(grub-root-search device kernel)+ #$kernel (string-join (list #$@arguments))+ #$initrd))) (define sugar (eye-candy config (menu-entry-device (first all-entries)) (menu-entry-device-mount-point (first all-entries))+ btrfs-subvolume-file-name #:system system #:port #~port)) (define keyboard-layout-config- (let ((layout (bootloader-configuration-keyboard-layout config))- (grub (bootloader-package- (bootloader-configuration-bootloader config))))- #~(let ((keymap #$(and layout- (keyboard-layout-file layout #:grub grub))))- (when keymap- (format port "\+ (let* ((layout (bootloader-configuration-keyboard-layout config))+ (grub (bootloader-package+ (bootloader-configuration-bootloader config)))+ (keymap* (and layout+ (keyboard-layout-file layout #:grub grub)))+ (keymap (and keymap*+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name+ #$keymap*)+ keymap*))))+ #~(when #$keymap+ (format port "\ insmod keylayouts-keymap ~a~%" keymap)))))+keymap ~a~%" #$keymap)))) (define builder #~(call-with-output-file #$outputdiff --git a/gnu/system.scm b/gnu/system.scmindex 06c58c27ba..d1f1b43426 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -5,6 +5,7 @@ ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> ;;; Copyright © 2019 Meiyo Peng <meiyo.peng@gmail.com>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -1001,19 +1002,23 @@ entry." (define* (operating-system-bootcfg os #:optional (old-entries '())) "Return the bootloader configuration file for OS. Use OLD-ENTRIES, a list of <menu-entry>, to populate the \"old entries\" menu."- (let* ((root-fs (operating-system-root-file-system os))+ (let* ((file-systems (operating-system-file-systems os))+ (root-fs (operating-system-root-file-system os)) (root-device (file-system-device root-fs)) (params (operating-system-boot-parameters os root-device #:system-kernel-arguments? #t)) (entry (boot-parameters->menu-entry params)) (bootloader-conf (operating-system-bootloader os)))+ (define generate-config-file (bootloader-configuration-file-generator (bootloader-configuration-bootloader bootloader-conf))) (generate-config-file bootloader-conf (list entry)- #:old-entries old-entries)))+ #:old-entries old-entries+ #:btrfs-subvolume-file-name+ (btrfs-store-subvolume-file-name file-systems)))) (define* (operating-system-boot-parameters os root-device #:key system-kernel-arguments?)diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex bde2b93702..617ef97814 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -21,7 +21,10 @@ #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-35) #:use-module (srfi srfi-9 gnu) #:use-module (guix records) #:use-module (gnu system uuid)@@ -48,6 +51,8 @@ file-system-location file-system-type-predicate+ btrfs-subvolume?+ btrfs-store-subvolume-file-name file-system-label file-system-label?@@ -565,4 +570,57 @@ system has the given TYPE." (lambda (fs) (string=? (file-system-type fs) type))) + +;;;+;;; Btrfs specific helpers.+;;;++(define (btrfs-subvolume? fs)+ "Predicate to check if FS, a file-system object, is a Btrfs subvolume."+ (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))+ (option-keys (map (match-lambda+ ((key . value) key)+ (key key))+ (file-system-options->alist+ (file-system-options fs)))))+ (find (cut string-prefix? "subvol" <>) option-keys)))++(define (btrfs-store-subvolume-file-name file-systems)+ "Return the subvolume file name within the Btrfs top level onto which the+store is located, else #f."++ (define (prepend-slash/maybe s)+ (if (string=? "/" (string-take s 1))+ s+ (string-append "/" s)))++ (define (file-name-depth file-name)+ (length (string-tokenize file-name %not-slash)))++ (and-let* ((btrfs-subvolume-fs (filter btrfs-subvolume? file-systems))+ (btrfs-subvolume-fs*+ (sort btrfs-subvolume-fs+ (lambda (fs1 fs2)+ (> (file-name-depth (file-system-mount-point fs1))+ (file-name-depth (file-system-mount-point fs2))))))+ (store-subvolume-fs+ (find (lambda (fs) (file-prefix? (file-system-mount-point fs)+ (%store-prefix)))+ btrfs-subvolume-fs*))+ (options (file-system-options->alist+ (file-system-options store-subvolume-fs))))+ ;; XXX: Deriving the subvolume name based from a subvolume ID is not+ ;; supported, as we'd need to query the actual file system.+ (or (and=> (assoc-ref options "subvol") prepend-slash/maybe)+ ;; XXX: Importing (guix utils) and using &fix-hint causes the+ ;; following error when booting the init RAM disk: "ERROR: In+ ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol not+ ;; found: strverscmp", so we just embed the hint in the message.+ (raise (condition+ (&message+ (message "The store is on a Btrfs subvolume, but the \+subvolume name is unknown.+Hint: Use the \"subvol\" Btrfs file system option.")))))))++ ;;; file-systems.scm ends herediff --git a/gnu/tests/install.scm b/gnu/tests/install.scmindex 9ecc45cc04..af266e03a1 100644--- a/gnu/tests/install.scm+++ b/gnu/tests/install.scm@@ -48,6 +48,7 @@ %test-raid-root-os %test-encrypted-root-os %test-btrfs-root-os+ %test-btrfs-root-on-subvolume-os %test-jfs-root-os %test-gui-installed-os@@ -834,6 +835,99 @@ build (current-guix) and then store a couple of full system images.") (command (qemu-command/writable-image image))) (run-basic-test %btrfs-root-os command "btrfs-root-os"))))) + +;;;+;;; Btrfs root file system on a subvolume.+;;;++(define-os-with-source (%btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source)+ ;; The OS we want to install.+ (use-modules (gnu) (gnu tests) (srfi srfi-1))++ (operating-system+ (host-name "hurd")+ (timezone "America/Montreal")+ (locale "en_US.UTF-8")+ (bootloader (bootloader-configuration+ (bootloader grub-bootloader)+ (target "/dev/vdb")))+ (kernel-arguments '("console=ttyS0"))+ (file-systems (cons* (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (options "subvol=rootfs,compress=zstd")+ (type "btrfs"))+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (options "subvol=homefs,compress=lzo")+ (type "btrfs"))+ %base-file-systems))+ (users (cons (user-account+ (name "charlie")+ (group "users")+ (supplementary-groups '("wheel" "audio" "video")))+ %base-user-accounts))+ (services (cons (service marionette-service-type+ (marionette-configuration+ (imported-modules '((gnu services herd)+ (guix combinators)))))+ %base-services))))++(define %btrfs-root-on-subvolume-installation-script+ ;; Shell script of a simple installation.+ "\+. /etc/profile+set -e -x+guix --version++export GUIX_BUILD_OPTIONS=--no-grafts+ls -l /run/current-system/gc-roots+parted --script /dev/vdb mklabel gpt \\+ mkpart primary ext2 1M 3M \\+ mkpart primary ext2 3M 2G \\+ set 1 boot on \\+ set 1 bios_grub on++# Setup the top level Btrfs file system with its subvolume.+mkfs.btrfs -L btrfs-pool /dev/vdb2+mount /dev/vdb2 /mnt+btrfs subvolume create /mnt/rootfs+btrfs subvolume create /mnt/homefs+umount /dev/vdb2++# Mount the subvolumes, ready for installation.+mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt+mkdir /mnt/home+mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home++herd start cow-store /mnt+mkdir /mnt/etc+cp /etc/target-config.scm /mnt/etc/config.scm+guix system build /mnt/etc/config.scm+guix system init /mnt/etc/config.scm /mnt --no-substitutes+sync+reboot\n")++(define %test-btrfs-root-on-subvolume-os+ (system-test+ (name "btrfs-root-on-subvolume-os")+ (description+ "Test basic functionality of an OS installed like one would do by hand.+This test is expensive in terms of CPU and storage usage since we need to+build (current-guix) and then store a couple of full system images.")+ (value+ (mlet* %store-monad+ ((image+ (run-install %btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source+ #:script+ %btrfs-root-on-subvolume-installation-script))+ (command (qemu-command/writable-image image)))+ (run-basic-test %btrfs-root-on-subvolume-os command+ "btrfs-root-on-subvolume-os")))))+ ;;; ;;; JFS root file system.diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 41f1021067..7f7c373884 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -83,4 +83,49 @@ #f (alist->file-system-options '())) + +;;;+;;; Btrfs related.+;;;++(define %btrfs-root-subvolume+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options "subvol=rootfs,compress=zstd")))++(define %btrfs-store-subvolid+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvolid=10,compress=zstd")+ (dependencies (list %btrfs-root-subvolume))))++(define %btrfs-store-subvolume+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvol=/some/nested/file/name")+ (dependencies (list %btrfs-root-subvolume))))++(test-assert "btrfs-subvolume? (subvol)"+ (btrfs-subvolume? %btrfs-root-subvolume))++(test-assert "btrfs-subvolume? (subvolid)"+ (btrfs-subvolume? %btrfs-store-subvolid))++(test-equal "btrfs-store-subvolume-file-name"+ "/some/nested/file/name"+ (parameterize ((%store-prefix "/gnu/store"))+ (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume+ %btrfs-store-subvolume))))++(test-error "btrfs-store-subvolume-file-name (subvolid)"+ (parameterize ((%store-prefix "/gnu/store"))+ (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume+ %btrfs-store-subvolid))))+ (test-end)-- 2.25.1
M
M
Maxim Cournoyer wrote on 31 Mar 2020 03:26
control message for bug #40236
(address . control@debbugs.gnu.org)
87lfnhz544.fsf@gmail.com
block 40236 by 37305quit
P
P
Pierre Neidhardt wrote on 17 May 2020 15:29
Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
(address . maxim.cournoyer@gmail.com)
87o8qmheqm.fsf@ambrevar.xyz
I'll try to test this patch, possibly today.
Is the patch from the 18th of March the right one?The patch says it has 5 components but the last patch is
Toggle snippet (3 lines)[PATCH 4/5] bootloader: grub: Allow booting from a Btrfs subvolume.
Is the fifth patch missing?
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7BPCEACgkQm9z0l6S7zH/ZAAgAirRshRTm3Z4MYsRBSEJTIeZlXFHv/3f8V6g02J27iEqigrfA2xJZy7bQwvAGvCoSSMOssVtn48tTTCPtHcDHaBPb9wZOoIGb+UDHvq3cJcXIrLpC0YrbdRk5zKh1/Lqx7wejiyoXWGLpeRpL8BOcLAtlNVYDBlp+UeLM4Aey/Og5c5/tv+9bwIHLLdtP9YCRz6xhjuZbgMlX0+eh591OGStBklrSArrZINz9UVESJ+to1GuwjsDmddbMT0DoepUn7r36oWvV3YhuuHX5k81Zo4B9peTOfvheFqkjwyJJZbWDfdsT/c2nZ0JcKhsk3hZzGApH/w7Xcz+BAXUkgF4qSg===MyaO-----END PGP SIGNATURE-----
P
P
Pierre Neidhardt wrote on 17 May 2020 16:03
(address . maxim.cournoyer@gmail.com)
87lflqhd4y.fsf@ambrevar.xyz
Hi Maxim!
maxim.cournoyer@gmail.com writes:
Toggle quote (8 lines)> +@lisp> +(file-system> + (device (file-system-label "btrfs-pool-1"))> + (mount-point "/gnu/store")> + (type "btrfs")> + (options "subvol=root-snapshots/root-current/guix-store"> + ("compress" . "zstd")))> +@end lisp
Is this ("compress" . "zstd") intentional? It does not match the first example.
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7BRD0ACgkQm9z0l6S7zH8/iwgAoZ/j/mi8Zhzm3BbzgfyIjeZ3d9V5EVUVKmNJx1EVFNHa16mGVMUA1mKAo+8CaTH8S6oLIvcIR3cOWDSY9t4JjRP4UahjXyL5722nCR4EL+jLOu/mgBFQ6GJ8h6OMpKlCkOZ5tbunSXPC2gz5Y5b8F01D+xgDlOAGcMe2w9fMyaRaCcK4IWv7TJPr3KpBZvOolnr2460Q6lqjmRV3wWfOpwfwpXRiOjgbvwIHL1t3GB03Jko0FK2yMyBGWPsP0G1g2jKyF2M06s5xEtXgtXM920A7O/Cgxt9VLkHv1mIpB5EN2PdlF9dGQB78VR7OM0KDQr4zo+DHzM0kFjd/Pm25yg===TKSC-----END PGP SIGNATURE-----
M
M
Maxim Cournoyer wrote on 17 May 2020 18:13
Re: [PATCH v3] Allow booting from a Btrfs subvolume
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
874ksebkup.fsf_-_@gmail.com
Hi Pierre!
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (9 lines)> I'll try to test this patch, possibly today.>> Is the patch from the 18th of March the right one?> The patch says it has 5 components but the last patch is>> [PATCH 4/5] bootloader: grub: Allow booting from a Btrfs subvolume.>> Is the fifth patch missing?
As I send my patches as attachments rather than with git send-email, Isimply forgot to update the subject line counter. There are fourpatches in total, although the hack in 0001 was controversial so isincluded as a curiosity only. I've rebased the 4 patches on currentmaster, and fixed some conflict that arose in the initrd code.
From b72da2bbc450303ffa804b840b5cbbb6efd28b2f Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 17 Nov 2019 06:01:00 +0900Subject: [PATCH 1/4] gnu: tests: Reduce the time required to run the system tests.
When setting the GUIX_DEV_HACKS environment variable, the Guix package usedinside the instrumented VMs recycles the binaries already found in the Guixcheckout of the developer instead of rebuilding Guix from scratch. Thisbrings the time required for this component from 20+ minutes down to 2-3minutes on an X200 machine.
* gnu/packages/package-management.scm (current-guix/pre-built): New procedure.* etc/system-tests.scm (tests-for-channel-instance): Use it, whenGUIX_DEV_HACKS is defined.--- etc/system-tests.scm | 5 ++- gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-)
Toggle diff (101 lines)diff --git a/etc/system-tests.scm b/etc/system-tests.scmindex 1085deed24..3bf684e584 100644--- a/etc/system-tests.scm+++ b/etc/system-tests.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2016, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -49,7 +50,9 @@ instance." ;; ;; make check-system TESTS=installed-os (parameterize ((current-guix-package- (channel-source->package source #:commit commit)))+ (if (getenv "GUIX_DEV_HACKS")+ (current-guix/pre-built)+ (channel-source->package source #:commit commit)))) (match (getenv "TESTS") (#f (all-system-tests))diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scmindex 3fc6fc404a..4a6f37ba11 100644--- a/gnu/packages/package-management.scm+++ b/gnu/packages/package-management.scm@@ -534,6 +534,72 @@ out) and returning a package that uses that as its 'source'." #:recursive? #t #:select? (force select?)))))))) +(define-public (current-guix/pre-built)+ "Similar to `current-guix', but with a modified build procedure that+reuses the existing byte compiled artifacts to save recompilation time."++ (let* ( ;; The `current-source-directory' macro doesn't work from the REPL.+ ;; For testing, you can replace it with a static string pointing to+ ;; your Guix checkout directory.+ (repository-root (delay (canonicalize-path+ (string-append (current-source-directory)+ "/../.."))))+ (select? (lambda (file stat)+ (match (basename file)+ ((or ".git"+ "configure" "autom4te.cache"+ "config.log" "config.status"+ "stamp-1" "stamp-2" "stamp-3" "stamp-4" "stamp-5"+ "stamp-h1" "stamp-vti"+ "Makefile" "Makefile.in" ".libs"+ ".deps" ".dirstamp"+ "test-tmp"+ ) #f)+ (_ #t)))))+ (package+ (inherit guix)+ (version (string-append (package-version guix) "+"))+ (source (local-file (force repository-root) "guix-current"+ #:recursive? #t+ #:select? select?))+ (arguments+ (substitute-keyword-arguments (package-arguments guix)+ ((#:phases phases)+ `(modify-phases ,phases+ ;; XXX: References to tools such as 'mkdir' and 'install' are+ ;; captured in Makefile.in when 'autoconf' is run. It'd be nicer+ ;; to find those at configuration time.+ (delete 'copy-bootstrap-guile)+ (delete 'check)+ (delete 'disable-failing-tests)+ (delete 'strip) ;can't strip .go files anyway+ (replace 'build+ (lambda _+ ;; Set the write permission bit on some files that need to be+ ;; touched.+ (chmod "nix" #o777)+ (for-each (lambda (f)+ (chmod f #o666))+ (cons* "guix-daemon"+ (find-files "." ".*\\.(a|o)$")))++ ;; The following prevent 'make install' from rebuilding the+ ;; daemon and the documentation.+ (invoke "make" "--touch" "info"+ ;; TODO: Currently we must rebuild the daemon as it+ ;; was linked against external dependencies that+ ;; depend on the provenance of the profile (or+ ;; environment) that was used to build it.++ ;; If we could query the provenance of any profile,+ ;; we could make this package inherit from the guix+ ;; inferior that was used to provide such+ ;; dependencies. The most reliable way would+ ;; probably be to record that provenance at build+ ;; time (as a make target).+ ;"guix-daemon"+ ))))))))))+ ;;; ;;; Other tools.-- 2.26.2
From b03a574ad565b34bbe8a7d3d0322591850984dc6 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Tue, 11 Feb 2020 14:00:06 -0500Subject: [PATCH 2/4] linux-boot: Refactor boot-system.
The --root option can now be omitted, and inferred from the root file systemdeclaration instead.
* gnu/build/file-systems.scm (canonicalize-device-spec): Extend to support NFSdirectly, and...* gnu/build/linux-boot.scm (boot-system): ...remove NFS special casing fromhere. Remove nested definitions for root-fs-type, root-fs-flags androot-fs-options, and bind those inside the let* instead. Make "--root" takeprecedence over the device field string representation of the root filesystem.* doc/guix.texi (Initial RAM Disk): Document that "--root" can be leftunspecified.--- doc/guix.texi | 7 +++-- gnu/build/file-systems.scm | 6 ++-- gnu/build/linux-boot.scm | 63 +++++++++++++++++--------------------- 3 files changed, 36 insertions(+), 40 deletions(-)
Toggle diff (125 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 22bf6bd224..3d8ea4b6c4 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -26530,9 +26530,10 @@ service activation programs and then spawns the GNU@tie{}Shepherd, the initialization system. @item --root=@var{root}-Mount @var{root} as the root file system. @var{root} can be a-device name like @code{/dev/sda1}, a file system label, or a file system-UUID.+Mount @var{root} as the root file system. @var{root} can be a device+name like @code{/dev/sda1}, a file system label, or a file system UUID.+When unspecified, the device name from the root file system of the+operating system declaration is used. @item --system=@var{system} Have @file{/run/booted-system} and @file{/run/current-system} point todiff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scmindex b920e8fc62..ad92d8a496 100644--- a/gnu/build/file-systems.scm+++ b/gnu/build/file-systems.scm@@ -661,8 +661,10 @@ were found." (match spec ((? string?)- ;; Nothing to do, but wait until SPEC shows up.- (resolve identity spec identity))+ (if (string-contains spec ":/")+ spec ; do not resolve NFS devices+ ;; Nothing to do, but wait until SPEC shows up.+ (resolve identity spec identity))) ((? file-system-label?) ;; Resolve the label. (resolve find-partition-by-labeldiff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scmindex c6f9df5f29..f08bb11514 100644--- a/gnu/build/linux-boot.scm+++ b/gnu/build/linux-boot.scm@@ -498,25 +498,13 @@ upon error." (define (root-mount-point? fs) (string=? (file-system-mount-point fs) "/")) - (define root-fs-type- (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-type fs)))- mounts)- "ext4"))-- (define root-fs-flags- (mount-flags->bit-mask (or (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-flags fs)))- mounts)- '())))-- (define root-fs-options- (any (lambda (fs)- (and (root-mount-point? fs)- (file-system-options fs)))- mounts))+ (define (device-string->file-system-device device-string)+ ;; The "--root=SPEC" kernel command-line option always provides a+ ;; string, but the string can represent a device, a UUID, or a+ ;; label. So check for all three.+ (cond ((string-prefix? "/" device-string) device-string)+ ((uuid device-string) => identity)+ (else (file-system-label device-string)))) (display "Welcome, this is GNU's early boot Guile.\n") (display "Use '--repl' for an initrd REPL.\n\n")@@ -526,7 +514,21 @@ upon error." (mount-essential-file-systems) (let* ((args (linux-command-line)) (to-load (find-long-option "--load" args))- (root (find-long-option "--root" args)))+ (root-fs (find root-mount-point? mounts))+ (root-fs-type (or (and=> root-fs file-system-type)+ "ext4"))+ (root-fs-device (and=> root-fs file-system-device))+ (root-fs-flags (mount-flags->bit-mask+ (or (and=> root-fs file-system-flags)+ '())))+ (root-options (if root-fs+ (file-system-options root-fs)+ #f))+ ;; --root takes precedence over the 'device' field of the root+ ;; <file-system> record.+ (root-device (or (and=> (find-long-option "--root" args)+ device-string->file-system-device)+ root-fs-device))) (when (member "--repl" args) (start-repl))@@ -561,21 +563,12 @@ upon error." (setenv "EXT2FS_NO_MTAB_OK" "1") - (if root- ;; The "--root=SPEC" kernel command-line option always provides a- ;; string, but the string can represent a device, a UUID, or a- ;; label. So check for all three.- (let ((device-spec (cond ((string-prefix? "/" root) root)- ((uuid root) => identity)- ((string-contains root ":/") #f) ; nfs- (else (file-system-label root)))))- (mount-root-file-system (if device-spec- (canonicalize-device-spec device-spec)- root)- root-fs-type- #:volatile-root? volatile-root?- #:flags root-fs-flags- #:options root-fs-options))+ (if root-device+ (mount-root-file-system (canonicalize-device-spec root-device)+ root-fs-type+ #:volatile-root? volatile-root?+ #:flags root-fs-flags+ #:options root-options) (mount "none" "/root" "tmpfs")) ;; Mount the specified file systems.-- 2.26.2
From 70737eac4ee6efebdb9c173e8ffe9ec710b9bc34 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 25 Sep 2019 22:43:41 +0900Subject: [PATCH 3/4] file-systems: Add helpers for parsing the options string into an alist.
* gnu/system/file-systems.scm (file-system-options->alist)(alist->file-system-options): New procedures.* tests/file-systems.scm: New tests.* doc/guix.texi (File Systems): Add note about the newly added procedures.--- doc/guix.texi | 12 ++++++++---- gnu/system/file-systems.scm | 31 +++++++++++++++++++++++++++++++ tests/file-systems.scm | 19 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-)
Toggle diff (115 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 3d8ea4b6c4..6989a21bf9 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11690,10 +11690,14 @@ update time on the in-memory version of the file inode), and Manual}, for more information on these flags. @item @code{options} (default: @code{#f})-This is either @code{#f}, or a string denoting mount options passed to the-file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C Library-Reference Manual}, for details and run @command{man 8 mount} for options for-various file systems.+This is either @code{#f}, or a string denoting mount options passed to+the file system driver. @xref{Mount-Unmount-Remount,,, libc, The GNU C+Library Reference Manual}, for details and run @command{man 8 mount} for+options for various file systems. Note that the+@code{file-system-options->alist} and @code{alist->file-system-options}+procedures from @code{(gnu system file-systems)} can be used to convert+file system options given as an association list to the string+representation, and vice-versa. @item @code{mount?} (default: @code{#t}) This value indicates whether to automatically mount the file system whendiff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex b41f66e943..07f272db7c 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -38,6 +39,9 @@ file-system-needed-for-boot? file-system-flags file-system-options+ file-system-options->alist+ alist->file-system-options+ file-system-mount? file-system-check? file-system-create-mount-point?@@ -251,6 +255,33 @@ UUID-TYPE, a symbol such as 'dce or 'iso9660." ((? string?) device))) +(define (file-system-options->alist string)+ "Translate the option string format of a <file-system> record into an+association list of options or option/value pairs."+ (if string+ (let ((options (string-split string #\,)))+ (map (lambda (param)+ (let ((=index (string-index param #\=)))+ (if =index+ (cons (string-take param =index)+ (string-drop param (1+ =index)))+ param)))+ options))+ '()))++(define (alist->file-system-options options)+ "Return the string representation of OPTIONS, an association list. The+string obtained can be used as the option field of a <file-system> record."+ (if (null? options)+ #f+ (string-join (map (match-lambda+ ((key . value)+ (string-append key "=" value))+ (key+ key))+ options)+ ",")))+ (define (file-system-needed-for-boot? fs) "Return true if FS has the 'needed-for-boot?' flag set, or if it holds the store--e.g., if FS is the root file system."diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 4c28d0ebc5..41f1021067 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -1,5 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2015, 2017 Ludovic Courtès <ludo@gnu.org>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -64,4 +65,22 @@ (_ #f)) (source-module-closure '((gnu system file-systems))))) +(test-equal "file-system-options->alist"+ '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))+ (file-system-options->alist "autodefrag,subvol=home,compress=lzo"))++(test-equal "file-system-options->alist (#f)"+ '()+ (file-system-options->alist #f))++(test-equal "alist->file-system-options"+ "autodefrag,subvol=root,compress=lzo"+ (alist->file-system-options '("autodefrag"+ ("subvol" . "root")+ ("compress" . "lzo"))))++(test-equal "alist->file-system-options (null)"+ #f+ (alist->file-system-options '()))+ (test-end)-- 2.26.2
From 082934db68964890ebd2a2118fb44d66911844d3 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Sun, 14 Jul 2019 20:50:23 +0900Subject: [PATCH 4/4] bootloader: grub: Allow booting from a Btrfs subvolume.
* gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.(normalize-file): Add procedure.(grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. Whendefined, prepend its value to the kernel and initrd file names, using theNORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass theBTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.(eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along withthe NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nestedvariables. Adjust doc.* gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.* gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.* gnu/system/file-systems.scm (btrfs-subvolume?)(btrfs-store-subvolume-file-name): New procedures.* gnu/system.scm (operating-system-bootcfg): Specify the Btrfssubvolume file name the store resides on to the`operating-system-bootcfg' procedure, using the newBTRFS-SUBVOLUME-FILE-NAME argument.* doc/guix.texi (File Systems): Add a Btrfs subsection to document the use ofsubvolumes.* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".--- doc/guix.texi | 104 ++++++++++++++++++++++++++++ gnu/bootloader/depthcharge.scm | 3 +- gnu/bootloader/extlinux.scm | 3 +- gnu/bootloader/grub.scm | 122 ++++++++++++++++++++------------- gnu/system.scm | 9 ++- gnu/system/file-systems.scm | 58 ++++++++++++++++ gnu/tests/install.scm | 94 +++++++++++++++++++++++++ tests/file-systems.scm | 45 ++++++++++++ 8 files changed, 388 insertions(+), 50 deletions(-)
Toggle diff (617 lines)diff --git a/doc/guix.texi b/doc/guix.texiindex 6989a21bf9..94f56559a9 100644--- a/doc/guix.texi+++ b/doc/guix.texi@@ -11778,6 +11778,110 @@ and unmount user-space FUSE file systems. This requires the @code{fuse.ko} kernel module to be loaded. @end defvr +@node Btrfs file system+@subsection Btrfs file system++The Btrfs has special features, such as subvolumes, that merit being+explained in more details. The following section attempts to cover+basic as well as complex uses of a Btrfs file system with the Guix+System.++In its simplest usage, a Btrfs file system can be described, for+example, by:++@lisp+(file-system+ (mount-point "/home")+ (type "btrfs")+ (device (file-system-label "my-home")))+@end lisp++The example below is more complex, as it makes use of a Btrfs+subvolume, named @code{rootfs}. The parent Btrfs file system is labeled+@code{my-btrfs-pool}, and is located on an encrypted device (hence the+dependency on @code{mapped-devices}):++@lisp+(file-system+ (device (file-system-label "my-btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options "subvol=rootfs")+ (dependencies mapped-devices))+@end lisp++Some bootloaders, for example GRUB, only mount a Btrfs partition at its+top level during the early boot, and rely on their configuration to+refer to the correct subvolume path within that top level. The+bootloaders operating in this way typically produce their configuration+on a running system where the Btrfs partitions are already mounted and+where the subvolume information is readily available. As an example,+@command{grub-mkconfig}, the configuration generator command shipped+with GRUB, reads @file{/proc/self/mountinfo} to determine the top-level+path of a subvolume.++The Guix System produces a bootloader configuration using the operating+system configuration as its sole input; it is therefore necessary to+extract the subvolume name on which @file{/gnu/store} lives (if any)+from that operating system configuration. To better illustrate,+consider a subvolume named 'rootfs' which contains the root file system+data. In such situation, the GRUB bootloader would only see the top+level of the root Btrfs partition, e.g.:++@example+/ (top level)+├── rootfs (subvolume directory)+ ├── gnu (normal directory)+ ├── store (normal directory)+[...]+@end example++Thus, the subvolume name must be prepended to the @file{/gnu/store} path+of the kernel, initrd binaries and any other files referred to in the+GRUB configuration that must be found during the early boot.++The next example shows a nested hierarchy of subvolumes and+directories:++@example+/ (top level)+├── rootfs (subvolume)+ ├── gnu (normal directory)+ ├── store (subvolume)+[...]+@end example++This scenario would work without mounting the 'store' subvolume.+Mounting 'rootfs' is sufficient, since the subvolume name matches its+intended mount point in the file system hierarchy. Alternatively, the+'store' subvolume could be referred to by setting the @code{subvol}+option to either @code{/rootfs/gnu/store} or @code{rootfs/gnu/store}.++Finally, a more contrived example of nested subvolumes:++@example+/ (top level)+├── root-snapshots (subvolume)+ ├── root-current (subvolume)+ ├── guix-store (subvolume)+[...]+@end example++Here, the 'guix-store' subvolume doesn't match its intended mount point,+so it is necessary to mount it. The subvolume must be fully specified,+by passing its file name to the @code{subvol} option. To illustrate,+the 'guix-store' subvolume could be mounted on @file{/gnu/store} by using+a file system declaration such as:++@lisp+(file-system+ (device (file-system-label "btrfs-pool-1"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvol=root-snapshots/root-current/guix-store,\+compress-force=zstd"))+@end lisp+ @node Mapped Devices @section Mapped Devices diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scmindex 58cc3f3932..0a50374bd9 100644--- a/gnu/bootloader/depthcharge.scm+++ b/gnu/bootloader/depthcharge.scm@@ -82,7 +82,8 @@ (define* (depthcharge-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) (match entries ((entry) (let ((kernel (menu-entry-linux entry))diff --git a/gnu/bootloader/extlinux.scm b/gnu/bootloader/extlinux.scmindex 5b4dd84965..6b5ff298e7 100644--- a/gnu/bootloader/extlinux.scm+++ b/gnu/bootloader/extlinux.scm@@ -28,7 +28,8 @@ (define* (extlinux-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ #:allow-other-keys) "Return the U-Boot configuration file corresponding to CONFIG, a <u-boot-configuration> object, and where the store is available at STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu entriesdiff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex 8c5b5eac0c..e0218caba5 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -64,18 +64,29 @@ ;;; ;;; Code: -(define (strip-mount-point mount-point file)- "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable object-denoting a file name."- (match mount-point- ((? string? mount-point)- (if (string=? mount-point "/")- file- #~(let ((file #$file))- (if (string-prefix? #$mount-point file)- (substring #$file #$(string-length mount-point))- file))))- (#f file)))+(define* (normalize-file file mount-point btrfs-subvolume-file-name)+ "Strip MOUNT-POINT and prepend BTRFS-SUBVOLUME-FILE-NAME to FILE, a+G-expression or other lowerable object denoting a file name."++ (define (strip-mount-point mount-point file)+ (if mount-point+ (if (string=? mount-point "/")+ file+ #~(let ((file #$file))+ (if (string-prefix? #$mount-point file)+ (substring #$file #$(string-length mount-point))+ file)))+ file))++ (define (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name file)+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name #$file)+ file))++ (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name+ (strip-mount-point mount-point file)))++ (define-record-type* <grub-image> grub-image make-grub-image@@ -143,13 +154,15 @@ WIDTH/HEIGHT, or #f if none was found." #:width width #:height height)))) (define* (eye-candy config store-device store-mount-point+ btrfs-store-subvolume-file-name #:key system port)- "Return a gexp that writes to PORT (a port-valued gexp) the-'grub.cfg' part concerned with graphics mode, background images, colors, and-all that. STORE-DEVICE designates the device holding the store, and-STORE-MOUNT-POINT is its mount point; these are used to determine where the-background image and fonts must be searched for. SYSTEM must be the target-system string---e.g., \"x86_64-linux\"."+ "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part+concerned with graphics mode, background images, colors, and all that.+STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POINT is+its mount point; these are used to determine where the background image and+fonts must be searched for. SYSTEM must be the target system string---e.g.,+\"x86_64-linux\". BTRFS-STORE-SUBVOLUME-FILE-NAME is the file name of the+Btrfs subvolume, to be prepended to any store path, if any." (define setup-gfxterm-body (let ((gfxmode (or (and-let* ((theme (bootloader-configuration-theme config))@@ -186,11 +199,14 @@ fi~%" #+font-file) (symbol->string (assoc-ref colors 'bg))))) (define font-file- (strip-mount-point store-mount-point- (file-append grub "/share/grub/unicode.pf2")))+ (normalize-file (file-append grub "/share/grub/unicode.pf2")+ store-mount-point+ btrfs-store-subvolume-file-name)) (define image- (grub-background-image config))+ (normalize-file (grub-background-image config)+ store-mount-point+ btrfs-store-subvolume-file-name)) (and image #~(format #$port "@@ -215,7 +231,7 @@ fi~%" #$(setup-gfxterm config font-file) #$(grub-setup-io config) - #$(strip-mount-point store-mount-point image)+ #$image #$(theme-colors grub-theme-color-normal) #$(theme-colors grub-theme-color-highlight)))) @@ -323,52 +339,66 @@ code." (define* (grub-configuration-file config entries #:key (system (%current-system))- (old-entries '()))+ (old-entries '())+ btrfs-subvolume-file-name) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at-STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu-entries corresponding to old generations of the system."+STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list+of menu entries corresponding to old generations of the system.+BTRFS-SUBVOLUME-FILE-NAME may be used to specify on which subvolume a+Btrfs root file system resides." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)- (let ((device (menu-entry-device entry))- (device-mount-point (menu-entry-device-mount-point entry))- (label (menu-entry-label entry))- (kernel (menu-entry-linux entry))- (arguments (menu-entry-linux-arguments entry))- (initrd (menu-entry-initrd entry)))+ (let* ((device (menu-entry-device entry))+ (device-mount-point (menu-entry-device-mount-point entry))+ (label (menu-entry-label entry))+ (arguments (menu-entry-linux-arguments entry))+ (kernel (normalize-file (menu-entry-linux entry)+ device-mount-point+ btrfs-subvolume-file-name))+ (initrd (normalize-file (menu-entry-initrd entry)+ device-mount-point+ btrfs-subvolume-file-name))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition.- (let ((kernel (strip-mount-point device-mount-point kernel))- (initrd (strip-mount-point device-mount-point initrd)))- #~(format port "menuentry ~s {++ ;; When BTRFS-SUBVOLUME-FILE-NAME is defined, prepend it the kernel and+ ;; initrd paths, to allow booting from a Btrfs subvolume.+ #~(format port "menuentry ~s { ~a linux ~a ~a initrd ~a }~%"- #$label- #$(grub-root-search device kernel)- #$kernel (string-join (list #$@arguments))- #$initrd))))+ #$label+ #$(grub-root-search device kernel)+ #$kernel (string-join (list #$@arguments))+ #$initrd))) (define sugar (eye-candy config (menu-entry-device (first all-entries)) (menu-entry-device-mount-point (first all-entries))+ btrfs-subvolume-file-name #:system system #:port #~port)) (define keyboard-layout-config- (let ((layout (bootloader-configuration-keyboard-layout config))- (grub (bootloader-package- (bootloader-configuration-bootloader config))))- #~(let ((keymap #$(and layout- (keyboard-layout-file layout #:grub grub))))- (when keymap- (format port "\+ (let* ((layout (bootloader-configuration-keyboard-layout config))+ (grub (bootloader-package+ (bootloader-configuration-bootloader config)))+ (keymap* (and layout+ (keyboard-layout-file layout #:grub grub)))+ (keymap (and keymap*+ (if btrfs-subvolume-file-name+ #~(string-append #$btrfs-subvolume-file-name+ #$keymap*)+ keymap*))))+ #~(when #$keymap+ (format port "\ insmod keylayouts-keymap ~a~%" keymap)))))+keymap ~a~%" #$keymap)))) (define builder #~(call-with-output-file #$outputdiff --git a/gnu/system.scm b/gnu/system.scmindex cd75e4d4ba..d929187695 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -8,6 +8,7 @@ ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org> ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re> ;;; Copyright © 2020 Florian Pelz <pelzflorian@pelzflorian.de>+;;; Copyright © 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; ;;; This file is part of GNU Guix. ;;;@@ -1102,19 +1103,23 @@ entry." (define* (operating-system-bootcfg os #:optional (old-entries '())) "Return the bootloader configuration file for OS. Use OLD-ENTRIES, a list of <menu-entry>, to populate the \"old entries\" menu."- (let* ((root-fs (operating-system-root-file-system os))+ (let* ((file-systems (operating-system-file-systems os))+ (root-fs (operating-system-root-file-system os)) (root-device (file-system-device root-fs)) (params (operating-system-boot-parameters os root-device #:system-kernel-arguments? #t)) (entry (boot-parameters->menu-entry params)) (bootloader-conf (operating-system-bootloader os)))+ (define generate-config-file (bootloader-configuration-file-generator (bootloader-configuration-bootloader bootloader-conf))) (generate-config-file bootloader-conf (list entry)- #:old-entries old-entries)))+ #:old-entries old-entries+ #:btrfs-subvolume-file-name+ (btrfs-store-subvolume-file-name file-systems)))) (define* (operating-system-boot-parameters os root-device #:key system-kernel-arguments?)diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scmindex 07f272db7c..1f0c0cea4b 100644--- a/gnu/system/file-systems.scm+++ b/gnu/system/file-systems.scm@@ -22,7 +22,10 @@ #:use-module (ice-9 match) #:use-module (rnrs bytevectors) #:use-module (srfi srfi-1)+ #:use-module (srfi srfi-2) #:use-module (srfi srfi-9)+ #:use-module (srfi srfi-26)+ #:use-module (srfi srfi-35) #:use-module (srfi srfi-9 gnu) #:use-module (guix records) #:use-module (gnu system uuid)@@ -49,6 +52,8 @@ file-system-location file-system-type-predicate+ btrfs-subvolume?+ btrfs-store-subvolume-file-name file-system-label file-system-label?@@ -566,4 +571,57 @@ system has the given TYPE." (lambda (fs) (string=? (file-system-type fs) type))) + +;;;+;;; Btrfs specific helpers.+;;;++(define (btrfs-subvolume? fs)+ "Predicate to check if FS, a file-system object, is a Btrfs subvolume."+ (and-let* ((btrfs-file-system? (string= "btrfs" (file-system-type fs)))+ (option-keys (map (match-lambda+ ((key . value) key)+ (key key))+ (file-system-options->alist+ (file-system-options fs)))))+ (find (cut string-prefix? "subvol" <>) option-keys)))++(define (btrfs-store-subvolume-file-name file-systems)+ "Return the subvolume file name within the Btrfs top level onto which the+store is located, else #f."++ (define (prepend-slash/maybe s)+ (if (string=? "/" (string-take s 1))+ s+ (string-append "/" s)))++ (define (file-name-depth file-name)+ (length (string-tokenize file-name %not-slash)))++ (and-let* ((btrfs-subvolume-fs (filter btrfs-subvolume? file-systems))+ (btrfs-subvolume-fs*+ (sort btrfs-subvolume-fs+ (lambda (fs1 fs2)+ (> (file-name-depth (file-system-mount-point fs1))+ (file-name-depth (file-system-mount-point fs2))))))+ (store-subvolume-fs+ (find (lambda (fs) (file-prefix? (file-system-mount-point fs)+ (%store-prefix)))+ btrfs-subvolume-fs*))+ (options (file-system-options->alist+ (file-system-options store-subvolume-fs))))+ ;; XXX: Deriving the subvolume name based from a subvolume ID is not+ ;; supported, as we'd need to query the actual file system.+ (or (and=> (assoc-ref options "subvol") prepend-slash/maybe)+ ;; XXX: Importing (guix utils) and using &fix-hint causes the+ ;; following error when booting the init RAM disk: "ERROR: In+ ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol not+ ;; found: strverscmp", so we just embed the hint in the message.+ (raise (condition+ (&message+ (message "The store is on a Btrfs subvolume, but the \+subvolume name is unknown.+Hint: Use the \"subvol\" Btrfs file system option.")))))))++ ;;; file-systems.scm ends herediff --git a/gnu/tests/install.scm b/gnu/tests/install.scmindex 94d970e1cc..cea26c8ef3 100644--- a/gnu/tests/install.scm+++ b/gnu/tests/install.scm@@ -61,6 +61,7 @@ %test-raid-root-os %test-encrypted-root-os %test-btrfs-root-os+ %test-btrfs-root-on-subvolume-os %test-jfs-root-os %test-f2fs-root-os @@ -863,6 +864,99 @@ build (current-guix) and then store a couple of full system images.") (command (qemu-command/writable-image image))) (run-basic-test %btrfs-root-os command "btrfs-root-os"))))) + +;;;+;;; Btrfs root file system on a subvolume.+;;;++(define-os-with-source (%btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source)+ ;; The OS we want to install.+ (use-modules (gnu) (gnu tests) (srfi srfi-1))++ (operating-system+ (host-name "hurd")+ (timezone "America/Montreal")+ (locale "en_US.UTF-8")+ (bootloader (bootloader-configuration+ (bootloader grub-bootloader)+ (target "/dev/vdb")))+ (kernel-arguments '("console=ttyS0"))+ (file-systems (cons* (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (options "subvol=rootfs,compress=zstd")+ (type "btrfs"))+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/home")+ (options "subvol=homefs,compress=lzo")+ (type "btrfs"))+ %base-file-systems))+ (users (cons (user-account+ (name "charlie")+ (group "users")+ (supplementary-groups '("wheel" "audio" "video")))+ %base-user-accounts))+ (services (cons (service marionette-service-type+ (marionette-configuration+ (imported-modules '((gnu services herd)+ (guix combinators)))))+ %base-services))))++(define %btrfs-root-on-subvolume-installation-script+ ;; Shell script of a simple installation.+ "\+. /etc/profile+set -e -x+guix --version++export GUIX_BUILD_OPTIONS=--no-grafts+ls -l /run/current-system/gc-roots+parted --script /dev/vdb mklabel gpt \\+ mkpart primary ext2 1M 3M \\+ mkpart primary ext2 3M 2G \\+ set 1 boot on \\+ set 1 bios_grub on++# Setup the top level Btrfs file system with its subvolume.+mkfs.btrfs -L btrfs-pool /dev/vdb2+mount /dev/vdb2 /mnt+btrfs subvolume create /mnt/rootfs+btrfs subvolume create /mnt/homefs+umount /dev/vdb2++# Mount the subvolumes, ready for installation.+mount LABEL=btrfs-pool -o 'subvol=rootfs,compress=zstd' /mnt+mkdir /mnt/home+mount LABEL=btrfs-pool -o 'subvol=homefs,compress=zstd' /mnt/home++herd start cow-store /mnt+mkdir /mnt/etc+cp /etc/target-config.scm /mnt/etc/config.scm+guix system build /mnt/etc/config.scm+guix system init /mnt/etc/config.scm /mnt --no-substitutes+sync+reboot\n")++(define %test-btrfs-root-on-subvolume-os+ (system-test+ (name "btrfs-root-on-subvolume-os")+ (description+ "Test basic functionality of an OS installed like one would do by hand.+This test is expensive in terms of CPU and storage usage since we need to+build (current-guix) and then store a couple of full system images.")+ (value+ (mlet* %store-monad+ ((image+ (run-install %btrfs-root-on-subvolume-os+ %btrfs-root-on-subvolume-os-source+ #:script+ %btrfs-root-on-subvolume-installation-script))+ (command (qemu-command/writable-image image)))+ (run-basic-test %btrfs-root-on-subvolume-os command+ "btrfs-root-on-subvolume-os")))))+ ;;; ;;; JFS root file system.diff --git a/tests/file-systems.scm b/tests/file-systems.scmindex 41f1021067..7f7c373884 100644--- a/tests/file-systems.scm+++ b/tests/file-systems.scm@@ -83,4 +83,49 @@ #f (alist->file-system-options '())) + +;;;+;;; Btrfs related.+;;;++(define %btrfs-root-subvolume+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/")+ (type "btrfs")+ (options "subvol=rootfs,compress=zstd")))++(define %btrfs-store-subvolid+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvolid=10,compress=zstd")+ (dependencies (list %btrfs-root-subvolume))))++(define %btrfs-store-subvolume+ (file-system+ (device (file-system-label "btrfs-pool"))+ (mount-point "/gnu/store")+ (type "btrfs")+ (options "subvol=/some/nested/file/name")+ (dependencies (list %btrfs-root-subvolume))))++(test-assert "btrfs-subvolume? (subvol)"+ (btrfs-subvolume? %btrfs-root-subvolume))++(test-assert "btrfs-subvolume? (subvolid)"+ (btrfs-subvolume? %btrfs-store-subvolid))++(test-equal "btrfs-store-subvolume-file-name"+ "/some/nested/file/name"+ (parameterize ((%store-prefix "/gnu/store"))+ (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume+ %btrfs-store-subvolume))))++(test-error "btrfs-store-subvolume-file-name (subvolid)"+ (parameterize ((%store-prefix "/gnu/store"))+ (btrfs-store-subvolume-file-name (list %btrfs-root-subvolume+ %btrfs-store-subvolid))))+ (test-end)-- 2.26.2
I'll test those rebased patches as well. The automated system tests nolonger pass -- although it might not be specific to this change (I'lltry running the "installed-os" test to see if all the install tests arebroken or just this new "btrfs-root-on-subvolume-os" one.). In case youare not familiar with system tests, a single system test can be runwith:
make check-system TESTS="btrfs-root-on-subvolume-os"
The install tests are defined under (gnu tests install) and are *very*expensive to run (mostly in time, but they require some disk space aswell). Hence the hack in 0001, but I'm not sure if it brings as muchbenefits as when I made it (given Ludovic keeps improving the way Guixgets built :-)).
A fresh benchmark could be interesting if you have lots of time on yourhands.
Thank you for looking at this!
Maxim
M
M
Maxim Cournoyer wrote on 17 May 2020 18:16
Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87zha6a660.fsf@gmail.com
Hello Pierre!
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (16 lines)> Hi Maxim!>> maxim.cournoyer@gmail.com writes:>>> +@lisp>> +(file-system>> + (device (file-system-label "btrfs-pool-1"))>> + (mount-point "/gnu/store")>> + (type "btrfs")>> + (options "subvol=root-snapshots/root-current/guix-store">> + ("compress" . "zstd")))>> +@end lisp>>> Is this ("compress" . "zstd") intentional? It does not match the first example.
Good catch! This pair syntax was removed, based on feedback fromprevious reviews. It can still be used with the helper procedures, butnot directly like that. It should be fixed in the patch series I justsent in the previous email.
Thank you,
Maxim
P
P
Pierre Neidhardt wrote on 17 May 2020 18:37
Re: [PATCH v3] Allow booting from a Btrfs subvolume
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
878shqh61b.fsf@ambrevar.xyz
Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:
Toggle quote (9 lines)> I'll test those rebased patches as well. The automated system tests no> longer pass -- although it might not be specific to this change (I'll> try running the "installed-os" test to see if all the install tests are> broken or just this new "btrfs-root-on-subvolume-os" one.). In case you> are not familiar with system tests, a single system test can be run> with:>> make check-system TESTS="btrfs-root-on-subvolume-os"
OK. Do you want me to try something here?
Toggle quote (9 lines)> The install tests are defined under (gnu tests install) and are *very*> expensive to run (mostly in time, but they require some disk space as> well). Hence the hack in 0001, but I'm not sure if it brings as much> benefits as when I made it (given Ludovic keeps improving the way Guix> gets built :-)).>> A fresh benchmark could be interesting if you have lots of time on your> hands.
Sorry, I don't think I'll be able to do that :)
Cheers!
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7BaDAACgkQm9z0l6S7zH8lgggAhSLKsuANE2xk3GPeHZC/u/FMM2ykeG9bTaNn+0BpFqyyl8OODAzk/b6ocXF8TudOb1ODuL4ma88fU37G8PDI5KsUpVQGpBs+I9cOfJ4Q9CHW5ho3aa8WsdF8jCTt7JoPjElhKTMg8Kz2m+ZqTYOOhW6laOwf/95cKqqXjwcj21vsIZGju/uDMNjmqlymtNCkq/1tFrtkgc+/idROGGIxJsz2/lwNZcuavZPVX9POCmsF8dfjRFyd5pF91gx6oKmsbTbUmIBgdcLTAaXFLOT6GEAkmKR1w2YA3M3BnGFjIR+lyAWeJ2WJ71Oi9d1RxF1XifESEnyN4Cn0oFDlYgmCXg===A8+G-----END PGP SIGNATURE-----
P
P
Pierre Neidhardt wrote on 17 May 2020 21:05
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87367ygz5c.fsf@ambrevar.xyz
Finally "system reconfigure"d with your patch.
The first entry fails to boot with:
Toggle snippet (6 lines)loading kernel modules...ice-9/boot-9.scm:1669:16: In procedure raise-exception:In procedure string-prefix?: Wrong type argument in position 2(expecting string): #<file-system-label "guix">
Funny thing is, the previous generation boots properly!
My config.scm's filesystem layout:
Toggle snippet (17 lines)(file-systems (cons* (file-system (device (file-system-label "guix")) (mount-point "/") (type "btrfs") (options "subvol=rootfs,compress=zstd")) (file-system (device (file-system-label "data")) (mount-point "/media/data") (type "ext4")) (file-system (mount-point "/tmp") (device "none") (type "tmpfs") (check? #f)) %base-file-systems))
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7Biw8ACgkQm9z0l6S7zH+4aAf+MInE16kpivdxlcQJjy4xebngj+LUHs/UV5W5FU8MzzeI2koE+S8MAus8Y5QtDHrNI7h4rRNsBIHn0LgJ/KUFt+JKjHWVPEnb1Ey2uAL/hPYj2IVI7cAVh7lMkcnACYwDO8SUwmTJJv22Q91fjumh3tUCaGFa7pbMA6NsdU5lFGV9GRV5ejOM+Mh9YCgSJ1HVif6amt/SF5k8CSB9VAqarSgZtUpx+IKHj+PkbpsJFOxzE34nF5DChZd1oRYZRpJN/7JHwyd3qIkLPbNbFOZw4Usv/nl57+AIlSiFnTcqL8xPUB0NHZndZKxVYG6ePiCP3X3ErUiE3e3KqEEiwZ9VYA===rlSu-----END PGP SIGNATURE-----
P
P
Pierre Neidhardt wrote on 17 May 2020 21:09
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87y2pqfkfa.fsf@ambrevar.xyz
The first (failing) generation was generated from today (or yesterday) Guixmaster.
The second (working) generation was generated from a 2 month old Guix.Let me know if you want the precise commits.
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7Bi9kACgkQm9z0l6S7zH+A3ggAm2nRb9WaJG75QGuYmY2fCTVoshoDmEcNGOubI25WA0hwKph7CRg497tMpV4nFLyAXcUAd4e/Vy8vdtvMtIUPfWVh7vPYYtOnEPZvZOiWiDxYEaSUgLBG0BkYoyhT08krwN2AYnPhIiiB5ESHunwc9gyTrkXD29Q4dWGGyhzakmIjIA7YbYUb+q2HzOVD0z6o53/B+y28mbnTScWlCi94A19GbOv5Z+00L67I7m3b/GGjm9XdfA2Mhl1lIBZu0qAgyBW+Ym5nuDuZdfA6rJchcaxnZSf6fDaT0Qdgx0A74UMOGe5PVL2HYsSvHPWkK6CgClOkpt8WXvCd3BTPiHqQig===j+T/-----END PGP SIGNATURE-----
P
P
Pierre Neidhardt wrote on 17 May 2020 21:48
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87v9kufim7.fsf@ambrevar.xyz
False alarm, I had mis-merged your (old) patch.After applying your patch from today, everything works.
I won't have access to this computer in 24 hours. Let me know if thereis anything else you'd like me to test before then! :)
Cheers!
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7BlQAACgkQm9z0l6S7zH9THgf8DdIDSOZYT5aIsD6/65Tkx1tH8SOEYnSjYzRPWgfJcAoOGZk1KP1LtnYwc8iwzFmk/RFrs1a6MMRxIuHFgVdRDhCAQzEwUmhDv37Uus6VA+v1b8dC4Ec0nXIySQq7EKyzOUdzGLP3mBV8oPk7VHXkboHKX9H6B9OK8LcIeCTryLcXdtvHimeTbNH57Tw8a82BdDB/9TiC+G77c3+9y4N8j79Svd6ns/dMh4KhJ6vbRe1I22EjHwmMaSic0Yz9jnqGPWSK9EO2l6trhaEMPMFWP+t2tUxHaaxE33b1d4ICq8956jG51o0Cxqtournrwe/s2ttokItBEMEns8cRcGl3PQ===c6WQ-----END PGP SIGNATURE-----
P
P
Pierre Neidhardt wrote on 17 May 2020 22:22
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87sgfyfh1m.fsf@ambrevar.xyz
About the patch: maybe some of it could be generalized to otherfilesystems that support subvolumes (like ZFS). But this is probablypremature and it could be long before someone tests all this with ZFS,thus it's probably wiser to first merge this and generalize later.
By the way, can Guix with installed on a ZFS root?
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7BnPUACgkQm9z0l6S7zH/yngf/Tv5akTfeCS11ZHV9Mp6MsM6p3BzrnbJ5xtj1ciZpccrSVFLTw/7Qsdvk3w8MTUUBXaxCdx6oNPqpIx7gWJEJNTfK5w5yGl1HTx7sVDOdNsz1cKHC4x/9pOVc57Eg32gDqcMCGgNPzQBxqKVjXWc/YV6Jws+imo8eKDd/JQ7KN8+jUdI7ZMYfmMPOjcHoFU1Vmxk/51p8hT5Jf2WHseMTMEvKPh2rKzkAaPb1K1GDoSzkZ4i/+kE+9iLSY9FQUkkP+cHlJUHJReRfHydWeIN0Sz8FW395F6eVZCrFDhsGM9g4RMhoEDfsA5tLTXnlfIA8ItNM1cisibtRIllhzcKhFw===hChS-----END PGP SIGNATURE-----
M
M
Maxim Cournoyer wrote on 18 May 2020 02:49
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87v9ku9ie5.fsf@gmail.com
Hi Pierre,
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (7 lines)> About the patch: maybe some of it could be generalized to other> filesystems that support subvolumes (like ZFS). But this is probably> premature and it could be long before someone tests all this with ZFS,> thus it's probably wiser to first merge this and generalize later.
> By the way, can Guix with installed on a ZFS root?
I'm sorry, but I know nothing about ZFS, except that its license isincompatible with the GPL.
Maxim
M
M
Maxim Cournoyer wrote on 18 May 2020 03:16
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87r1vi9h5q.fsf@gmail.com
Hello Pierre!
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (3 lines)> False alarm, I had mis-merged your (old) patch.> After applying your patch from today, everything works.
Woohoo! Thank you for testing!
Toggle quote (3 lines)> I won't have access to this computer in 24 hours. Let me know if there> is anything else you'd like me to test before then! :)
Any comments above the implementation (code) or documentation? Wassomething unclear/missing?
If everything looks OK, I'll give this another 2 weeks period from nowto allow for more comments then merge the three non-controversial (i.e.,all except the hack to speed installation tests) to the master branch.
Thank you!
Maxim
P
P
Pierre Neidhardt wrote on 18 May 2020 10:54
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87k119fwrt.fsf@ambrevar.xyz
Hi Maxim!
Toggle quote (6 lines)>> I won't have access to this computer in 24 hours. Let me know if there>> is anything else you'd like me to test before then! :)>> Any comments above the implementation (code) or documentation? Was> something unclear/missing?
I had a cursory look. The code looks good to me as far as I can tell(which is little, considering my limited knowledge of the file systemcode).
The documentation examples are good. The paragraphs are a little bitharder to grasp for me, but I am not sure how to make it clearer;besides, the examples really help clarifying everything, so it's good enough.
Thanks!
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7CTVYACgkQm9z0l6S7zH+Idgf/b+HzE7WWaqkP+4D/vrYUNw4KGCA1VieeHSZDyR3pu6FHgUTufalVhE5sYWw6v/TDtVfY/T2/TIVqUmzbTsA81HUkV22PmF3+tN1eV4hBq957wyU7UFmOOLtguur7jB1VmnmR3vdZwHD2s6ExIYortwRKvPB/HYnZylbXVYP2zIlox8iiczA57b7vy+yb1V9MVzJphiHij2L6sgTsRLzPPPM2kwYFYkyBz85KblRSS+nVIteMPAV3P407UBbeq1HZLAR5aYgJrA0BpPbaUKUkTYP5xV3ap5WL0EjVlYDJAy3pciUxp4zBPU6EJa0lJeZ+jVGzW/POoopVqLkRpSooIw===fpn2-----END PGP SIGNATURE-----
L
L
Ludovic Courtès wrote on 18 May 2020 23:55
Re: [bug#37305] [PATCH v3] Allow booting from a Btrfs subvolume
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87y2pohpqx.fsf@gnu.org
Hi Maxim,
Sorry for dropping the ball for sooo long.
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (17 lines)>>From b03a574ad565b34bbe8a7d3d0322591850984dc6 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Tue, 11 Feb 2020 14:00:06 -0500> Subject: [PATCH 2/4] linux-boot: Refactor boot-system.>> The --root option can now be omitted, and inferred from the root file system> declaration instead.>> * gnu/build/file-systems.scm (canonicalize-device-spec): Extend to support NFS> directly, and...> * gnu/build/linux-boot.scm (boot-system): ...remove NFS special casing from> here. Remove nested definitions for root-fs-type, root-fs-flags and> root-fs-options, and bind those inside the let* instead. Make "--root" take> precedence over the device field string representation of the root file> system.> * doc/guix.texi (Initial RAM Disk): Document that "--root" can be left
[...]
Toggle quote (25 lines)> +++ b/gnu/build/linux-boot.scm> @@ -498,25 +498,13 @@ upon error."> (define (root-mount-point? fs)> (string=? (file-system-mount-point fs) "/"))> > - (define root-fs-type> - (or (any (lambda (fs)> - (and (root-mount-point? fs)> - (file-system-type fs)))> - mounts)> - "ext4"))> -> - (define root-fs-flags> - (mount-flags->bit-mask (or (any (lambda (fs)> - (and (root-mount-point? fs)> - (file-system-flags fs)))> - mounts)> - '())))> -> - (define root-fs-options> - (any (lambda (fs)> - (and (root-mount-point? fs)> - (file-system-options fs)))> - mounts))
[...]
Toggle quote (11 lines)> + (root-fs (find root-mount-point? mounts))> + (root-fs-type (or (and=> root-fs file-system-type)> + "ext4"))> + (root-fs-device (and=> root-fs file-system-device))> + (root-fs-flags (mount-flags->bit-mask> + (or (and=> root-fs file-system-flags)> + '())))> + (root-options (if root-fs> + (file-system-options root-fs)> + #f))
I would tend to keep these as defines to make the ‘let*’ lessintimidating, but it’s a detail.
Toggle quote (5 lines)> + ;; XXX: Importing (guix utils) and using &fix-hint causes the> + ;; following error when booting the init RAM disk: "ERROR: In> + ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol not> + ;; found: strverscmp", so we just embed the hint in the message.
I think it should just be “FIXME: Use &fix-hint once it no longer pullsin (guix utils).”
Toggle quote (26 lines)>>From 082934db68964890ebd2a2118fb44d66911844d3 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Sun, 14 Jul 2019 20:50:23 +0900> Subject: [PATCH 4/4] bootloader: grub: Allow booting from a Btrfs subvolume.>> * gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.> (normalize-file): Add procedure.> (grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. When> defined, prepend its value to the kernel and initrd file names, using the> NORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass the> BTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.> (eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along with> the NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nested> variables. Adjust doc.> * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.> * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.> * gnu/system/file-systems.scm (btrfs-subvolume?)> (btrfs-store-subvolume-file-name): New procedures.> * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs> subvolume file name the store resides on to the> `operating-system-bootcfg' procedure, using the new> BTRFS-SUBVOLUME-FILE-NAME argument.> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of> subvolumes.> * gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".
Please list the entities added to ‘install.scm’.
Toggle quote (4 lines)> (define* (eye-candy config store-device store-mount-point> + btrfs-store-subvolume-file-name> #:key system port)
I think ‘btrfs-store-subvolume-file-name’ should be a keyword argument.
Toggle quote (7 lines)> (define* (grub-configuration-file config entries> #:key> (system (%current-system))> - (old-entries '()))> + (old-entries '())> + btrfs-subvolume-file-name)
I wonder if we should just call it ‘store-directory-prefix’ or similarsince, after all, it’s just about prepending a prefix, which couldperhaps be useful for file systems other than Btrfs.
Thoughts?
Anyway, that’s great work, so I’ll be happy to finally see it committedin the coming days!
Ludo’.
M
M
Maxim Cournoyer wrote on 20 May 2020 14:44
(name . Ludovic Courtès)(address . ludo@gnu.org)
87wo56pyi5.fsf@gmail.com
Hi Ludovic!
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (4 lines)> Hi Maxim,>> Sorry for dropping the ball for sooo long.
No worries :-)
Toggle quote (2 lines)> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
[...]
Toggle quote (41 lines)>> +++ b/gnu/build/linux-boot.scm>> @@ -498,25 +498,13 @@ upon error.">> (define (root-mount-point? fs)>> (string=? (file-system-mount-point fs) "/"))>> >> - (define root-fs-type>> - (or (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-type fs)))>> - mounts)>> - "ext4"))>> ->> - (define root-fs-flags>> - (mount-flags->bit-mask (or (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-flags fs)))>> - mounts)>> - '())))>> ->> - (define root-fs-options>> - (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-options fs)))>> - mounts))>> [...]>>> + (root-fs (find root-mount-point? mounts))>> + (root-fs-type (or (and=> root-fs file-system-type)>> + "ext4"))>> + (root-fs-device (and=> root-fs file-system-device))>> + (root-fs-flags (mount-flags->bit-mask>> + (or (and=> root-fs file-system-flags)>> + '())))>> + (root-options (if root-fs>> + (file-system-options root-fs)>> + #f))>> I would tend to keep these as defines to make the ‘let*’ less> intimidating, but it’s a detail.
It would only *appear* less intimidating ;-). I personally prefer thelet* versions as the logic is more succinctly expressed (there is noneed for 'any' + lambdas, for example).
Toggle quote (8 lines)>> + ;; XXX: Importing (guix utils) and using &fix-hint causes the>> + ;; following error when booting the init RAM disk: "ERROR: In>> + ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol not>> + ;; found: strverscmp", so we just embed the hint in the message.>> I think it should just be “FIXME: Use &fix-hint once it no longer pulls> in (guix utils).”
Done!
Toggle quote (28 lines)>>>From 082934db68964890ebd2a2118fb44d66911844d3 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Sun, 14 Jul 2019 20:50:23 +0900>> Subject: [PATCH 4/4] bootloader: grub: Allow booting from a Btrfs subvolume.>>>> * gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.>> (normalize-file): Add procedure.>> (grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. When>> defined, prepend its value to the kernel and initrd file names, using the>> NORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass the>> BTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.>> (eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along with>> the NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nested>> variables. Adjust doc.>> * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.>> * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.>> * gnu/system/file-systems.scm (btrfs-subvolume?)>> (btrfs-store-subvolume-file-name): New procedures.>> * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs>> subvolume file name the store resides on to the>> `operating-system-bootcfg' procedure, using the new>> BTRFS-SUBVOLUME-FILE-NAME argument.>> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of>> subvolumes.>> * gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".>> Please list the entities added to ‘install.scm’.
Done!
Toggle quote (6 lines)>> (define* (eye-candy config store-device store-mount-point>> + btrfs-store-subvolume-file-name>> #:key system port)>> I think ‘btrfs-store-subvolume-file-name’ should be a keyword argument.
Done!
Toggle quote (13 lines)>> (define* (grub-configuration-file config entries>> #:key>> (system (%current-system))>> - (old-entries '()))>> + (old-entries '())>> + btrfs-subvolume-file-name)>> I wonder if we should just call it ‘store-directory-prefix’ or similar> since, after all, it’s just about prepending a prefix, which could> perhaps be useful for file systems other than Btrfs.>> Thoughts?
Perhaps, but given it's not yet clear whether another file system willrequire similar support from GRUB, I'd rather keep things as explicit aspossible for now.
Toggle quote (3 lines)> Anyway, that’s great work, so I’ll be happy to finally see it committed> in the coming days!
Thanks for the great words and for having a last look :-).
I've added a news entry and pushed to master as:
Toggle snippet (6 lines)489699c456 allow-booting-from-btrfs-subvolume news: Add entry for Btrfs subvolume boot support.b460ba7992 bootloader: grub: Allow booting from a Btrfs subvolume.fa35fb58c8 file-systems: Add helpers for parsing the options string into an alist.281d80d8e5 linux-boot: Refactor boot-system.
Closing! Thanks to Pierre and Ludovic for testing and reviewing.
Maxim
M
M
Maxim Cournoyer wrote on 20 May 2020 14:44
(name . Ludovic Courtès)(address . ludo@gnu.org)
87v9kqpyhu.fsf@gmail.com
Hi Ludovic!
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (4 lines)> Hi Maxim,>> Sorry for dropping the ball for sooo long.
No worries :-)
Toggle quote (2 lines)> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
[...]
Toggle quote (41 lines)>> +++ b/gnu/build/linux-boot.scm>> @@ -498,25 +498,13 @@ upon error.">> (define (root-mount-point? fs)>> (string=? (file-system-mount-point fs) "/"))>> >> - (define root-fs-type>> - (or (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-type fs)))>> - mounts)>> - "ext4"))>> ->> - (define root-fs-flags>> - (mount-flags->bit-mask (or (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-flags fs)))>> - mounts)>> - '())))>> ->> - (define root-fs-options>> - (any (lambda (fs)>> - (and (root-mount-point? fs)>> - (file-system-options fs)))>> - mounts))>> [...]>>> + (root-fs (find root-mount-point? mounts))>> + (root-fs-type (or (and=> root-fs file-system-type)>> + "ext4"))>> + (root-fs-device (and=> root-fs file-system-device))>> + (root-fs-flags (mount-flags->bit-mask>> + (or (and=> root-fs file-system-flags)>> + '())))>> + (root-options (if root-fs>> + (file-system-options root-fs)>> + #f))>> I would tend to keep these as defines to make the ‘let*’ less> intimidating, but it’s a detail.
It would only *appear* less intimidating ;-). I personally prefer thelet* versions as the logic is more succinctly expressed (there is noneed for 'any' + lambdas, for example).
Toggle quote (8 lines)>> + ;; XXX: Importing (guix utils) and using &fix-hint causes the>> + ;; following error when booting the init RAM disk: "ERROR: In>> + ;; procedure dynamic-func:\nIn procedure dynamic-pointer: Symbol not>> + ;; found: strverscmp", so we just embed the hint in the message.>> I think it should just be “FIXME: Use &fix-hint once it no longer pulls> in (guix utils).”
Done!
Toggle quote (28 lines)>>>From 082934db68964890ebd2a2118fb44d66911844d3 Mon Sep 17 00:00:00 2001>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>>> Date: Sun, 14 Jul 2019 20:50:23 +0900>> Subject: [PATCH 4/4] bootloader: grub: Allow booting from a Btrfs subvolume.>>>> * gnu/bootloader/grub.scm (strip-mount-point): Remove procedure.>> (normalize-file): Add procedure.>> (grub-configuration-file): New BTRFS-SUBVOLUME-FILE-NAME parameter. When>> defined, prepend its value to the kernel and initrd file names, using the>> NORMALIZE-FILE procedure. Adjust the call to EYE-CANDY to pass the>> BTRFS-SUBVOLUME-FILE-NAME argument. Normalize the KEYMAP file as well.>> (eye-candy): Add a BTRFS-SUBVOLUME-FILE-NAME parameter, and use it, along with>> the NORMALIZE-FILE procedure, to normalize the FONT-FILE and IMAGE nested>> variables. Adjust doc.>> * gnu/bootloader/depthcharge.scm (depthcharge-configuration-file): Adapt.>> * gnu/bootloader/extlinux.scm (extlinux-configuration-file): Likewise.>> * gnu/system/file-systems.scm (btrfs-subvolume?)>> (btrfs-store-subvolume-file-name): New procedures.>> * gnu/system.scm (operating-system-bootcfg): Specify the Btrfs>> subvolume file name the store resides on to the>> `operating-system-bootcfg' procedure, using the new>> BTRFS-SUBVOLUME-FILE-NAME argument.>> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the use of>> subvolumes.>> * gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".>> Please list the entities added to ‘install.scm’.
Done!
Toggle quote (6 lines)>> (define* (eye-candy config store-device store-mount-point>> + btrfs-store-subvolume-file-name>> #:key system port)>> I think ‘btrfs-store-subvolume-file-name’ should be a keyword argument.
Done!
Toggle quote (13 lines)>> (define* (grub-configuration-file config entries>> #:key>> (system (%current-system))>> - (old-entries '()))>> + (old-entries '())>> + btrfs-subvolume-file-name)>> I wonder if we should just call it ‘store-directory-prefix’ or similar> since, after all, it’s just about prepending a prefix, which could> perhaps be useful for file systems other than Btrfs.>> Thoughts?
Perhaps, but given it's not yet clear whether another file system willrequire similar support from GRUB, I'd rather keep things as explicit aspossible for now.
Toggle quote (3 lines)> Anyway, that’s great work, so I’ll be happy to finally see it committed> in the coming days!
Thanks for the great words and for having a last look :-).
I've added a news entry and pushed to master as:
Toggle snippet (6 lines)489699c456 allow-booting-from-btrfs-subvolume news: Add entry for Btrfs subvolume boot support.b460ba7992 bootloader: grub: Allow booting from a Btrfs subvolume.fa35fb58c8 file-systems: Add helpers for parsing the options string into an alist.281d80d8e5 linux-boot: Refactor boot-system.
Closing! Thanks to Pierre and Ludovic for testing and reviewing.
Maxim
Closed
P
P
Pierre Neidhardt wrote on 20 May 2020 15:29
(address . 37305-done@debbugs.gnu.org)
87imgq68g1.fsf@ambrevar.xyz
Thanks a lot!This is a huge improvement to Guix in my opinion :)
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7FML4ACgkQm9z0l6S7zH8fxAf+JH8HcsbRsKs24mgBH9/0I9lSCcSfda7Gcd+83jlB1HhkxkfAjatl8ami0lkAul+US7G5V/IMjgHXOOYYU5kjdoJNvufZYeQKn9FtHuoLnlUxvxUvCE+NYZ8PRmfZ7zvNHcnT30OI4oQpPhL6XM/jfy/VdfdwqjBZkahOlPxtARb+qnhtBHCKNa4OCLV/7W+8wRfyXLGllgyLNMW01gw8PNKWCh911sM4eUzygOOcBlwZ11idWIBT1Ovv0d0yQjIfydTv8ZUsUZFPBP2WrcwvIrY4qq0qbgYgRHNhmEbGb/NinQcQxsZbwWLGuHnSrzHAvXe4M/cnTZxJlNAXfaK/9Q===yNo2-----END PGP SIGNATURE-----
Closed
L
L
Ludovic Courtès wrote on 21 May 2020 00:03
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87sgfuclh8.fsf@gnu.org
Hi Maxim,
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
[...]
Toggle quote (17 lines)>>> (define* (grub-configuration-file config entries>>> #:key>>> (system (%current-system))>>> - (old-entries '()))>>> + (old-entries '())>>> + btrfs-subvolume-file-name)>>>> I wonder if we should just call it ‘store-directory-prefix’ or similar>> since, after all, it’s just about prepending a prefix, which could>> perhaps be useful for file systems other than Btrfs.>>>> Thoughts?>> Perhaps, but given it's not yet clear whether another file system will> require similar support from GRUB, I'd rather keep things as explicit as> possible for now.
To me, another consideration is familiarity with Btrfs for those who’lltouch the code: to someone not familiar with it, the code may be viewedas “read-only” because it says “btrfs”. Whereas if it clearly statesthat it’s just about prepending a directory name or similar, it’s easyto reason about it.
Toggle quote (14 lines)>> Anyway, that’s great work, so I’ll be happy to finally see it committed>> in the coming days!>> Thanks for the great words and for having a last look :-).>> I've added a news entry and pushed to master as:>> 489699c456 allow-booting-from-btrfs-subvolume news: Add entry for Btrfs subvolume boot support.> b460ba7992 bootloader: grub: Allow booting from a Btrfs subvolume.> fa35fb58c8 file-systems: Add helpers for parsing the options string into an alist.> 281d80d8e5 linux-boot: Refactor boot-system.>> Closing! Thanks to Pierre and Ludovic for testing and reviewing.
That’s great news, thanks a lot for your work… and for your patience!
Ludo’.
Closed
P
P
Pierre Neidhardt wrote on 21 May 2020 08:58
(address . 37305-done@debbugs.gnu.org)
87tv09epux.fsf@ambrevar.xyz
Ludovic Courtès <ludo@gnu.org> writes:
Toggle quote (6 lines)> To me, another consideration is familiarity with Btrfs for those who’ll> touch the code: to someone not familiar with it, the code may be viewed> as “read-only” because it says “btrfs”. Whereas if it clearly states> that it’s just about prepending a directory name or similar, it’s easy> to reason about it.
Agreed, this is where I was going to with my comment on ZFS.Maybe the "btrfs" part of the symbols can be left out to make it moregeneral and understandable.
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7GJpYACgkQm9z0l6S7zH+BHwf9Ezg/nhB9+37DXruP7g047WBuD4mTexBKqX2KZ5IKvDO4KU3C2m6XKZVJRCReWstcQe+dPASfJ6kig2DXpYUN3pcfjz7BnlWgLMylaSyr6h+kBimaagqW18M279YhYZzKHeCVH8EDK2hlXabEthzihXtkwB/Tc0tktOO5L7grwMbsESc0lzMqJ2wfar2NvkynM9WdLTtJlHFNyykZS2SfzrC5dOTUp/7jOXIzqHelke0pbrtD44+SwqRjJINkYJdCYl7DRXQohVrsTLwSHJXuWKQrcbk3G+u5u2RfC0XQbylXjLzf9wGUl/gwc1sdS5sGwvSSMxsKBZOE9cH/zekhPw===jL6A-----END PGP SIGNATURE-----
Closed
M
M
Maxim Cournoyer wrote on 28 May 2020 06:30
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87lflc65ra.fsf@gmail.com
Hello,
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (12 lines)> Ludovic Courtès <ludo@gnu.org> writes:>>> To me, another consideration is familiarity with Btrfs for those who’ll>> touch the code: to someone not familiar with it, the code may be viewed>> as “read-only” because it says “btrfs”. Whereas if it clearly states>> that it’s just about prepending a directory name or similar, it’s easy>> to reason about it.>> Agreed, this is where I was going to with my comment on ZFS.> Maybe the "btrfs" part of the symbols can be left out to make it more> general and understandable.
I've adapted with the naming suggested earlier by Ludovic. Does thepatch below fit the bill?
Thanks,
Maxim
From ee23cc391cce7b8dcdcb5146d4b84a55881a5cb9 Mon Sep 17 00:00:00 2001From: Maxim Cournoyer <maxim.cournoyer@gmail.com>Date: Wed, 27 May 2020 22:44:28 -0400Subject: [PATCH] bootloader: grub: Rename the btrfs-subvolume-file-name parameter.
Following discussion in https://issues.guix.gnu.org/37305, it seems moreappropriate to give the parameter a more generic name that better describeswhat it does.
* gnu/bootloader/grub.scm (normalize-file): Rename thebtrfs-subvolume-file-name parameter to store-directory-prefix.(eye-candy): Likewise.(grub-configuration-file): Likewise.* gnu/system.scm (operating-system-bootcfg): Adapt.--- gnu/bootloader/grub.scm | 46 ++++++++++++++++++++--------------------- gnu/system.scm | 2 +- 2 files changed, 24 insertions(+), 24 deletions(-)
Toggle diff (141 lines)diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scmindex bb40c551a7..7b2fc18103 100644--- a/gnu/bootloader/grub.scm+++ b/gnu/bootloader/grub.scm@@ -58,8 +58,8 @@ ;;; ;;; Code: -(define* (normalize-file file mount-point btrfs-subvolume-file-name)- "Strip MOUNT-POINT and prepend BTRFS-SUBVOLUME-FILE-NAME to FILE, a+(define* (normalize-file file mount-point store-directory-prefix)+ "Strip MOUNT-POINT and prepend STORE-DIRECTORY-PREFIX to FILE, a G-expression or other lowerable object denoting a file name." (define (strip-mount-point mount-point file)@@ -72,12 +72,12 @@ G-expression or other lowerable object denoting a file name." file))) file)) - (define (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name file)- (if btrfs-subvolume-file-name- #~(string-append #$btrfs-subvolume-file-name #$file)+ (define (prepend-store-directory-prefix store-directory-prefix file)+ (if store-directory-prefix+ #~(string-append #$store-directory-prefix #$file) file)) - (prepend-btrfs-subvolume-file-name btrfs-subvolume-file-name+ (prepend-store-directory-prefix store-directory-prefix (strip-mount-point mount-point file))) @@ -135,14 +135,14 @@ file with the resolution provided in CONFIG." (_ #f))))) (define* (eye-candy config store-device store-mount-point- #:key btrfs-store-subvolume-file-name system port)+ #:key store-directory-prefix system port) "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part concerned with graphics mode, background images, colors, and all that. STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POINT is its mount point; these are used to determine where the background image and fonts must be searched for. SYSTEM must be the target system string---e.g.,-\"x86_64-linux\". BTRFS-STORE-SUBVOLUME-FILE-NAME is the file name of the-Btrfs subvolume, to be prepended to any store path, if any."+\"x86_64-linux\". STORE-DIRECTORY-PREFIX is a directory prefix to prepend to+any store path." (define setup-gfxterm-body (let ((gfxmode (or (and-let* ((theme (bootloader-configuration-theme config))@@ -181,12 +181,12 @@ fi~%" #+font-file) (define font-file (normalize-file (file-append grub "/share/grub/unicode.pf2") store-mount-point- btrfs-store-subvolume-file-name))+ store-directory-prefix)) (define image (normalize-file (grub-background-image config) store-mount-point- btrfs-store-subvolume-file-name))+ store-directory-prefix)) (and image #~(format #$port "@@ -320,13 +320,13 @@ code." #:key (system (%current-system)) (old-entries '())- btrfs-subvolume-file-name)+ store-directory-prefix) "Return the GRUB configuration file corresponding to CONFIG, a <bootloader-configuration> object, and where the store is available at-STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list-of menu entries corresponding to old generations of the system.-BTRFS-SUBVOLUME-FILE-NAME may be used to specify on which subvolume a-Btrfs root file system resides."+STORE-FS, a <file-system> object. OLD-ENTRIES is taken to be a list of menu+entries corresponding to old generations of the system.+STORE-DIRECTORY-PREFIX may be used to specify a store prefix, as is required+when booting a root file system on a Btrfs subvolume." (define all-entries (append entries (bootloader-configuration-menu-entries config))) (define (menu-entry->gexp entry)@@ -336,17 +336,17 @@ Btrfs root file system resides." (arguments (menu-entry-linux-arguments entry)) (kernel (normalize-file (menu-entry-linux entry) device-mount-point- btrfs-subvolume-file-name))+ store-directory-prefix)) (initrd (normalize-file (menu-entry-initrd entry) device-mount-point- btrfs-subvolume-file-name)))+ store-directory-prefix))) ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount point. ;; Use the right file names for KERNEL and INITRD in case ;; DEVICE-MOUNT-POINT is not "/", meaning that the store is on a ;; separate partition. - ;; When BTRFS-SUBVOLUME-FILE-NAME is defined, prepend it the kernel and- ;; initrd paths, to allow booting from a Btrfs subvolume.+ ;; When STORE-DIRECTORY-PREFIX is defined, prepend it to the kernel and+ ;; initrd paths, for example to allow booting from a Btrfs subvolume. #~(format port "menuentry ~s { ~a linux ~a ~a@@ -360,7 +360,7 @@ Btrfs root file system resides." (eye-candy config (menu-entry-device (first all-entries)) (menu-entry-device-mount-point (first all-entries))- #:btrfs-store-subvolume-file-name btrfs-subvolume-file-name+ #:store-directory-prefix store-directory-prefix #:system system #:port #~port)) @@ -371,8 +371,8 @@ Btrfs root file system resides." (keymap* (and layout (keyboard-layout-file layout #:grub grub))) (keymap (and keymap*- (if btrfs-subvolume-file-name- #~(string-append #$btrfs-subvolume-file-name+ (if store-directory-prefix+ #~(string-append #$store-directory-prefix #$keymap*) keymap*)))) #~(when #$keymapdiff --git a/gnu/system.scm b/gnu/system.scmindex d929187695..ac8bbd1d16 100644--- a/gnu/system.scm+++ b/gnu/system.scm@@ -1118,7 +1118,7 @@ a list of <menu-entry>, to populate the \"old entries\" menu." (generate-config-file bootloader-conf (list entry) #:old-entries old-entries- #:btrfs-subvolume-file-name+ #:store-directory-prefix (btrfs-store-subvolume-file-name file-systems)))) (define* (operating-system-boot-parameters os root-device-- 2.26.2
Closed
P
P
Pierre Neidhardt wrote on 28 May 2020 10:26
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87eer44g8m.fsf@ambrevar.xyz
Looks good to me, but:
Toggle quote (2 lines)> (btrfs-store-subvolume-file-name file-systems))))
I haven't looked at the context, but is this procedure really Btrfs-only?
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7PdckACgkQm9z0l6S7zH9l/AgArRm+83adOnfs7gIXLrf5FzGxg5OhLpPz1YNF2qKXmkAMDMr+Yh2QDnvuVKfxf+MoYd+75aa55kirni/SIv34efrM8MqX5HLllrXltJGZQ07mYwep0BDCBBmEYRLjBtSloSjvnWNsAIBzbAiDRuN2FK/5SQOYwk7AJnGx4r345Lmr9Ve7DGs/oRSCXvUSmmVmr5hZGPrflvSCFzZo1JFIlYnoAJ4rVnOQVpynn1EqthIfyq/vUccMrwVioZNy8ZtUEtvsmEz2uzu78Cw6Bh2vqG2LANiaqVQ5U2jv0SDCW0sIwmCHCjUKMWAl8XnZ+B8fzr1WQwesD8/EWYnjVQMJDQ===nsT8-----END PGP SIGNATURE-----
Closed
L
L
Ludovic Courtès wrote on 28 May 2020 14:30
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
87tv00ckdl.fsf@gnu.org
Hello!
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
Toggle quote (16 lines)> From ee23cc391cce7b8dcdcb5146d4b84a55881a5cb9 Mon Sep 17 00:00:00 2001> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>> Date: Wed, 27 May 2020 22:44:28 -0400> Subject: [PATCH] bootloader: grub: Rename the btrfs-subvolume-file-name> parameter.>> Following discussion in <https://issues.guix.gnu.org/37305>, it seems more> appropriate to give the parameter a more generic name that better describes> what it does.>> * gnu/bootloader/grub.scm (normalize-file): Rename the> btrfs-subvolume-file-name parameter to store-directory-prefix.> (eye-candy): Likewise.> (grub-configuration-file): Likewise.> * gnu/system.scm (operating-system-bootcfg): Adapt.
[...]
Toggle quote (13 lines)> (define* (eye-candy config store-device store-mount-point> - #:key btrfs-store-subvolume-file-name system port)> + #:key store-directory-prefix system port)> "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part> concerned with graphics mode, background images, colors, and all that.> STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POINT is> its mount point; these are used to determine where the background image and> fonts must be searched for. SYSTEM must be the target system string---e.g.,> -\"x86_64-linux\". BTRFS-STORE-SUBVOLUME-FILE-NAME is the file name of the> -Btrfs subvolume, to be prepended to any store path, if any."> +\"x86_64-linux\". STORE-DIRECTORY-PREFIX is a directory prefix to prepend to> +any store path."
s/path/file name/ :-)
Maybe you can have ‘store-directory-prefix’ default to "" and adjustusers accordingly.
Otherwise LGTM.
Thanks for taking the time to work on this patch!
Ludo’.
Closed
M
M
Maxim Cournoyer wrote on 29 May 2020 23:14
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87sgfixx37.fsf@gmail.com
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (6 lines)> Looks good to me, but:>>> (btrfs-store-subvolume-file-name file-systems))))>> I haven't looked at the context, but is this procedure really Btrfs-only?
Yes! It takes a list of file-system objects, filter the Btrfs onesusing the "subvol" option and returns their subvolume file name, if thestore is mounted on such subvolume.
Closed
M
M
Maxim Cournoyer wrote on 30 May 2020 04:00
(name . Ludovic Courtès)(address . ludo@gnu.org)
87lflaxjv2.fsf@gmail.com
Hello,
Ludovic Courtès <ludo@gnu.org> writes:
[...]
Toggle quote (5 lines)>> +\"x86_64-linux\". STORE-DIRECTORY-PREFIX is a directory prefix to prepend to>> +any store path.">> s/path/file name/ :-)
Done!
Toggle quote (3 lines)> Maybe you can have ‘store-directory-prefix’ default to "" and adjust> users accordingly.
I tried adapting it, but my test failed, because I had failed to adaptone of the users. I find that using #f to denote the absence of aprefix more accurate than "" (after all, "" is a valid prefix) andcomposes better (should we want to 'or' a couple of prefix seekingprocedures together).
Toggle quote (4 lines)> Otherwise LGTM.>> Thanks for taking the time to work on this patch!
No problem :-) Pushed as commit e7b86a0d88.
Maxim
Closed
P
P
Pierre Neidhardt wrote on 30 May 2020 09:32
(address . 37305-done@debbugs.gnu.org)
87r1v1dgiw.fsf@ambrevar.xyz
Hooray!
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7SDBcACgkQm9z0l6S7zH/PVAf+OJVOUk+N2J4J7SqjVGXILW6qXiY+GrXm2lg/W2T+o46j0Lm50IjZBtdFavzWCdQcomRR7ZGsjrSgFPEutHmEcKQ09aLbf0PZfK6BvYO29C7fiabYXj65mLN4fLIwl7dGH45g3xhmaA73Gax5cBfJCifIaYJGTFDyA991hchaQm1b5DeGh4Wke3muz48vljraW4QM084C+BwHK61FaQw+QgW+RbMUU6y2orqWEJEz0NYnL1irKY6xC6R6v8e/BBgOQx+fKQyN/oDwft/SAIlqkBSC5f7o8W33TwOr+pQwRCvQAh7pVc+MMcXGj747AZNbj6E06Em6VGNZf2FfsoKVHA===AEBq-----END PGP SIGNATURE-----
Closed
P
P
Pierre Neidhardt wrote on 30 May 2020 09:32
(address . 37305-done@debbugs.gnu.org)
87o8q5dgif.fsf@ambrevar.xyz
Maybe this would warrant a blog post! :)
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7SDCgACgkQm9z0l6S7zH/QOAgAjc7mqdh991/q2yWEVjthRiSb9h8Cm/0gYG1bMnyDhZ5eVJf6cL2AeFWCRIypZ3O44QgCjSucUxkTMuehm4tadPNszlBHDznxTl6KGjfX6FR6P+PHJBgBre+U3bIlshx+aU7DEgR4zHwxyFiKcUZflTYvIUH6QzMecNE5sSa2gkQ5YQDASE0HLo9sNDz+fBukg+f2Bc/9hHnujxmshM+unb25Eb9PA+QxDYN97Rgl54YP+kSWzAcH+bPrRcWgPlTQrmXdFPjbbfA2AwFjHRzYNIYPdr5AJZQeMEd0hrc8GUt1XkwgJuCAHcW+iSZRH41pPf6+RvgRDxPAITfiwWYhmA===kbF2-----END PGP SIGNATURE-----
Closed
M
M
Maxim Cournoyer wrote on 31 May 2020 04:44
(name . Pierre Neidhardt)(address . mail@ambrevar.xyz)
87k10sx1qn.fsf@gmail.com
Hello Pierre!
Pierre Neidhardt <mail@ambrevar.xyz> writes:
Toggle quote (2 lines)> Maybe this would warrant a blog post! :)
Eh, I'm not sure. It's kind of a basic thing that other systems alreadysupport (through grub-mkconfig). We've just caught up :-).
Maxim
Closed
P
P
Pierre Neidhardt wrote on 31 May 2020 09:32
(name . Maxim Cournoyer)(address . maxim.cournoyer@gmail.com)
871rn04l04.fsf@ambrevar.xyz
Sure, but I don't know how popular Btrfs is, plus compression is a verywelcome addition to Guix (for all those SSD users with little space :p).
Granted, this is not very Guix specific...
-- Pierre Neidhardthttps://ambrevar.xyz/
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCAAdFiEEUPM+LlsMPZAEJKvom9z0l6S7zH8FAl7TXasACgkQm9z0l6S7zH8PIAf8DvFyB0tZB4zXe+n8No7xrMY2hW3UpJ1YTlGG4oFZ2pVUL2JDNc1HNmRay+/VbDOv/EwTS5kuh1dkAym1rc9lCBSRmAEgs3tBacdiTuiDRvkLFzDWurtjZRP7+prxuJRGpjuxIf+OkGCQ/NeJvWWWZxf4/sYG8XtfyRi8x43aYWc1hZqkJ/CtgaAfuo3XOlzeyacDxNndEF3j9ECSNBLj6dIQ6/1CVtTBR0ET6gt733GQgwXMeXWH/8gn+k5iG7yOMhkl3QHjdna/D6L8xsZ/+wsvJ5F1F0vhUFv9Dgi0un6Vhuw6IKjT383o98OBNfixUILKh2W5KGdDIyZjeCO2Gw===uGkx-----END PGP SIGNATURE-----
Closed
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send email to 37305@debbugs.gnu.org