GNU bug report logs - #37305
[PATCH] Allow booting from a Btrfs subvolume.

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: guix-patches; Reported by: Maxim Cournoyer <maxim.cournoyer@HIDDEN>; Keywords: patch; dated Thu, 5 Sep 2019 00:21:01 UTC; Maintainer for guix-patches is guix-patches@HIDDEN.
Added indication that bug 37305 blocks40236 Request was from Maxim Cournoyer <maxim.cournoyer@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 18 Mar 2020 15:28:12 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Mar 18 11:28:12 2020
Received: from localhost ([127.0.0.1]:41051 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1jEac6-0004rk-Se
	for submit <at> debbugs.gnu.org; Wed, 18 Mar 2020 11:28:12 -0400
Received: from mail-qt1-f194.google.com ([209.85.160.194]:37465)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1jEac4-0004rW-6S
 for 37305 <at> debbugs.gnu.org; Wed, 18 Mar 2020 11:28:09 -0400
Received: by mail-qt1-f194.google.com with SMTP id l20so21002925qtp.4
 for <37305 <at> debbugs.gnu.org>; Wed, 18 Mar 2020 08:28:08 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=ZLEk45Cu/3CuTc2Of82GB8D/n24Bsf2uYPB/FxCrd/Y=;
 b=UP25oKwlzfFbgyqLrYq9VdzwUu0n9h6e+RVc5zXvglrV0NnsufzbZkL9At8iwPGZ7f
 QCse52+rko3HK0SSnOUctCF8xJd6FxBdGz8Ze1LEdKNUwFIhwjjtbVnyUIm32VAeUFc1
 nQQqoPKvXEQEBwPD0JUCBU6IBuATWN4j/biyELqE4lWTB87pNC3bfAmPzVZFzqVSX8wR
 Qvak/h7v5ZVpyrW/X7O0NsH9LNb72KA91ILMtMSBBPj7sxxgZ2BOOgCGqTn76/Q1AUiP
 OjtI9qPQBUA86tLveYFoziM0IuveqnZkZuzTxSw4dVxiAsYAMEXNPhSpNDUGOkgzl2K9
 qfVA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=ZLEk45Cu/3CuTc2Of82GB8D/n24Bsf2uYPB/FxCrd/Y=;
 b=Qt/iAubrJNgAy2SR6B+g1RCk3Ezkkaxf9nY9VyVqWGBxGc52I2FY3cMMPmzVWdGPcu
 JxDXOAd/zovses6jEvVgvUtlokW2NIuE/5MWQHxTLdUxk9ikzOYRNEaiKUA+Zkxk0LKo
 ok+ZyDNLy1u73nwWFF/3rQioUG1SxkmLAIlykSG/GvWqH8TAlSTX0LDCtzXW5tYNPUm3
 IccenZebwSv39hWQOpvED+uQzEvHcyu6NZUa9q4KBtnlouWc7acUEQ+vTwdIpte2S9Xi
 ET2WnJlhPOrUMqiXRWJlkF+NFiFo77DfiMmkJzENkkOzdA2HZUzx62ZR+YfwuJ6OqjB/
 rqug==
X-Gm-Message-State: ANhLgQ3H4WyJRii9TdWH9bMeP/vsgHLrlGHBzPC7eJddyQPRbtDRS9Va
 eEfjcrAus7fKZkkbqzlOQJiq12/oiPQ=
X-Google-Smtp-Source: ADFU+vvkyPrAuWN5+wW9c2hKI6sI31A3ROt/74eUwwzKquK0OQN8NDvMp8mRALZFtoBnMw3i4cda6w==
X-Received: by 2002:aed:21bc:: with SMTP id l57mr5010641qtc.218.1584545281942; 
 Wed, 18 Mar 2020 08:28:01 -0700 (PDT)
Received: from raisin ([2607:fad8:4:6:235e:8579:8464:aacc])
 by smtp.gmail.com with ESMTPSA id f13sm5156122qte.53.2020.03.18.08.27.58
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 18 Mar 2020 08:27:59 -0700 (PDT)
From: maxim.cournoyer@HIDDEN
X-Google-Original-From: mcournoyer@HIDDEN
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
References: <875zg2xtsb.fsf@HIDDEN> <87lfoxbn2e.fsf@HIDDEN>
Date: Wed, 18 Mar 2020 11:27:58 -0400
In-Reply-To: <87lfoxbn2e.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Thu, 20 Feb 2020 10:55:05 +0100")
Message-ID: <87v9n1pts1.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org, Maxim Cournoyer <maxim.cournoyer@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hi Ludovic,

Ludovic Court=C3=A8s <ludo@HIDDEN> writes:

> Hi Maxim,
>
> Maxim Cournoyer <maxim.cournoyer@HIDDEN> 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 =E2=80=98raise=E2=80=99 with =E2=80=98&message=E2=80=99 and =
=E2=80=98&fix-hint=E2=80=99 conditions.
>>
>> I tried this, but importing (guix utils) to acces &fix-hint caused the i=
nit
>> RAM disk to fail mysteriously:
>
> Oh, my bad.  We should move =E2=80=98&fix-hint=E2=80=99 to (guix diagnost=
ics)
> eventually.
>
> In the meantime, I=E2=80=99d say just raise a =E2=80=98&message=E2=80=99 =
and leave the hint as a
> comment (it=E2=80=99s not supposed to be a user-facing interface).  Or ma=
ybe you
> could define a specific error condition type for this?
>
> Thanks,
> Ludo=E2=80=99.
>
> PS: I=E2=80=99ll comment on the other bits ASAP!

The remaining, reworked patches for this series are attached below.  If
you don't want to merge the 0001 for now (speeding up tests), I don't
mind too much (though it still provides value to me, when using old
hardware).

Thanks for your patience :-)

Maxim


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-gnu-tests-Reduce-the-time-required-to-run-the-system.patch
Content-Transfer-Encoding: quoted-printable

From 62bb442870864a8e867023f95d814dc1b389512a Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 17 Nov 2019 06:01:00 +0900
Subject: [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 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 procedu=
re.
* etc/system-tests.scm (tests-for-channel-instance): Use it, when
GUIX_DEV_HACKS is defined.
---
 etc/system-tests.scm                |  5 ++-
 gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/etc/system-tests.scm b/etc/system-tests.scm
index 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 =C2=A9 2016, 2018, 2019, 2020 Ludovic Court=C3=A8s <ludo@gnu=
.org>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -49,7 +50,9 @@ instance."
   ;;
   ;;   make check-system TESTS=3Dinstalled-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-man=
agement.scm
index 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 'so=
urce'."
                                 #:recursive? #t
                                 #:select? (force select?))))))))
=20
+(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 RE=
PL.
+         ;; 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 n=
icer
+             ;; 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 t=
o 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 t=
he
+                 ;; 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 profil=
e,
+                         ;; we could make this package inherit from the gu=
ix
+                         ;; 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.
--=20
2.25.1


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-linux-boot-Refactor-boot-system.patch

From c60913505af32c2005ffc9bb3ea7078de5379c54 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:00:06 -0500
Subject: [PATCH 2/5] 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 precedence over the device field string
representation of the root file system.
* doc/guix.texi (Initial RAM Disk): Document that "--root" can be left
unspecified.
---
 doc/guix.texi            |  7 +++--
 gnu/build/linux-boot.scm | 60 +++++++++++++++++++---------------------
 2 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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 to
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0003-file-systems-Add-helpers-for-parsing-the-options-str.patch
Content-Transfer-Encoding: quoted-printable

From 62f62a1b49adbe13a1d401ac16f56d58fda2af78 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Wed, 25 Sep 2019 22:43:41 +0900
Subject: [PATCH 3/5] file-systems: Add helpers for parsing the options stri=
ng
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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.
=20
 @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 f=
or
-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.
=20
 @item @code{mount?} (default: @code{#t})
 This value indicates whether to automatically mount the file system when
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index 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 =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
+(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 ((=3Dindex (string-index param #\=3D)))
+                 (if =3Dindex
+                     (cons (string-take param =3Dindex)
+                           (string-drop param (1+ =3Dindex)))
+                     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 "=3D" 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 t=
he
 store--e.g., if FS is the root file system."
diff --git a/tests/file-systems.scm b/tests/file-systems.scm
index 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 =C2=A9 2015, 2017 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -64,4 +65,22 @@
           (_ #f))
         (source-module-closure '((gnu system file-systems)))))
=20
+(test-equal "file-system-options->alist"
+  '("autodefrag" ("subvol" . "home") ("compress" . "lzo"))
+  (file-system-options->alist "autodefrag,subvol=3Dhome,compress=3Dlzo"))
+
+(test-equal "file-system-options->alist (#f)"
+  '()
+  (file-system-options->alist #f))
+
+(test-equal "alist->file-system-options"
+  "autodefrag,subvol=3Droot,compress=3Dlzo"
+  (alist->file-system-options '("autodefrag"
+                                ("subvol" . "root")
+                                ("compress" . "lzo"))))
+
+(test-equal "alist->file-system-options (null)"
+  #f
+  (alist->file-system-options '()))
+
 (test-end)
--=20
2.25.1


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0004-bootloader-grub-Allow-booting-from-a-Btrfs-subvolume.patch
Content-Transfer-Encoding: quoted-printable

From 12e7ca2628a7e16a1afacfd8953bd6bcfe5c10bd Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 14 Jul 2019 20:50:23 +0900
Subject: [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.  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 w=
ith
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".
---
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index f55098cfd5..5dfd62d02f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11589,6 +11589,110 @@ and unmount user-space FUSE file systems.  This r=
equires the
 @code{fuse.ko} kernel module to be loaded.
 @end defvr
=20
+@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=3Drootfs")
+  (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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume directory)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 root-snapshots          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 root-current        (subvolume)
+        =E2=94=9C=E2=94=80=E2=94=80 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=3Droot-snapshots/root-current/guix-store"
+  ("compress" . "zstd")))
+@end lisp
+
 @node Mapped Devices
 @section Mapped Devices
=20
diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scm
index 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.scm
index 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-F=
S, a
 <file-system> object.  OLD-ENTRIES is taken to be a list of menu entries
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index 28e6cb1f5f..e7a6f928c6 100644
--- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -63,18 +63,29 @@
 ;;;
 ;;; Code:
=20
-(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=3D? 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=3D? 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 fil=
e)
+    (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)))
+
+
=20
 (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))))
=20
 (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, a=
nd
-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' p=
art
+concerned with graphics mode, background images, colors, and all that.
+STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POIN=
T 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)))))
=20
   (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))
=20
   (define image
-    (grub-background-image config))
+    (normalize-file (grub-background-image config)
+                    store-mount-point
+                    btrfs-store-subvolume-file-name))
=20
   (and image
        #~(format #$port "
@@ -214,7 +230,7 @@ fi~%"
                  #$(setup-gfxterm config font-file)
                  #$(grub-setup-io config)
=20
-                 #$(strip-mount-point store-mount-point image)
+                 #$image
                  #$(theme-colors grub-theme-color-normal)
                  #$(theme-colors grub-theme-color-highlight))))
=20
@@ -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 me=
nu
-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 poin=
t.
       ;; 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))
=20
   (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))))
=20
   (define builder
     #~(call-with-output-file #$output
diff --git a/gnu/system.scm b/gnu/system.scm
index 06c58c27ba..d1f1b43426 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Meiyo Peng <meiyo.peng@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
     (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))))
=20
 (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.scm
index 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
=20
             file-system-type-predicate
+            btrfs-subvolume?
+            btrfs-store-subvolume-file-name
=20
             file-system-label
             file-system-label?
@@ -565,4 +570,57 @@ system has the given TYPE."
   (lambda (fs)
     (string=3D? (file-system-type fs) type)))
=20
+
+;;;
+;;; 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=3D "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=3D? "/" (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=3D> (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 n=
ot
+        ;; 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 here
diff --git a/gnu/tests/install.scm b/gnu/tests/install.scm
index 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
=20
             %test-gui-installed-os
@@ -834,6 +835,99 @@ build (current-guix) and then store a couple of full s=
ystem images.")
                          (command (qemu-command/writable-image image)))
       (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
=20
+
+;;;
+;;; 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=3DttyS0"))
+    (file-systems (cons* (file-system
+                           (device (file-system-label "btrfs-pool"))
+                           (mount-point "/")
+                           (options "subvol=3Drootfs,compress=3Dzstd")
+                           (type "btrfs"))
+                         (file-system
+                           (device (file-system-label "btrfs-pool"))
+                           (mount-point "/home")
+                           (options "subvol=3Dhomefs,compress=3Dlzo")
+                           (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=3D--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=3Dbtrfs-pool -o 'subvol=3Drootfs,compress=3Dzstd' /mnt
+mkdir /mnt/home
+mount LABEL=3Dbtrfs-pool -o 'subvol=3Dhomefs,compress=3Dzstd' /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.scm
index 41f1021067..7f7c373884 100644
--- a/tests/file-systems.scm
+++ b/tests/file-systems.scm
@@ -83,4 +83,49 @@
   #f
   (alist->file-system-options '()))
=20
+
+;;;
+;;; Btrfs related.
+;;;
+
+(define %btrfs-root-subvolume
+  (file-system
+    (device (file-system-label "btrfs-pool"))
+    (mount-point "/")
+    (type "btrfs")
+    (options "subvol=3Drootfs,compress=3Dzstd")))
+
+(define %btrfs-store-subvolid
+  (file-system
+    (device (file-system-label "btrfs-pool"))
+    (mount-point "/gnu/store")
+    (type "btrfs")
+    (options "subvolid=3D10,compress=3Dzstd")
+    (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=3D/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)
--=20
2.25.1


--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 7 Mar 2020 04:01:25 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Mar 06 23:01:25 2020
Received: from localhost ([127.0.0.1]:46086 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1jAQeS-0004C5-Hh
	for submit <at> debbugs.gnu.org; Fri, 06 Mar 2020 23:01:25 -0500
Received: from mail-qt1-f179.google.com ([209.85.160.179]:36014)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1jAQeQ-0004Bq-FV
 for 37305 <at> debbugs.gnu.org; Fri, 06 Mar 2020 23:01:22 -0500
Received: by mail-qt1-f179.google.com with SMTP id m33so3338253qtb.3
 for <37305 <at> debbugs.gnu.org>; Fri, 06 Mar 2020 20:01:22 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=5VSihh2zBwDDASPSNvSbmAu8yhTc9x/xhoISq/xfHzQ=;
 b=dTcMm4d+VHa9XBMU4zW1bnQT7dzuClOQI5fDRnPOPuqQ/Y8by8zRKcTKTinT7n9jYS
 WKS9YDd5W8e42D+vM/ypYdhe+gvJ2unJOUTYJ5r1iQ4P3YbjGDLQi9sYjC3DOvElatYC
 Mw0h+5AwRrZsUWE5uh/KMypOmnRDZ4mygtM17V4wnJ+Es7wRnRWhkwbhGLSU+cKUAwk5
 bJvbvNAhMXbEoDRzIhxVIMlfvWdtZgOiGWFU7pt7V1ZyESV2i9ZRveJRwtUHXs+8Degg
 75m/10NKSvj1gBoTzOQzp+rOVe3GbYL8KH1P/H9OUtnj1I/fMUBEoTY9dWVuGObE/oCP
 UkfQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=5VSihh2zBwDDASPSNvSbmAu8yhTc9x/xhoISq/xfHzQ=;
 b=Gk2tBn/BdpZAqUNZWUdHFZw5JfUFpoJuWQpTdD+wta704RiLcrxUnCPK9vrTQsOM3g
 QV/PnEDwZoo5giJ+XTnizZCn7LyWlBi3rAqDsbQ4n/HkvSZBiu0reMFMjJkaECnFJPRs
 cvN0KCpOERlY6HlvMblo/u1LGAY8yqBEq43XRMizqLZsCGhMw5jCGaG9rMDAEkAtEqKP
 nPvAw1vhfixmGZDUXvGwj2Ng3IE7OlGO7uRc2tyfZtovqmjB0knCs0WSEjv4mFT/bKq8
 p73Ffwm5HdNoOyVbTtQSzAWrDE+hGY1Z8/PomGGITgt/d8wzf/ohYZafjNHXdvMp02cn
 fvTA==
X-Gm-Message-State: ANhLgQ0HFNvI2w5to2WuugmESOboQH5TnLRaxDP14PEqXr91L7uYZl0f
 aRwAyJAnh0+dyE99EZhRgxVtXYhp
X-Google-Smtp-Source: ADFU+vvUmwuB1HIO5HHYeiN5vTZrW/PQAP+CdBWK6WbkzWk4Qc37GAeCX6fXs1HrBZhXjWJcW+Z2pw==
X-Received: by 2002:ac8:7956:: with SMTP id r22mr5907801qtt.323.1583553676541; 
 Fri, 06 Mar 2020 20:01:16 -0800 (PST)
Received: from apteryx ([207.35.95.105])
 by smtp.gmail.com with ESMTPSA id x93sm10823374qte.60.2020.03.06.20.01.15
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 06 Mar 2020 20:01:15 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] Making system installation tests faster
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
 <8736ba3hxo.fsf_-_@HIDDEN> <87sgj8j9sf.fsf@HIDDEN>
 <87sgj7wpqa.fsf@HIDDEN>
Date: Fri, 06 Mar 2020 23:01:14 -0500
In-Reply-To: <87sgj7wpqa.fsf@HIDDEN> (Maxim Cournoyer's message of "Tue, 18
 Feb 2020 16:27:25 -0500")
Message-ID: <87eeu4ke45.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Hello, this is a small update, to reflect recent changes to the code
base.

Maxim Cournoyer <maxim.cournoyer@HIDDEN> writes:

> 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 code
above.  Here's an updated version:

--8<---------------cut here---------------start------------->8---
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)))))))))'
--8<---------------cut here---------------end--------------->8---

Time taken:

real    7m39.912s
user    0m57.129s
sys     0m0.499s

Compared to recycling the Guix development copy from the work tree:

real    0m48.297s
user    0m2.516s
sys     0m0.229s

Maxim




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 3 Mar 2020 05:00:17 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Mar 03 00:00:16 2020
Received: from localhost ([127.0.0.1]:38600 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j8zfE-0007DZ-Jc
	for submit <at> debbugs.gnu.org; Tue, 03 Mar 2020 00:00:16 -0500
Received: from mail-qk1-f194.google.com ([209.85.222.194]:46889)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j8zfD-0007DJ-8G
 for 37305 <at> debbugs.gnu.org; Tue, 03 Mar 2020 00:00:15 -0500
Received: by mail-qk1-f194.google.com with SMTP id u124so2144434qkh.13
 for <37305 <at> debbugs.gnu.org>; Mon, 02 Mar 2020 21:00:15 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version:content-transfer-encoding;
 bh=IlZ5VwqEMMqddF0lgJmJZ9Qnx2++BOsC3TBkig4Rg7I=;
 b=Jk9Q5w75RaWfRq+4rqhwAz1aQT6x9PJPF2hOlSTTRVakH7e+DVTM6tlmwgBLtuTY9T
 MAao8AOuP0uV1k8oTYPdyl65PtTfhtm+bHNWxtkeabE4wq5M5/Fu5S9xbB3LNfQhva5X
 Kzvp40X0ol2ghJDw+A3zkr/IJscleSUa8tTugfVXc+qgbCPpUNr+hZ6njyOejOsVDVel
 yqREBIBLN5fvezVwwyVRGot9mZ+Ah3D8uIgc1yGrAsFhv/lIof4yjIyEZq40FgU948mo
 yqgdLC2coHHI3tpAk2n70GIfi53XymrrCtXAwrP4xz3T/PdebhJkbfUSYV2GUTmYJohr
 FFDg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version:content-transfer-encoding;
 bh=IlZ5VwqEMMqddF0lgJmJZ9Qnx2++BOsC3TBkig4Rg7I=;
 b=lWwwQdECUOd3aTziKPYQazhk99nhXz/aU9yqy8CL7NALzEFg/8Ni8/05IywO+ufht8
 18pC0jilKjHQKH4z926Qd87EfQLP0X1wQgWgrRaBmNBcdDuzIlgBzgxwamj28Vs7YmhB
 2xj+SHXvpn0hzfmGd8x/eQUAyiAxkFpoYioBWIwUQAwHhtnNKYip3ZVvmB8calzT7F8t
 winbzmWQhvU+WuQFEJeWu6Stvjc6YQQ6l126MxXT0QYU96XdglsSu1Hg9f6zrptBNYTu
 fgxU4mMIypHHFQovxcWW1JqKrY9d8fYJw9M7AnLX4D4lC+BFsaVgv9TPGnRu3aHKoWWH
 uGzg==
X-Gm-Message-State: ANhLgQ23LiJcdPSEcaybNL+laqFfc5hSijqLLIXuQoZPWHjhPuRQBquO
 qvbmXPFLW++Jb9NNwyOqQP0TJZXk
X-Google-Smtp-Source: ADFU+vu5Vc8FRLCqxQwrOJkOTbgLq6TDgrsVxmVfDbNo1pDmN3TSVxCnfp8UxDfmmDvZMAeCcgKMTQ==
X-Received: by 2002:ae9:eb43:: with SMTP id b64mr2476978qkg.314.1583211609377; 
 Mon, 02 Mar 2020 21:00:09 -0800 (PST)
Received: from apteryx (dsl-10-148-69.b2b2c.ca. [72.10.148.69])
 by smtp.gmail.com with ESMTPSA id e88sm4135082qtd.9.2020.03.02.21.00.07
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Mon, 02 Mar 2020 21:00:08 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
 <87imjwkm6u.fsf@HIDDEN>
Date: Tue, 03 Mar 2020 00:00:05 -0500
In-Reply-To: <87imjwkm6u.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Mon, 24 Feb 2020 17:02:49 +0100")
Message-ID: <87y2sijane.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: -1.5 (-)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -2.5 (--)

Hello Ludovic!

Resuming review; I hope I'll be able to bring this series to completion
this time.

[...]

> =E2=80=9Cgnu:=E2=80=9D is for changes to (gnu packages).  The idea is tha=
t the prefix
> should reflect what subsystem the commit is modifying.  But yeah,
> looking at =E2=80=98git log=E2=80=99 can be inspiring.  :-)

OK.  Makes sense.  Thanks for taking the time to explain!

[...]

>> 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=E2=80=99s certainly useful to have =E2=80=98--=
root=E2=80=99 at least
> as an option.
>
>>> The main issue I see with this change is that mount(2) takes raw strings
>>> for the options.  There=E2=80=99s a convention to have those strings lo=
ok like
>>> =E2=80=9CKEY1=3DVALUE1,KEY2=3DVALUE2=E2=80=9D, but it=E2=80=99s just a =
convention.
>>>
>>> As a rule of thumb, I=E2=80=99d 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.

[...]

>> 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 =E2=80=9Cdefaults=E2=80=9D option, a way to pass mount(2)=
 flags as
> options (like =E2=80=9Cro=E2=80=9D, =E2=80=9Cremount=E2=80=9D, =E2=80=9Cb=
ind=E2=80=9D), /etc/fstab handling, etc.
>
> Guix System handles /etc/fstab differently and =E2=80=9Cdefaults=E2=80=9D=
 makes little
> sense in our API (one can just use leave the default value of the
> =E2=80=98options=E2=80=99 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=E2=80=99t improve clarity and future-proof-ness (what if a file sys=
tem has
> a =E2=80=9Cbind=E2=80=9D option, etc.).

I think I agree.  It may be cleaner to use the API of mount(2), while
mapping the low level stuff (binary flags?) to saner symbols, like it's
already done.

> 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=E2=80=99t hard-code that directly in our API.

Okay.  I'll keep them around in (gnu system file-systems); they're handy
when we need to check the presence of an option in the option string.

> WDYT?
>
>>>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001
>>>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>>>> 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" k=
ernel
>>>> argument, and use it when calling `mount-root-file-system'.  Update do=
c.
>>>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-op=
tions"
>>>> 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=E2=80=99d rather avoid it for now.  Less code is better.  :-)

Done!

>>> (Also, in hindsight, I think it was a mistake to call them
>>> =E2=80=98--something=E2=80=99.  Following the common naming convention,=
 we should rather
>>> call these options =E2=80=98gnu.something=E2=80=99.)
>>
>> Is this convention detailed somewhere?  I haven't found it in 'Standards=
'.
>
> It=E2=80=99s a convention of the Linux kernel, I don=E2=80=99t know if it=
=E2=80=99s documented.

Well, with Hurd support coming, perhaps the standards used for a
particular kernel are not too relevant? :-)

One last thing that I'll try to understand before considering this
finished: I think adding a special properties field to the file system
record might not be necessary, as it seems that the subvol option can
take an absolute path as well as a relative path (I thought it only
accepted subvolume *names*.)

Will send the 3rd revision soon.

Thank you!

Maxim




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 24 Feb 2020 16:03:01 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Feb 24 11:03:01 2020
Received: from localhost ([127.0.0.1]:53959 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j6GCC-0006Lf-UI
	for submit <at> debbugs.gnu.org; Mon, 24 Feb 2020 11:03:01 -0500
Received: from eggs.gnu.org ([209.51.188.92]:50417)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1j6GCB-0006LJ-0K
 for 37305 <at> debbugs.gnu.org; Mon, 24 Feb 2020 11:02:59 -0500
Received: from fencepost.gnu.org ([2001:470:142:3::e]:57017)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1j6GC5-0003WT-S8; Mon, 24 Feb 2020 11:02:53 -0500
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=34546 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1j6GC3-0005ob-AD; Mon, 24 Feb 2020 11:02:52 -0500
From: =?utf-8?Q?Ludovic_Court=C3=A8s?= <ludo@HIDDEN>
To: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Subject: Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
Date: Mon, 24 Feb 2020 17:02:49 +0100
In-Reply-To: <87blpzozz7.fsf@HIDDEN> (Maxim Cournoyer's message of "Sun, 16
 Feb 2020 00:36:28 -0500")
Message-ID: <87imjwkm6u.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hi Maxim,

Resuming review of this series=E2=80=A6  Sorry for the delay!

Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:

>>> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001
>>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>>> 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 =E2=80=9Cgnu:=E2=80=9D 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? :-)

=E2=80=9Cgnu:=E2=80=9D is for changes to (gnu packages).  The idea is that =
the prefix
should reflect what subsystem the commit is modifying.  But yeah,
looking at =E2=80=98git log=E2=80=99 can be inspiring.  :-)

>>>  @item --root=3D@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 syst=
em
>>> -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=E2=80=99ve been c=
arrying
>> =E2=80=98--root=E2=80=99 and I=E2=80=99m not sure if I=E2=80=99m forgett=
ing 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, =E2=80=98--root=E2=80=99 can resolve labels and UUIDs; my question was=
 more about
why we have it in the first place.

> 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=E2=80=99s certainly useful to have =E2=80=98--ro=
ot=E2=80=99 at least
as an option.

>> The main issue I see with this change is that mount(2) takes raw strings
>> for the options.  There=E2=80=99s a convention to have those strings loo=
k like
>> =E2=80=9CKEY1=3DVALUE1,KEY2=3DVALUE2=E2=80=9D, but it=E2=80=99s just a c=
onvention.
>>
>> As a rule of thumb, I=E2=80=99d 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 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 =E2=80=9Cdefaults=E2=80=9D option, a way to pass mount(2) f=
lags as
options (like =E2=80=9Cro=E2=80=9D, =E2=80=9Cremount=E2=80=9D, =E2=80=9Cbin=
d=E2=80=9D), /etc/fstab handling, etc.

Guix System handles /etc/fstab differently and =E2=80=9Cdefaults=E2=80=9D m=
akes little
sense in our API (one can just use leave the default value of the
=E2=80=98options=E2=80=99 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=E2=80=99t improve clarity and future-proof-ness (what if a file syste=
m has
a =E2=80=9Cbind=E2=80=9D option, etc.).

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=E2=80=99t hard-code that directly in our API.

WDYT?

>>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001
>>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>>> 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" ke=
rnel
>>> argument, and use it when calling `mount-root-file-system'.  Update doc.
>>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-opt=
ions"
>>> 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=E2=80=99d rather avoid it for now.  Less code is better.  :-)

>> (Also, in hindsight, I think it was a mistake to call them
>> =E2=80=98--something=E2=80=99.  Following the common naming convention, =
we should rather
>> call these options =E2=80=98gnu.something=E2=80=99.)
>
> Is this convention detailed somewhere?  I haven't found it in 'Standards'.

It=E2=80=99s a convention of the Linux kernel, I don=E2=80=99t know if it=
=E2=80=99s documented.

That=E2=80=99s it!

Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 24 Feb 2020 14:23:29 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Feb 24 09:23:29 2020
Received: from localhost ([127.0.0.1]:53035 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j6Edr-0003Ls-R4
	for submit <at> debbugs.gnu.org; Mon, 24 Feb 2020 09:23:29 -0500
Received: from mail-qk1-f195.google.com ([209.85.222.195]:42740)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j6Edp-0003Lg-WC
 for 37305 <at> debbugs.gnu.org; Mon, 24 Feb 2020 09:23:27 -0500
Received: by mail-qk1-f195.google.com with SMTP id o28so8774398qkj.9
 for <37305 <at> debbugs.gnu.org>; Mon, 24 Feb 2020 06:23:25 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=c2YhjAr3Zg+I1feJCErjl/B2L/DpGXirBqF9bs8ktJo=;
 b=DwYoHjmde1AOhb5MKv4QPUiZG7fiZlL73yOSHg6iqSZEpQMR9jc7b9CeZZ5gSRS1wc
 1aSMidafnxfZeCpvGtVN8j4k3Wk6GAN739UY2Pe4/V8BGzHt1mvXmuSWZ2IrvBSlCa7y
 JxWycYkvYetzBDBmmp9VYN1Y7QDtu6IeX0QfT6j9/hEjl2IZsjNDEImW1TOU4ByGqOPd
 0PhC8U8lw46doMRv0aUxzSwx2QLhyoQSZyLixKAkicDY9m5Z3VePS4KjwpjKzL2w7q30
 1kfiV3+UozkPvIoW7xDKTCxvENAP+/v2BiBBgsvTVdIqXygromZuIbK4bPul/HhJZZJu
 R+4w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=c2YhjAr3Zg+I1feJCErjl/B2L/DpGXirBqF9bs8ktJo=;
 b=ie6HS2Kakdo3THQOU91YrtrqvxO3LOCjPJU05+Neo5/zocK/twf7h1WtPT0qa9GoX3
 6N59klOcVEVUYCYgiqpFgPJ6SZ/KnKpd9byK3DZ6LercXrqOnglJdSFACOadA/5E6XQI
 rdxJ75fKxJoaXar6FHnWF8Y22Fv6oAnP64TjbdlAr/M+2lsboyM4WARVMjjAnnPagK+N
 X2fWa+TL0ZmmuKv2JC5IwO/S0tjyXqTpfeaUnPpRIuQH1hfBootbM2Z7msGgss6+sQ8H
 yZMTe5/2p8S+JF+R7WTF5ObNwLlAcxBZcnROn/Rlq3N8EEP21KJ63kN6IqLk817KcZnj
 aX9w==
X-Gm-Message-State: APjAAAXKFp7HRYg7tH3mk/yYr1xc1OJGT3TL0fEaBtzaws15NTb2yLIG
 DPvecG10qknYj19yAW9aYotsVqfq
X-Google-Smtp-Source: APXvYqymqUYX5xCn9sTkNQLipKbiENNMO7mFoROwEuUQqV4X03R+CbwKG+oI3zbD94oQZbXfAfmeAA==
X-Received: by 2002:a37:e47:: with SMTP id 68mr25770358qko.17.1582554200434;
 Mon, 24 Feb 2020 06:23:20 -0800 (PST)
Received: from raisin ([2607:fad8:4:6:235e:8579:8464:aacc])
 by smtp.gmail.com with ESMTPSA id z21sm5946666qka.122.2020.02.24.06.23.19
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Mon, 24 Feb 2020 06:23:19 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] [PATCH V3] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN>
Date: Mon, 24 Feb 2020 09:23:18 -0500
In-Reply-To: <8736bdf5il.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Fri, 14 Feb 2020 18:22:26 +0100")
Message-ID: <871rqkf4ix.fsf_-_@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="==-=-=";
 micalg=pgp-sha256; protocol="application/pgp-signature"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: text/plain

I've added a `normalize-file' procedure to the attached patch, which
simplify producing correct store references in the GRUB configuration
file generated.

This fixed the GRUB video mode issues reported in a another issue.

Thanks!

Maxim

--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-bootloader-grub-Allow-booting-from-a-Btrfs-subvolume.patch
Content-Transfer-Encoding: quoted-printable

From=201c0aafd5d0e013387a8f9bede3c42622b85957c5 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 14 Jul 2019 20:50:23 +0900
Subject: [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.  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 w=
ith
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.  Document the new `properties' field of the `<file-system>'
record.
* gnu/tests/install.scm: Add test "btrfs-root-on-subvolume-os".
=2D--
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index d6bfbd7b55..f0956f965a 100644
=2D-- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and
=20
 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
=20
@@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems.  This r=
equires the
 @code{fuse.ko} kernel module to be loaded.
 @end defvr
=20
+@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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume directory)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 root-snapshots          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 root-current        (subvolume)
+        =E2=94=9C=E2=94=80=E2=94=80 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
=20
diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scm
index 58cc3f3932..0a50374bd9 100644
=2D-- a/gnu/bootloader/depthcharge.scm
+++ b/gnu/bootloader/depthcharge.scm
@@ -82,7 +82,8 @@
 (define* (depthcharge-configuration-file config entries
                                          #:key
                                          (system (%current-system))
=2D                                         (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.scm
index 5b4dd84965..6b5ff298e7 100644
=2D-- a/gnu/bootloader/extlinux.scm
+++ b/gnu/bootloader/extlinux.scm
@@ -28,7 +28,8 @@
 (define* (extlinux-configuration-file config entries
                                       #:key
                                       (system (%current-system))
=2D                                      (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-F=
S, a
 <file-system> object.  OLD-ENTRIES is taken to be a list of menu entries
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index b99f5fa4f4..99cb42c4a2 100644
=2D-- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -4,6 +4,7 @@
 ;;; Copyright =C2=A9 2017 Leo Famulari <leo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Jan (janneke) Nieuwenhuizen <janneke@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -61,18 +62,29 @@
 ;;;
 ;;; Code:
=20
=2D(define (strip-mount-point mount-point file)
=2D  "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable object
=2Ddenoting a file name."
=2D  (match mount-point
=2D    ((? string? mount-point)
=2D     (if (string=3D? mount-point "/")
=2D         file
=2D         #~(let ((file #$file))
=2D             (if (string-prefix? #$mount-point file)
=2D                 (substring #$file #$(string-length mount-point))
=2D                 file))))
=2D    (#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=3D? 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 fil=
e)
+    (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)))
+
+
=20
 (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))))
=20
 (define* (eye-candy config store-device store-mount-point
+                    btrfs-store-subvolume-file-name
                     #:key system port)
=2D  "Return a gexp that writes to PORT (a port-valued gexp) the
=2D'grub.cfg' part concerned with graphics mode, background images, colors,=
 and
=2Dall that.  STORE-DEVICE designates the device holding the store, and
=2DSTORE-MOUNT-POINT is its mount point; these are used to determine where =
the
=2Dbackground image and fonts must be searched for.  SYSTEM must be the tar=
get
=2Dsystem string---e.g., \"x86_64-linux\"."
+  "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' p=
art
+concerned with graphics mode, background images, colors, and all that.
+STORE-DEVICE designates the device holding the store, and STORE-MOUNT-POIN=
T 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, where=
as
     ;; most other modern architectures have no other mode and therefore do=
n't
@@ -194,11 +208,14 @@ fi~%" #$font-file)
                      (symbol->string (assoc-ref colors 'bg)))))
=20
   (define font-file
=2D    (strip-mount-point store-mount-point
=2D                       (file-append grub "/share/grub/unicode.pf2")))
+    (normalize-file (file-append grub "/share/grub/unicode.pf2")
+                    store-mount-point
+                    btrfs-store-subvolume-file-name))
=20
   (define image
=2D    (grub-background-image config))
+    (normalize-file (grub-background-image config)
+                    store-mount-point
+                    btrfs-store-subvolume-file-name))
=20
   (and image
        #~(format #$port "
@@ -223,7 +240,7 @@ fi~%"
                  #$(setup-gfxterm config font-file)
                  #$(grub-setup-io config)
=20
=2D                 #$(strip-mount-point store-mount-point image)
+                 #$image
                  #$(theme-colors grub-theme-color-normal)
                  #$(theme-colors grub-theme-color-highlight))))
=20
@@ -327,52 +344,66 @@ code."
 (define* (grub-configuration-file config entries
                                   #:key
                                   (system (%current-system))
=2D                                  (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
=2DSTORE-FS, a <file-system> object.  OLD-ENTRIES is taken to be a list of =
menu
=2Dentries 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)
=2D    (let ((device (menu-entry-device entry))
=2D          (device-mount-point (menu-entry-device-mount-point entry))
=2D          (label (menu-entry-label entry))
=2D          (kernel (menu-entry-linux entry))
=2D          (arguments (menu-entry-linux-arguments entry))
=2D          (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 poin=
t.
       ;; 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.
=2D      (let ((kernel  (strip-mount-point device-mount-point kernel))
=2D            (initrd  (strip-mount-point device-mount-point initrd)))
=2D        #~(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
 }~%"
=2D                  #$label
=2D                  #$(grub-root-search device kernel)
=2D                  #$kernel (string-join (list #$@arguments))
=2D                  #$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))
=20
   (define keyboard-layout-config
=2D    (let ((layout (bootloader-configuration-keyboard-layout config))
=2D          (grub   (bootloader-package
=2D                   (bootloader-configuration-bootloader config))))
=2D      #~(let ((keymap #$(and layout
=2D                             (keyboard-layout-file layout #:grub grub))))
=2D          (when keymap
=2D            (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
=2Dkeymap ~a~%" keymap)))))
+keymap ~a~%" #$keymap))))
=20
   (define builder
     #~(call-with-output-file #$output
diff --git a/gnu/system.scm b/gnu/system.scm
index 2e6d03272d..59c3526098 100644
=2D-- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Meiyo Peng <meiyo.peng@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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."
=2D  (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)))
=20
     (generate-config-file bootloader-conf (list entry)
=2D                          #:old-entries old-entries)))
+                          #:old-entries old-entries
+                          #:btrfs-subvolume-file-name
+			  (btrfs-store-subvolume-file-name file-systems))))
=20
 (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.scm
index 4f0c5ad99e..7b78731524 100644
=2D-- 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
=20
             file-system-type-predicate
             file-system-independent-mount-option?
+            btrfs-subvolume?
+            btrfs-store-subvolume-file-name
=20
             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 pai=
rs
+                    (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))))
=20
+(define (btrfs-subvolume? fs)
+  "Predicate to check if FS, a file-system object, is a Btrfs subvolume."
+  (and-let* ((btrfs-file-system? (string=3D "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=3D 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=3D> 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=3D> 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: Sy=
mbol
+              ;; 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 here
diff --git a/gnu/tests/install.scm b/gnu/tests/install.scm
index d475bda2c7..82e2b46e3e 100644
=2D-- 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))
=20
 ;;; 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")))))
=20
+
+;;;
+;;; 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=3DttyS0"))
+    (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=3D--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=3Dbtrfs-pool -o 'subvol=3Drootfs,compress=3Dzstd' /mnt
+mkdir /mnt/home
+mount LABEL=3Dbtrfs-pool -o 'subvol=3Dhomefs,compress=3Dzstd' /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.
=2D-=20
2.25.0


--=-=-=--

--==-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl5T3FYACgkQEmDkZILm
NWIFGw/9HAUn9ZQml2lUXmMGFGPKJJpvPKQIgKSxmOk8w/1SmTmKCCrEF10kCQsV
rrhz/rifZXI7M24zmGJX6N0yqdbbj3EdyKvqPoGANUtEfj2Pz3AFph3DLgFGMJ5D
Sj8O4xJVlQ1V6TAeSmtRXwZeOQ3n6yGFxypoeDmHRgVyT+MV/uC3bYV64s1kLgWM
petBRUAvoipU9q8Jw/uXvySMUTbZXr7+MPYWQcC67JxjhU2SnrJhmJxCb7Wi8kQm
NFiWkOv9Ou1x2a552NjLyMW1dqsJJDbHfepdv8MfVo+cYAukB8FzdfzMZT1V4WkL
vCKiSNdRZlF8+jp61F1UC2hD1DVaMkDofd1yFlzboIE6q+IVILzDzDm4u0ThoAcg
5n6HAIDKRiQBc/5iXKlzQfABRSGaMlNxYgVUnMqkONGFp6JyAAgOpwiZTjmHjxIz
5nxzgikGSFyT5wNiTZcR6pBSiSGHuCTdYAdtpmoog0QWuhkv6K4TllgdURlp8vfO
QJZAQd+MsX58AE8U0UVBYb3MmY6pM7Y722J5Khpr9+OxLCuECF+83h/k0GmVazdf
h6aC9P4S+d8+/RbjwygASCC4ngJur4xWVLGJZlZoeIVEazYv1bTVlwjPzaLg2/f7
zZR++xezmszteLZ1M13JZpP4WCC8zkTPxATyhk+an14QTOlyAHQ=
=Op9E
-----END PGP SIGNATURE-----
--==-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 20 Feb 2020 09:55:20 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Feb 20 04:55:20 2020
Received: from localhost ([127.0.0.1]:43857 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j4iYB-0005Uz-TG
	for submit <at> debbugs.gnu.org; Thu, 20 Feb 2020 04:55:20 -0500
Received: from eggs.gnu.org ([209.51.188.92]:41015)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1j4iY9-0005Uk-Qq
 for 37305 <at> debbugs.gnu.org; Thu, 20 Feb 2020 04:55:18 -0500
Received: from fencepost.gnu.org ([2001:470:142:3::e]:56308)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1j4iY4-0007Og-KV; Thu, 20 Feb 2020 04:55:12 -0500
Received: from [2001:660:6102:320:e120:2c8f:8909:cdfe] (port=45970 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1j4iXz-000667-Jf; Thu, 20 Feb 2020 04:55:08 -0500
From: =?utf-8?Q?Ludovic_Court=C3=A8s?= <ludo@HIDDEN>
To: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Subject: Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
References: <875zg2xtsb.fsf@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 2 =?utf-8?Q?Vent=C3=B4se?= an 228 de la =?utf-8?Q?R?=
 =?utf-8?Q?=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Thu, 20 Feb 2020 10:55:05 +0100
In-Reply-To: <875zg2xtsb.fsf@HIDDEN> (Maxim Cournoyer's message of "Tue, 18
 Feb 2020 21:52:24 -0500 (15 hours, 38 minutes, 5 seconds ago)")
Message-ID: <87lfoxbn2e.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hi Maxim,

Maxim Cournoyer <maxim.cournoyer@HIDDEN> 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 =E2=80=98raise=E2=80=99 with =E2=80=98&message=E2=80=99 and =
=E2=80=98&fix-hint=E2=80=99 conditions.
>
> I tried this, but importing (guix utils) to acces &fix-hint caused the in=
it
> RAM disk to fail mysteriously:

Oh, my bad.  We should move =E2=80=98&fix-hint=E2=80=99 to (guix diagnostic=
s)
eventually.

In the meantime, I=E2=80=99d say just raise a =E2=80=98&message=E2=80=99 an=
d leave the hint as a
comment (it=E2=80=99s not supposed to be a user-facing interface).  Or mayb=
e you
could define a specific error condition type for this?

Thanks,
Ludo=E2=80=99.

PS: I=E2=80=99ll comment on the other bits ASAP!




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 19 Feb 2020 19:27:00 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Feb 19 14:27:00 2020
Received: from localhost ([127.0.0.1]:43406 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j4Uzo-0001Tq-Dp
	for submit <at> debbugs.gnu.org; Wed, 19 Feb 2020 14:27:00 -0500
Received: from mail-qk1-f193.google.com ([209.85.222.193]:43749)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j4Uzk-0001Ta-78
 for 37305 <at> debbugs.gnu.org; Wed, 19 Feb 2020 14:26:54 -0500
Received: by mail-qk1-f193.google.com with SMTP id p7so1213262qkh.10
 for <37305 <at> debbugs.gnu.org>; Wed, 19 Feb 2020 11:26:52 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:date:message-id:mime-version;
 bh=cxxjANQgd9NaxluMBhfzeFDnnXRQdVwCLNRTn5cDblw=;
 b=Xp8GtycLudlgeWM5be5OJ7tsGIqGfvw2LjI/WbZ6xV3HWfVXfidRYxCWUVhxtNIJkR
 HuHcYmYXFZyqo6DVZTLqj8bUrh5FTotUhnVo/zNLcTAgPQ8RKc2FN3+m9UCcGJQkhseF
 ZY8gDUMbSlIViiHFhw0/2lDx8Kvnckvkp6MHtaw95Iw9j6rnSgZ2TYZsZTxgxBqUUJc0
 6sLDjCnqWU2EiikjHE+O4SRTtadnFri7LkuNv2QxLompNXJBfw4jfe2FFnrNpqwFAv49
 Lc6WF/y50fLV5AkRwdlbXfVCerFrgk7N2xVUlpJUB78l6PmgCJglwLc+4pjPCLqLGoMk
 LJhA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version;
 bh=cxxjANQgd9NaxluMBhfzeFDnnXRQdVwCLNRTn5cDblw=;
 b=MSSywWHaEtKuBn+bxGfuy535yfFp4E4CUR5pQ9x0YZku3QEJzDPZZUbQU0vGTZyEO/
 CCbryRPLZHLcu11yTKHk+O30HdJ+Yka1P+20ZiyiSJL+wC4dSwZBKXmIcWXWGagbSbRF
 24gUwmLCaquG4o8SxxoqCCRN/7LaJAckO8A/vtyaJQ/1GvJshfXVUw/qPw2u7WxqGV4/
 1xHTKJaD+wXNZksr9pTQ1ysmRuN1th1DpsfOLw2E/VTYW4JEAV+67rgzSNe+zJVC1uH8
 LVRnMuOMw/xIhRd92UH9xPXTAvGMCdBTnQJIqa9E5Wr5ZNepWcEBqVMnRWrg+kqeCu0r
 rorQ==
X-Gm-Message-State: APjAAAUhvKL0lSPTTCW9H0u2t1ikQQQPaXMN5MTFiV8AwPwmO4jw1jZ/
 mwI79K7MqXlUnWGEZKKHPwCZF2VO7OU=
X-Google-Smtp-Source: APXvYqyKOpwnKjt0IYDzrWzi15+LoHsoizpEbA0+MmSeLcvGgIBk65ZeQafjn7uvMM+FjbG7UMNVgQ==
X-Received: by 2002:a37:8683:: with SMTP id
 i125mr25393222qkd.491.1582140406248; 
 Wed, 19 Feb 2020 11:26:46 -0800 (PST)
Received: from raisin ([2607:fad8:4:6:235e:8579:8464:aacc])
 by smtp.gmail.com with ESMTPSA id k58sm526415qtb.60.2020.02.19.11.26.45
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 19 Feb 2020 11:26:45 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] Allow booting from a Btrfs subvolume [review part 2]
Date: Tue, 18 Feb 2020 21:52:24 -0500 (15 hours, 38 minutes, 5 seconds ago)
Message-ID: <875zg2xtsb.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.8 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.2 (/)

--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hello Ludovic,

Here comes part 2!

Ludovic Court=C3=A8s <ludo@HIDDEN> writes:

>> From 6cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> Date: Sun, 14 Jul 2019 20:50:23 +0900
>> Subject: [PATCH 8/9] bootloader: grub: Allow booting from a Btrfs subvol=
ume.
>>
>> * gnu/bootloader/grub.scm (grub-configuration-file) [btrfs-subvolume-pat=
h]:
>> 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 u=
se 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-SUBVOLUM=
E-PATH
>> +may be used to specify on which subvolume a Btrfs root file system resi=
des."
>
> (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.

> It=E2=80=99s 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=E2=80=99t have a better idea, but it=E2=80=99d be great if Btrfs su=
pport 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 or
other bootloaders than GRUB.  All I know is that for GRUB they need to
handle 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't
exist in traditional file systems like EXT4.  I think ZFS must have
something similar, though.

>> +  (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=3D "btrfs" (file-system-type f=
s)))
>> +             (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 =E2=80=98raise=E2=80=99 with =E2=80=98&message=E2=80=99 and =
=E2=80=98&fix-hint=E2=80=99 conditions.

I tried this, but importing (guix utils) to acces &fix-hint caused the init
RAM disk to fail mysteriously:

--8<---------------cut here---------------start------------->8---
[    0.614503] Run /init as init process
GC Warning: pthread_getattr_np or pthread_attr_getstack failed for main thr=
ead
GC Warning: Couldn't read /proc/stat
Backtrace:
In ice-9/boot-9.scm:
   222:29 19 (map1 (((ice-9 match)) ((rnrs bytevectors)) ((srfi=20
   222:29 18 (map1 (((rnrs bytevectors)) ((srfi srfi-1)) ((srfi=20
   222:29 17 (map1 (((srfi srfi-1)) ((srfi srfi-2)) ((srfi #)) (#)=20
   222:29 16 (map1 (((srfi srfi-2)) ((srfi srfi-9)) ((srfi #)) (#)=20
   222:29 15 (map1 (((srfi srfi-9)) ((srfi srfi-26)) ((srfi #)) (#)=20
   222:29 14 (map1 (((srfi srfi-26)) ((srfi srfi-35)) ((srfi # #))=20
   222:29 13 (map1 (((srfi srfi-35)) ((srfi srfi-9 gnu)) ((guix=20
))[    0.657578] random: fast init done
   222:29 12 (map1 (((srfi srfi-9 gnu)) ((guix records)) ((guix=20
   222:29 11 (map1 (((guix records)) ((guix utils)) ((gnu system=20
))))
   222:17 10 (map1 (((guix utils)) ((gnu system uuid))))
  2800:17  9 (resolve-interface (guix utils) #:select _ #:hide _ # _=20
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 7f455b8fd
In 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=
=3D0x00000100
[    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: 000000=
00000000e7
[    0.707808] RAX: ffffffffffffffda RBX: 00000000007c51f0 RCX: 00000000005=
df9c6
[    0.708643] RDX: 0000000000000001 RSI: 000000000000003c RDI: 00000000000=
00001
[    0.709482] RBP: 0000000000000001 R08: 00000000000000e7 R09: fffffffffff=
fffb0
[    0.710328] R10: 0000000000436340 R11: 0000000000000246 R12: 00000000007=
c51f0
[    0.711166] R13: 0000000000000001 R14: 0000000000000000 R15: 00000000000=
00003
[    0.712026] Kernel Offset: 0x13000000 from 0xffffffff81000000 (relocatio=
n range: 0xffffffff80000000-0xffffffffbfffffff)
[    0.713288] Rebooting in 1 seconds..
file-size: /gnu/store/zfi66vny0h10d180xajgm4pq2vnvmc2z-nss-certs-3.49.1/etc=
/ssl/certs/NetLock_Arany_=3DClass_Gold=3D_F??tan??s??tv??ny:2.6.73.65.44.22=
8.0.16.pem: No such file or directory
file-size: /gnu/store/04xpkgf9zlhcngyr6gnhl4rb8g6v6i1i-profile/etc/ssl/cert=
s/NetLock_Arany_=3DClass_Gold=3D_F??tan??s??tv??ny:2.6.73.65.44.228.0.16.pe=
m: No such file or directory
--8<---------------cut here---------------end--------------->8---

The exception I had refactored to use with &fix-hint looked like:

--8<---------------cut here---------------start------------->8---
(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 system
option."))))
--8<---------------cut here---------------end--------------->8---

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

--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-gnu-tests-Reduce-the-time-required-to-run-the-system.patch
Content-Transfer-Encoding: quoted-printable

From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 17 Nov 2019 06:01:00 +0900
Subject: [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 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 procedu=
re.
* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when
GUIX_DEV_HACKS is defined.
---
 build-aux/run-system-tests.scm      | 11 ++++-
 gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scm
index 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 =C2=A9 2016, 2018, 2019 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -58,8 +59,16 @@ instance."
   ;; of tests to run in the usual way:
   ;;
   ;;   make check-system TESTS=3Dinstalled-os
+
+  ;; When the GUIX_DEV_HACKS environment variable is defined, override the
+  ;; package returned by `current-guix' with a flavor that saves recompili=
ng
+  ;; Guix from scratch and reuse the developer's checkout binaries.  The
+  ;; override "builds" about 20 times faster than the regular `current-gui=
x'
+  ;; 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-man=
agement.scm
index 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 'so=
urce'."
                                 #:recursive? #t
                                 #:select? (force select?))))))))
=20
+(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 RE=
PL.
+         ;; 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 n=
icer
+             ;; 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 t=
o 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 t=
he
+                 ;; 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 profil=
e,
+                         ;; we could make this package inherit from the gu=
ix
+                         ;; 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.
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-linux-boot-Ensure-volatile-root-is-mounted-read-only.patch

From c6e00c0eb8b2ed0c758e9c1be28c6e93f4795a64 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 12:57:29 -0500
Subject: [PATCH 2/8] 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.
---
 gnu/build/linux-boot.scm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0003-file-systems-Add-a-file-system-device-string-procedu.patch

From c367fc7efeb8ff15c22a98f32098bbcdbf1457b6 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 23:56:45 -0500
Subject: [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(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index 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.scm
index 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.scm
index 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.scm
index 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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0004-linux-boot-Refactor-boot-system.patch

From 7593b5dfeb180acf51dd7f586f31b1c8c671f1fa Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:00:06 -0500
Subject: [PATCH 4/8] 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 precedence over the device field string
representation of the root file system.
* doc/guix.texi (Initial RAM Disk): Document that "--root" can be left
unspecified.
---
 doc/guix.texi            |  7 +++--
 gnu/build/linux-boot.scm | 66 +++++++++++++++++++++-------------------
 2 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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 to
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0005-file-systems-Represent-the-file-system-options-as-an.patch
Content-Transfer-Encoding: quoted-printable

From a9b65ec0b4aa80c99c544aad41ec19ab64b295b0 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Wed, 25 Sep 2019 22:43:41 +0900
Subject: [PATCH 5/8] 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.
---
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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.
=20
-@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 f=
or
-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.
=20
 @item @code{mount?} (default: @code{#t})
 This value indicates whether to automatically mount the file system when
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index 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))
=20
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 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 termin=
ated with
=20
 (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=3D"
-                                   (file-system-label->string label)))
-                   ((? uuid? uuid)
-                    (string-append "UUID=3D" (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=3D"
+                                     (file-system-label->string label)))
+                     ((? uuid? uuid)
+                      (string-append "UUID=3D" (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 becau=
se we
+                   ;; don't have anything sensible to put in there.
+                   )))
=20
 (define (file-systems->fstab file-systems)
   "Return a @file{/etc} entry for an @file{fstab} describing
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index 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 =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
+(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 ((=3Dindex (string-index param #\=3D)))
+	       (if =3Dindex
+		   (cons (string-take param =3Dindex)
+			 (string-drop param (1+ =3Dindex)))
+		   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 "=3D" 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 t=
he
 store--e.g., if FS is the root file system."
diff --git a/tests/file-systems.scm b/tests/file-systems.scm
index 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 =C2=A9 2015, 2017 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -64,4 +65,27 @@
           (_ #f))
         (source-module-closure '((gnu system file-systems)))))
=20
+(define %fs-with-deprecated-options-string
+  (file-system
+    (device (file-system-label "btrfs-pool"))
+    (mount-point "/home")
+    (type "btrfs")
+    (options "autodefrag,subvol=3Dhome,compress=3Dlzo")))
+
+(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=3Droot,compress=3Dlzo"
+  (file-system-options->string
+   (file-system-options %fs)))
+
 (test-end)
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0006-linux-boot-Honor-the-root-options-kernel-argument.patch
Content-Transfer-Encoding: quoted-printable

From 9e988968566f004f887080b02712043520d9327e Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:14:36 -0500
Subject: [PATCH 6/8] 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.
---
 doc/guix.texi            | 10 ++++++++++
 gnu/build/linux-boot.scm | 16 +++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5d526b1aee..d6bfbd7b55 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @comm=
and{modprobe} command
 must be a comma-separated list of module names---e.g.,
 @code{usbkbd,9pnet}.
=20
+@item --root-options=3D@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.  Our
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index c3229fa292..063daa4ca4 100644
--- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -2,6 +2,7 @@
 ;;; Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Guillaume Le Vaillant <glv@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE wit=
h 'loadkeys' (if
 KEYMAP-FILE is true), then setting up QEMU guest networking if
 QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file syste=
ms
 specified in MOUNTS, and finally booting into the new root if any.  The in=
itrd
-supports kernel command-line options '--load', '--root', and '--repl'.
+supports kernel command-line options '--load', '--root', '--root-options' =
and
+'--repl'.
=20
 Mount the root file system, specified by the '--root' command-line argumen=
t,
 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 ro=
ot
@@ -500,10 +503,13 @@ upon error."
              (root-device (or (and=3D> (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 o=
f 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)))))
=20
         (when (member "--repl" args)
           (start-repl))
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0007-linux-boot-Filter-out-file-system-independent-option.patch

From 2cc5b27defbd2b9fd75c70482ac2ecf045b880e3 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:27:19 -0500
Subject: [PATCH 7/8] 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.
---
 gnu/build/linux-boot.scm    |  3 ++-
 gnu/system/file-systems.scm | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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 root
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index 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


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0008-bootloader-grub-Allow-booting-from-a-Btrfs-subvolume.patch
Content-Transfer-Encoding: quoted-printable

From e73112a8a476f89a4728a865576dab7e8042bb47 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 14 Jul 2019 20:50:23 +0900
Subject: [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 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.  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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index d6bfbd7b55..f0956f965a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and
=20
 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
=20
@@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems.  This r=
equires the
 @code{fuse.ko} kernel module to be loaded.
 @end defvr
=20
+@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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume directory)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 root-snapshots          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 root-current        (subvolume)
+        =E2=94=9C=E2=94=80=E2=94=80 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
=20
diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scm
index 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.scm
index 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-F=
S, a
 <file-system> object.  OLD-ENTRIES is taken to be a list of menu entries
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index b99f5fa4f4..3ec960abd8 100644
--- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -4,6 +4,7 @@
 ;;; Copyright =C2=A9 2017 Leo Famulari <leo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Jan (janneke) Nieuwenhuizen <janneke@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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 me=
nu
-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 #$kern=
el*)
+                       kernel*))
+           (initrd (if btrfs-subvolume-file-name
+                       #~(string-append #$btrfs-subvolume-file-name #$init=
rd*)
+                       initrd*)))
       ;; Here DEVICE is the store and DEVICE-MOUNT-POINT is its mount poin=
t.
       ;; 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.scm
index 2e6d03272d..59c3526098 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Meiyo Peng <meiyo.peng@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
     (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))))
=20
 (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.scm
index 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
=20
             file-system-type-predicate
             file-system-independent-mount-option?
+            btrfs-subvolume?
+            btrfs-store-subvolume-file-name
=20
             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 pai=
rs
+                    (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))))
=20
+(define (btrfs-subvolume? fs)
+  "Predicate to check if FS, a file-system object, is a Btrfs subvolume."
+  (and-let* ((btrfs-file-system? (string=3D "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=3D 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=3D> 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=3D> 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: Sy=
mbol
+              ;; 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 here
diff --git a/gnu/tests/install.scm b/gnu/tests/install.scm
index 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))
=20
 ;;; 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")))))
=20
+
+;;;
+;;; 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=3DttyS0"))
+    (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=3D--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=3Dbtrfs-pool -o 'subvol=3Drootfs,compress=3Dzstd' /mnt
+mkdir /mnt/home
+mount LABEL=3Dbtrfs-pool -o 'subvol=3Dhomefs,compress=3Dzstd' /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.
--=20
2.25.0


--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 18 Feb 2020 21:27:34 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Feb 18 16:27:34 2020
Received: from localhost ([127.0.0.1]:41364 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j4AP0-0004sF-Az
	for submit <at> debbugs.gnu.org; Tue, 18 Feb 2020 16:27:34 -0500
Received: from mail-qk1-f176.google.com ([209.85.222.176]:33407)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j4AOz-0004s2-0b
 for 37305 <at> debbugs.gnu.org; Tue, 18 Feb 2020 16:27:33 -0500
Received: by mail-qk1-f176.google.com with SMTP id h4so21090942qkm.0
 for <37305 <at> debbugs.gnu.org>; Tue, 18 Feb 2020 13:27:32 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=FxdB2xoksPWA1Tup1a0PeXl5VLnz6ADQeUE9g9mJ7lU=;
 b=AeePYfwp9B1ADa218Kw+nnOJus8MR8pSeB7A9JxWCqqEOmWoxte2UVv8ciRk/gudQL
 9xrTw1GEAgXwDj5cG9BhyKCXaO5TFVLA1GoPNHuSo+7+Jwk/zTqLHGAcYdoI0xMG8KMi
 gV0jOgpHJCyUM+dMwlWV2L1XQFHifqq1J8L89MXcguocf1CRNUCuv3S09HSVvwVjSl1W
 SjBSsYv+6vHRVTSJPeNfI1c/QLnyzdEXrXdFXSPH13gzo1+EEGeU5c41OIJXsUdOq92S
 PNTUncHsJHYPivb3K0yOjf62QnpyelaKtWvIl6C0k4AOJxRkgwUuBwGftUbnbpaU96LJ
 v9PQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=FxdB2xoksPWA1Tup1a0PeXl5VLnz6ADQeUE9g9mJ7lU=;
 b=QE8ICWa3wn3/0wiig65K/4Iwe7qRc9modzTzGVaOmjev8MGZjSAy+cAJXwFvdhUDPF
 mFs+Tz7tJo4WW3FbVW9TWG4JMqgDv6e7E1rrm7Bh/TmiCHx2LVSXyxHfxiqvqAU68w8X
 L7KC5Wk8DjkzuPsSXL1g7TyShaI5aQnyO/PX0hrSPkrOHkm1UXUOw6RQs7RKi/Uqmyik
 2Q6k7OsdpbLhRP5xMlzxEa5PCHPIO6TgiKI8LcLNMVpDLFxqadrcpr42EIm76NGpLqWU
 iOeYHnGqnX9fpo8+bbYUG4FzAok02Kd0MoUVI02fTwCC/v9BMBPVPD6iwH+OL3ZLZC/a
 OFlQ==
X-Gm-Message-State: APjAAAUmNgS9F1/DoEBkZIXtlVPN/gebNiidwva4nNXmCkoK85d4k4v0
 +XWsvyUK/rfPbNkiLGdKKteOZGK6rpQ=
X-Google-Smtp-Source: APXvYqzr8lqtO+WLcqdqMF+/VPaDigu5+9UHDhUXaK04vcjiQqD3GYeQ/YopntI2cWmaSXwRH+Scvg==
X-Received: by 2002:a37:9d03:: with SMTP id g3mr20813714qke.39.1582061246980; 
 Tue, 18 Feb 2020 13:27:26 -0800 (PST)
Received: from raisin ([2607:fad8:4:6:235e:8579:8464:aacc])
 by smtp.gmail.com with ESMTPSA id b12sm2504920qkl.0.2020.02.18.13.27.25
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 18 Feb 2020 13:27:26 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: Making system installation tests faster
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
 <8736ba3hxo.fsf_-_@HIDDEN> <87sgj8j9sf.fsf@HIDDEN>
Date: Tue, 18 Feb 2020 16:27:25 -0500
In-Reply-To: <87sgj8j9sf.fsf@HIDDEN> (Maxim Cournoyer's message of "Tue, 18
 Feb 2020 08:37:52 -0500")
Message-ID: <87sgj7wpqa.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

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:
--8<---------------cut here---------------start------------->8---
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))))'
--8<---------------cut here---------------end--------------->8---

current-guix (old fashionned):
--8<---------------cut here---------------start------------->8---
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))))'
--8<---------------cut here---------------end--------------->8---

new current-guix (guix self):
--8<---------------cut here---------------start------------->8---
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)))))))))'
--8<---------------cut here---------------end--------------->8---

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 the
previous one used, to give an idea of the time someone would have to
wait just to build the operating system to test.  An x200 would be even
slightly slower that than.

One of the things that seems costly is rebuilding the documentation.

Maxim




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 18 Feb 2020 13:38:07 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue Feb 18 08:38:07 2020
Received: from localhost ([127.0.0.1]:39666 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j434f-0007zX-U0
	for submit <at> debbugs.gnu.org; Tue, 18 Feb 2020 08:38:07 -0500
Received: from mail-qk1-f179.google.com ([209.85.222.179]:43843)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j434c-0007z1-2S
 for 37305 <at> debbugs.gnu.org; Tue, 18 Feb 2020 08:38:03 -0500
Received: by mail-qk1-f179.google.com with SMTP id p7so19462359qkh.10
 for <37305 <at> debbugs.gnu.org>; Tue, 18 Feb 2020 05:38:02 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version:content-transfer-encoding;
 bh=qrWijrn4qXg4VL3lAe2l4GJLvK84LClgqZuz78Ath68=;
 b=AMoJJzIsETXb6VcbdvV/WW+4RE6gUNYnZQXzd9UWkRvquEdB7lZYFMfXhkC07E5PU5
 lYkHCtX0Xesbd94q8LqDxCVn1hhO+cmfSyOShFYgY1k8FTava1ll47rF8QFhYYABAGyV
 bbiG2AEht0PUCG1d0gjkxQx0kQahiQbbPouDdUUJjWga+eflkqYGcH0VA6dyLVUh5x7V
 n5qGpW8ZDmhMJ2Rs6tJToIGsrvIK4USvo9u+e5wt0XdAXm7VLKpRDMt86Ja2eAe58o+H
 bU1rtEg+ZU65aIRppDRv7fGbTeGSq8Dcv69nZgNqwVu41gTQtMd44hzM88PC+PG+NPHN
 6SQA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version:content-transfer-encoding;
 bh=qrWijrn4qXg4VL3lAe2l4GJLvK84LClgqZuz78Ath68=;
 b=SpNR2tjHiJAw4S0QDFGH/eH0gpYtId73yDW9kOTrDZZKUEWaOr8E8a4smS4pP7PlzC
 YFTZ/ruxMeFFw/TVWMAaNSdCp1womUhcI9u5XGLwWWh9Kj0t8feHHhSeREFzFYy6NAV/
 gQpISQLuKCCoWCqFIj4SYmLYN5bJ1/h2k5uCG9r6vC90MlVOcnvDcqjGv30s7tTY6pm3
 nuNsipczxyESyjSDBn4HXwdXdhSetOk+tDfiosihBJ9KWYiNJ10FUqFtYt4t9qJ4V4lv
 wU/g/dF3jAujZ1xWWHr2Hw7/LJruGEEg9ivVYJ6hwGLYQxQwLTiToyitL1MMqGq78eFK
 sCHA==
X-Gm-Message-State: APjAAAWSw0s+w80IcdU5hYvKfteCSTx7Sv2LRVW+jjXSmignuOmaNGOX
 5Kt/BCIG6d0i86N70UFvgD7xKBEr
X-Google-Smtp-Source: APXvYqyyD/+0MhgSOKpHB03BttFB/waxYB9PppThXHQPJbTyszigfvlAyFzHkoXTilW2BfvaGqZOcQ==
X-Received: by 2002:a05:620a:12da:: with SMTP id
 e26mr1592450qkl.214.1582033075534; 
 Tue, 18 Feb 2020 05:37:55 -0800 (PST)
Received: from apteryx (dsl-155-216.b2b2c.ca. [66.158.155.216])
 by smtp.gmail.com with ESMTPSA id w41sm1844002qtj.49.2020.02.18.05.37.53
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 18 Feb 2020 05:37:54 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: Making system installation tests faster
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
 <8736ba3hxo.fsf_-_@HIDDEN>
Date: Tue, 18 Feb 2020 08:37:52 -0500
In-Reply-To: <8736ba3hxo.fsf_-_@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\?\=
 \=\?utf-8\?Q\?\=22's\?\= message of "Sun,
 16 Feb 2020 12:11:47 +0100")
Message-ID: <87sgj8j9sf.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.5 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.5 (/)

Hi Ludovic,

Ludovic Court=C3=A8s <ludo@HIDDEN> writes:

> Hi Maxim,
>
> Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:
>
>> Ludovic Court=C3=A8s <ludo@HIDDEN> writes:
>>
>>> Hi Maxim!
>>>
>>> Great to see Btrfs support improving; many people will love that!
>>>
>>> Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:
>>>
>>>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
>>>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>>>> Date: Sun, 17 Nov 2019 06:01:00 +0900
>>>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the s=
ystem
>>>>  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.  Th=
is
>>>> 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 pr=
ocedure.
>>>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it,=
 when
>>>> GUIX_DEV_HACKS is defined.
>>>
>>> I understand the need, but I=E2=80=99d really like to avoid that; it=E2=
=80=99s too
>>> fragile IMO.
>>>
>>> But I have good news!  First, commit
>>> 887fd835a7c90f720d36a211478012547feaead0 really improved things by
>>> avoiding the full =E2=80=98guix=E2=80=99 package rebuild (and we=E2=80=
=99re 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=E2=80=99s still room for improvement, but I=E2=80=99d 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=E2=80=99s grabbing files from the working tree, with heuristics to min=
imize
> the changes in incorporating files that shouldn=E2=80=99t be there; I thi=
nk it=E2=80=99s
> fragile.  :-)

Fragile or not, it's helped me getting this change tested much faster
than I could have had otherwise, which is the point of that hack :-).
Benchmarks below.

> 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 implemen=
tation 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=E2=80=99d have to maintain that in the meantime and =
deal
> with any =E2=80=9Csurprising=E2=80=9D effects it has for those using it.

Yeah.

> FWIW, when testing (gnu installer tests), I only have to rebuild
> =E2=80=9Cguix-system-tests.drv=E2=80=9D, which is fast.  And in fact, I c=
an also not
> rebuild anything by doing:
>
>   (define operating-system-with-current-guix identity)
>
> because in this particular case, I know it=E2=80=99s not necessary to hav=
e the
> current =E2=80=98guix=E2=80=99 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 GRUB
configuration file at 'guix system init' time.

Below are some analysis of the derivations triggered in different scenarios.

Without the hack:

--8<---------------cut here---------------start------------->8---
./pre-inst-env make check-system TESTS=3Dbtrfs-root-on-subvolume-os
Compiling Scheme modules...
random seed for tests: 1581852580
Computing 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.d=
rv
   /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.g=
o.drv
   /gnu/store/clv6h5sxwgchw1kkf9cnafgvd5ms4p4r-shepherd-file-system--home.s=
cm.drv
   /gnu/store/zc84ngrjdvbc4kibdvzipf9sxjj50rgz-module-import-compiled.drv
   /gnu/store/6cca3yng6k4zl812ysdgmj5lyw8lmwln-shepherd-file-system--gnu-st=
ore.go.drv
   /gnu/store/rplp3l38j9jm0fism0ka1iqbfhx7h3ir-shepherd-file-system--gnu-st=
ore.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-sh=
m.go.drv
   /gnu/store/apsplfgbzzq38b5q7p06jxjn37kx74b2-shepherd-file-system--dev-sh=
m.scm.drv
   /gnu/store/qj459c7mlrls9imm1nw98lw9fgqh4yyy-shepherd-udev.go.drv
   /gnu/store/78klph6xipr232a938qjhm8v4qviacvd-shepherd-udev.scm.drv
   /gnu/store/z103dcbbvz3inx6ax7s966zxmy1s38hn-shepherd-file-system--dev-pt=
s.go.drv
   /gnu/store/5ss1d8nwn4dv9vb69h1iyw884b61y487-shepherd-file-system--dev-pt=
s.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.d=
rv
   /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.sc=
m.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
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...
successfully built /gnu/store/dmi03i3jv9wwkw10fm57g7fq97kwlscf-module-impor=
t.drv
building /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinf=
o.drv...
^Cmake: *** [Makefile:5711: check-system] Interrupt
--8<---------------cut here---------------end--------------->8---

With the hack:

--8<---------------cut here---------------start------------->8---
./pre-inst-env make check-system TESTS=3Dbtrfs-root-on-subvolume-os GUIX_DE=
V_HACKS=3D1
Compiling Scheme modules...
random seed for tests: 1581851372
Running 1 system tests...
The following derivations will be built:
   /gnu/store/l4z1363klr8a58qmm3pjzy2y5bxsr6bd-btrfs-root-on-subvolume-os.d=
rv
   /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.g=
o.drv
   /gnu/store/clv6h5sxwgchw1kkf9cnafgvd5ms4p4r-shepherd-file-system--home.s=
cm.drv
   /gnu/store/zc84ngrjdvbc4kibdvzipf9sxjj50rgz-module-import-compiled.drv
   /gnu/store/6cca3yng6k4zl812ysdgmj5lyw8lmwln-shepherd-file-system--gnu-st=
ore.go.drv
   /gnu/store/rplp3l38j9jm0fism0ka1iqbfhx7h3ir-shepherd-file-system--gnu-st=
ore.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-sh=
m.go.drv
   /gnu/store/apsplfgbzzq38b5q7p06jxjn37kx74b2-shepherd-file-system--dev-sh=
m.scm.drv
   /gnu/store/qj459c7mlrls9imm1nw98lw9fgqh4yyy-shepherd-udev.go.drv
   /gnu/store/78klph6xipr232a938qjhm8v4qviacvd-shepherd-udev.scm.drv
   /gnu/store/z103dcbbvz3inx6ax7s966zxmy1s38hn-shepherd-file-system--dev-pt=
s.go.drv
   /gnu/store/5ss1d8nwn4dv9vb69h1iyw884b61y487-shepherd-file-system--dev-pt=
s.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.sc=
m.drv
   /gnu/store/nhi2s5zcyd5frjqag4jnp7fvhzbx6kd6-activate.scm.drv
The 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.drv
building /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
--8<---------------cut here---------------end--------------->8---

The diff between those two looks like:
--8<---------------cut here---------------start------------->8---
--- /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.d=
rv
-   /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.g=
o.drv
    /gnu/store/a5nb6vhs86g76ww5bmpphi398pggnga7-shepherd-file-system--tmp.s=
cm.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
--8<---------------cut here---------------end--------------->8---

So, we can see there would me many guix-* things to build without the
hack.

Just building the OS using guix-current/pre-built, vs old
guix-current', vs the modern guix-current used for system tests:

guix-current/pre-built:
--8<---------------cut here---------------start------------->8---
time ./pre-inst-env guix system build -e '(begin (use-modules (gnu packages=
 package-management)) (parameterize ((current-guix-package (current-guix/pr=
e-built))) ((@@ (gnu tests install) operating-system-with-current-guix) (@@=
 (gnu tests install) %btrfs-root-on-subvolume-os))))'
[...]
real    12m23.259s
user    0m9.124s
sys     0m0.986s
--8<---------------cut here---------------end--------------->8---

old guix-current:
--8<---------------cut here---------------start------------->8---
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 test=
s install) %btrfs-root-on-subvolume-os))))'
[...]
real    45m45.572s
user    0m10.428s
sys     0m1.279s
--8<---------------cut here---------------end--------------->8---

And with the new "guix-current", computed with (guix self):
--8<---------------cut here---------------start------------->8---
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-derivation
substituting /gnu/store/7r7lbghps6qcl10qb6m321a3bgpr72fi-compute-guix-deriv=
ation...
downloading from http://10.42.0.199/nar/gzip/7r7lbghps6qcl10qb6m321a3bgpr72=
fi-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.d=
rv
   /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.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
The 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.drv
building /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-translated-texinf=
o.drv...
Your input po file ./guix-manual.de.po seems outdated (The amount of entrie=
s 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 entrie=
s 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 entrie=
s 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 entrie=
s 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 entrie=
s 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 entrie=
s 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 entrie=
s 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 entrie=
s 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 ent=
ries 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 ent=
ries differ between files: 7994 is not 281
). Please consider running po4a-updatepo to refresh it.
successfully built /gnu/store/9yz0spp1h158zdh8wmg2r7sspnkm0qfc-guix-transla=
ted-texinfo.drv
applying 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.drv
building /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.drv...
./guix.de.texi:2286: warning: @node name should not contain `,': Tastaturbe=
legung, Netzwerkanbindung und Partitionierung
./guix.de.texi:29751: warning: @node name should not contain `,': Vorbereit=
ung, um die Bootstrap-Bin=EF=BF=BDrdateien zu verwenden
./guix.ru.texi:932: warning: accent command `@,' must not be followed by wh=
itespace
Wide character in warn at /gnu/store/irj21yhgls637jhhkb5yr79s76c96maq-texin=
fo-6.6/bin/makeinfo line 656.
./guix.ru.texi:3977: warning: `.' or `,' must follow @xref, not =D0=B4
successfully built /gnu/store/95lcx1xx41p4vcwqlwli7phny6hpp8b0-guix-manual.=
drv
applying 1 graft for /gnu/store/qn8j1cqp2lfvghiv4sy5rps4kv2hz02y-guile3.0-g=
it-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.drv
process 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-b=
ase-source'
exporting path `/gnu/store/d3s80rm5pyggyqk71mwrsqzqahjc8jqr-guix-packages-b=
ase-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-sour=
ce'
exporting path `/gnu/store/0szskn0spa0gkf36p9fkrl9b4r7x67vc-guix-extra-buil=
der'
exporting path `/gnu/store/vg4zq88aw4y1skaljyd092yricg0krj0-guix-extra.drv'
exporting path `/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-b=
ase.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-sourc=
e'
offloading '/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packages-base.=
drv' to '10.42.0.199'...
offloading build of /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packag=
es-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-b=
ase.drv - x86_64-linux /var/log/guix/drvs/5z//hgzvnyswm8g50aha95rvdx6dpmw32=
9-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-gu=
ix-packages-base'...
found valid signature for '/gnu/store/60yrpv6cfzl9pzw4sgawfw0b8bx679js-guix=
-packages-base'
done with offloaded '/gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-packa=
ges-base.drv'
successfully built /gnu/store/5zhgzvnyswm8g50aha95rvdx6dpmw329-guix-package=
s-base.drv
building /gnu/store/7ih7cmbhz1p7a4m7yrgy0s2jawqc666n-guix-packages-base-mod=
ules.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-package=
s-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 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-b=
uilder'
exporting path `/gnu/store/qymkn55sgl7ln68cmkp60xx4h6kckg7p-guix-packages-s=
ource'
exporting path `/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.d=
rv'
offloading '/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.drv' =
to '10.42.0.199'...
offloading build of /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packag=
es.drv to '10.42.0.199'
substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
@ build-started /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packages.d=
rv - x86_64-linux /var/log/guix/drvs/il//y3pqqvfkjz5622fxz6mxg31jbiqb21-gui=
x-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-gu=
ix-packages'...
found valid signature for '/gnu/store/d5bz30n1r7fg8xybqip2prrxmfy07jz1-guix=
-packages'
done with offloaded '/gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-packa=
ges.drv'
successfully built /gnu/store/ily3pqqvfkjz5622fxz6mxg31jbiqb21-guix-package=
s.drv
building /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-package=
s-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.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-sou=
rce'
exporting path `/gnu/store/nw9kr3wkgfks44wrf8zw9y0l50bnzg77-guix-system-bui=
lder'
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.d=
rv -
retrieving 1 store item from '10.42.0.199'...
importing file or directory '/gnu/store/6swg1fk14gw145ihh0ml1549cdqvq9n1-gu=
ix-system'...
found valid signature for '/gnu/store/6swg1fk14gw145ihh0ml1549cdqvq9n1-guix=
-system'
done with offloaded '/gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-syste=
m.drv'
successfully built /gnu/store/ifqlhiq9mlbcq7cy05r2da7yr2c03whl-guix-system.=
drv
process 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.dr=
v...
waiting for locks or build slots...
successfully built /gnu/store/z3mzdfm2x2jrab7g3yhcg06lrgpq2ijz-guix-system-=
modules.drv
process 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-builde=
r'
exporting path `/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv'
offloading '/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv' to '1=
0.42.0.199'...
offloading build of /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.dr=
v 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-gu=
ix-cli'...
found valid signature for '/gnu/store/7gh81jn54ak2qw3ahq4nb9dc0zzn0h4v-guix=
-cli'
done with offloaded '/gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.d=
rv'
successfully built /gnu/store/6mdpdsflpz3axdlifw7mqfdmzhnpzvvc-guix-cli.drv
building /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-mod=
ules.drv
process 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-tes=
ts-builder'
exporting path `/gnu/store/sbrl1022yphyzdcjilpabfgq102rxxkc-guix-system-tes=
ts-source'
exporting path `/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tes=
ts.drv'
offloading '/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-tests.d=
rv' 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-tes=
ts.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-t=
ests.drv -
retrieving 1 store item from '10.42.0.199'...
importing file or directory '/gnu/store/c98xnkcbm1bd3j69k08kr3d8msm5zg94-gu=
ix-system-tests'...
found valid signature for '/gnu/store/c98xnkcbm1bd3j69k08kr3d8msm5zg94-guix=
-system-tests'
done with offloaded '/gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-syste=
m-tests.drv'
successfully built /gnu/store/fwr4jlsgxjxkiqn6l4dr1hfl684irmp0-guix-system-=
tests.drv
building /gnu/store/ysr4d2bqhs4c4viwyk9pvcjcnwv4pnr8-guix-system-tests-modu=
les.drv...
successfully built /gnu/store/ysr4d2bqhs4c4viwyk9pvcjcnwv4pnr8-guix-system-=
tests-modules.drv
building /gnu/store/mx5kd00k1axs9xrgwn5hibiidbxshy3g-guix-000000000-modules=
.drv...
successfully built /gnu/store/mx5kd00k1axs9xrgwn5hibiidbxshy3g-guix-0000000=
00-modules.drv
building /gnu/store/flii6im368mj1mlwb1xmnvwhibll0acg-guix-module-union.drv.=
..
successfully built /gnu/store/flii6im368mj1mlwb1xmnvwhibll0acg-guix-module-=
union.drv
building /gnu/store/cjzvm56h61zhwd56g1ksi91spq567b4b-guix-command.drv...
successfully built /gnu/store/cjzvm56h61zhwd56g1ksi91spq567b4b-guix-command=
.drv
building /gnu/store/65dva2y1zq173i93z57xzffn34rmfbgw-guix-daemon.drv...
successfully built /gnu/store/65dva2y1zq173i93z57xzffn34rmfbgw-guix-daemon.=
drv
building /gnu/store/hb87zw934jkgxwkgbbfykwaq55p6pzlq-guix-000000000.drv...
successfully built /gnu/store/hb87zw934jkgxwkgbbfykwaq55p6pzlq-guix-0000000=
00.drv
building CA certificate bundle...
successfully built /gnu/store/qpcnvr43c5rl6bgpsj7l3m38r6xndz7j-ca-certifica=
te-bundle.drv
building fonts directory...
successfully built /gnu/store/scm0rsny7n5kmryffp081hdh6rh2659l-fonts-dir.drv
building directory of Info manuals...
successfully built /gnu/store/qc53qlnzwxlhlm01fxp45ppdnrzw0lfz-info-dir.drv
building database for manual pages...
Creating manual page database...
[  1/  1] building list of man-db entries...
0 entries processed in 0.0 s
successfully built /gnu/store/8k7vn4fbwqvlmhsv604v7zkgils5j0f4-manual-datab=
ase.drv
building /gnu/store/2hd5a6klgq8zz22rsm3jd4wqw6cbcmbq-profile.drv...
successfully built /gnu/store/2hd5a6klgq8zz22rsm3jd4wqw6cbcmbq-profile.drv
building /gnu/store/zdqspx48gmwa9xv2ibn993qfswq9zgkf-inferior-script.scm.dr=
v...
successfully built /gnu/store/zdqspx48gmwa9xv2ibn993qfswq9zgkf-inferior-scr=
ipt.scm.drv
building package cache...
(repl-version 0 0)
Generating package cache for '/gnu/store/lxl90crn49lgnmxd13ljka6w6dz6vm9p-p=
rofile'...
(values (value "/gnu/store/ckyfrrsk8fdx9lzkiwvf0a3p79ll2gfg-guix-package-ca=
che/lib/guix/package.cache"))
successfully built /gnu/store/841rih0j6iskwdxvay7cm94l3vn4idl7-guix-package=
-cache.drv
building /gnu/store/3rqfd301xgwlaacwppswdxshlc13ky7p-profile.drv...
successfully built /gnu/store/3rqfd301xgwlaacwppswdxshlc13ky7p-profile.drv
building CA certificate bundle...
successfully built /gnu/store/44wi6c2lq0mpkmx940wsi56fmxr8fjh4-ca-certifica=
te-bundle.drv
building fonts directory...
successfully built /gnu/store/1li6nkn0p7zikf5y36ljir2n53rf81cg-fonts-dir.drv
building directory of Info manuals...
successfully built /gnu/store/d80j7mvj59m6h33m3c72mwfckb9xrn7r-info-dir.drv
building database for manual pages...
Creating manual page database...
[ 45/ 45] building list of man-db entries...
1039 entries processed in 3.2 s
successfully built /gnu/store/x1cfgs17hpiw33fpq8gj51ldykf8wd25-manual-datab=
ase.drv
building /gnu/store/5688khnjjabnh8bnn4hc41j05h1larh9-shepherd-guix-daemon.s=
cm.drv...
successfully built /gnu/store/5688khnjjabnh8bnn4hc41j05h1larh9-shepherd-gui=
x-daemon.scm.drv
building /gnu/store/a2dl48yn635qqbga72gwkqnypd45lxaf-profile.drv...

warning: collision encountered:
  /gnu/store/zg26g1i42sfn26ll4k5i3wb20zmwmpah-info-dir/share/info/dir
  /gnu/store/ma7ccwpzsypkxp88j2jlr4vq1gad06vd-profile/share/info/dir
warning: choosing /gnu/store/zg26g1i42sfn26ll4k5i3wb20zmwmpah-info-dir/shar=
e/info/dir

warning: collision encountered:
  /gnu/store/5al8wjz7522q8rqzyfmz46mlbzm70jzj-manual-database/share/man/ind=
ex.db
  /gnu/store/ma7ccwpzsypkxp88j2jlr4vq1gad06vd-profile/share/man/index.db
warning: choosing /gnu/store/5al8wjz7522q8rqzyfmz46mlbzm70jzj-manual-databa=
se/share/man/index.db
successfully built /gnu/store/a2dl48yn635qqbga72gwkqnypd45lxaf-profile.drv
building /gnu/store/7wkb1al9lxp5k84k9b1i5v7h69x9p3wr-shepherd-guix-daemon.g=
o.drv...
successfully built /gnu/store/7wkb1al9lxp5k84k9b1i5v7h69x9p3wr-shepherd-gui=
x-daemon.go.drv
building /gnu/store/jp62bqlvch38sqcqkxk3ddwih84qz8ka-shepherd.conf.drv...
successfully built /gnu/store/jp62bqlvch38sqcqkxk3ddwih84qz8ka-shepherd.con=
f.drv
building /gnu/store/ixk9m5hqwj42kdzh88vwy06alk9bw811-boot.drv...
successfully built /gnu/store/ixk9m5hqwj42kdzh88vwy06alk9bw811-boot.drv
building /gnu/store/1kmbdnkdip0xbdi4h09jj44nccmpmxh6-system.drv...
successfully built /gnu/store/1kmbdnkdip0xbdi4h09jj44nccmpmxh6-system.drv
/gnu/store/mv1c4cv6c1wws712zi4wz8l6ab8gwn85-system
--8<---------------cut here---------------end--------------->8---

real    58m19.825s
user    3m42.533s
sys     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 the
commits of this change set.

Maxim




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 16 Feb 2020 11:11:55 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Feb 16 06:11:55 2020
Received: from localhost ([127.0.0.1]:36751 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j3Hq6-0004KA-LD
	for submit <at> debbugs.gnu.org; Sun, 16 Feb 2020 06:11:54 -0500
Received: from eggs.gnu.org ([209.51.188.92]:59722)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1j3Hq5-0004Jz-UF
 for 37305 <at> debbugs.gnu.org; Sun, 16 Feb 2020 06:11:54 -0500
Received: from fencepost.gnu.org ([2001:470:142:3::e]:33987)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1j3Hq0-00056v-Rm; Sun, 16 Feb 2020 06:11:48 -0500
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=48584 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1j3Hq0-0006Ou-Ch; Sun, 16 Feb 2020 06:11:48 -0500
From: =?utf-8?Q?Ludovic_Court=C3=A8s?= <ludo@HIDDEN>
To: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Subject: Making system installation tests faster
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN> <87blpzozz7.fsf@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 28 =?utf-8?Q?Pluvi=C3=B4se?= an 228 de la
 =?utf-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Sun, 16 Feb 2020 12:11:47 +0100
In-Reply-To: <87blpzozz7.fsf@HIDDEN> (Maxim Cournoyer's message of "Sun, 16
 Feb 2020 00:36:28 -0500")
Message-ID: <8736ba3hxo.fsf_-_@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hi Maxim,

Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:

> Ludovic Court=C3=A8s <ludo@HIDDEN> writes:
>
>> Hi Maxim!
>>
>> Great to see Btrfs support improving; many people will love that!
>>
>> Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:
>>
>>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
>>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>>> Date: Sun, 17 Nov 2019 06:01:00 +0900
>>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the sy=
stem
>>>  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 pro=
cedure.
>>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, =
when
>>> GUIX_DEV_HACKS is defined.
>>
>> I understand the need, but I=E2=80=99d really like to avoid that; it=E2=
=80=99s too
>> fragile IMO.
>>
>> But I have good news!  First, commit
>> 887fd835a7c90f720d36a211478012547feaead0 really improved things by
>> avoiding the full =E2=80=98guix=E2=80=99 package rebuild (and we=E2=80=
=99re 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=E2=80=99s still room for improvement, but I=E2=80=99d 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=E2=80=99s grabbing files from the working tree, with heuristics to minim=
ize
the changes in incorporating files that shouldn=E2=80=99t be there; I think=
 it=E2=80=99s
fragile.  :-)

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 implement=
ation 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=E2=80=99d have to maintain that in the meantime and de=
al
with any =E2=80=9Csurprising=E2=80=9D effects it has for those using it.

FWIW, when testing (gnu installer tests), I only have to rebuild
=E2=80=9Cguix-system-tests.drv=E2=80=9D, 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=E2=80=99s not necessary to have =
the
current =E2=80=98guix=E2=80=99 package.

I suppose this would also be an option in your case, when testing the
Btrfs changes, no?

Perhaps we should make this case more easily accessible through an
environment variable?

Thanks,
Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 16 Feb 2020 05:36:38 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Feb 16 00:36:38 2020
Received: from localhost ([127.0.0.1]:36668 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j3Cbd-0004II-Ez
	for submit <at> debbugs.gnu.org; Sun, 16 Feb 2020 00:36:38 -0500
Received: from mail-qk1-f195.google.com ([209.85.222.195]:45600)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j3Cbc-0004I4-6b
 for 37305 <at> debbugs.gnu.org; Sun, 16 Feb 2020 00:36:36 -0500
Received: by mail-qk1-f195.google.com with SMTP id a2so13203329qko.12
 for <37305 <at> debbugs.gnu.org>; Sat, 15 Feb 2020 21:36:36 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version:content-transfer-encoding;
 bh=deGspZNU/oOO78cn/fxq1S8kDx/q/0y7hpMbmI38a80=;
 b=c92WsGR4Jqu8Xg2SQu2msZl/RpCl/o/r+O7hsOdZ1QkuypfF9K5g+MhQ/I2dre2p9x
 ozRea/1G6A5oh3nPLfdvo1owqdqsyGdFIz6+aJitevAWN4eqRhI3nPxvcR5OuB4BulAp
 5bbQDW866IMudELjvIeDAG0zDcBsJ/4kk7huj/kP3jnULGyvvs6FAb2iteSQZlmdR2q1
 NBWU0JoVv50IfilVLLkfE15hW0O6U6ppGT8BVOv4DacXazzLCpu1cdRyGTRZ/AF2+E7h
 GUXIdYfrOkr/XOTgJnRhtdjcRKn7lTJxfSF78TV/yjrPhR18cEhw6uc52Qf9ApDYQHSR
 iyDg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version:content-transfer-encoding;
 bh=deGspZNU/oOO78cn/fxq1S8kDx/q/0y7hpMbmI38a80=;
 b=mpczfO7oFOH+F43qrBHdfXk+0EUohVSYvTIc6PT6UqoV8+MfsD/eoIA+T/iYzQh8cG
 jE7TtyJnX4CNngIzgxgd56/rlcpUo7uEsEFvjCwUyR3Wcp2uT+atuUpLQCTrAJBlSUUj
 GRmbZugNoo7jzUo0UIDDjPTZDFA6X/IzrIjSH3vBDIBNTE4BKW1WEC+fD43WnthVPPXu
 bKP+WYLjTtly1k/cUZdhPcl/wqgEtNOBA2rF9xZ4HdytLpQPzreAe8KpmUrj+L3Ly/ZQ
 byHLtxlYH3RdpJeyYjG8XWhDUGZkt/+Omrgi6VUWwSnqENDPQuEA1yIyNkUq5eBuCGNO
 yv6w==
X-Gm-Message-State: APjAAAX9DQc51HE4s7t/Xo9j3fUsWpqsw8Vn4wA1SM9o+kM6qbylKGcf
 363PCP8e72KQR+g9Sg3/1ZsuUPFi
X-Google-Smtp-Source: APXvYqxW3yuUr5YQEZASYlMN87vxMq25CeFCRV1kes41EbzykZr8Sh6Aj14873uLtcMPjV1P4u1qmw==
X-Received: by 2002:a05:620a:214f:: with SMTP id
 m15mr8411347qkm.461.1581831390390; 
 Sat, 15 Feb 2020 21:36:30 -0800 (PST)
Received: from apteryx (dsl-149-226.b2b2c.ca. [66.158.149.226])
 by smtp.gmail.com with ESMTPSA id x126sm6830364qkc.42.2020.02.15.21.36.28
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Sat, 15 Feb 2020 21:36:29 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
 <8736bdf5il.fsf@HIDDEN>
Date: Sun, 16 Feb 2020 00:36:28 -0500
In-Reply-To: <8736bdf5il.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Fri, 14 Feb 2020 18:22:26 +0100")
Message-ID: <87blpzozz7.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Hello!

Thanks for the prompt feedback.

Ludovic Court=C3=A8s <ludo@HIDDEN> writes:

> Hi Maxim!
>
> Great to see Btrfs support improving; many people will love that!
>
> Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:
>
>> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> Date: Sun, 17 Nov 2019 06:01:00 +0900
>> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the sys=
tem
>>  tests.
>>
>> When setting the GUIX_DEV_HACKS environment variable, the Guix package u=
sed
>> inside the instrumented VMs recycles the binaries already found in the G=
uix
>> 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 proc=
edure.
>> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, w=
hen
>> GUIX_DEV_HACKS is defined.
>
> I understand the need, but I=E2=80=99d really like to avoid that; it=E2=
=80=99s too
> fragile IMO.
>
> But I have good news!  First, commit
> 887fd835a7c90f720d36a211478012547feaead0 really improved things by
> avoiding the full =E2=80=98guix=E2=80=99 package rebuild (and we=E2=80=99=
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=E2=80=99s still room for improvement, but I=E2=80=99d rather work i=
n 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.

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 implementat=
ion 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"
;-).

>> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> 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 =E2=80=9Cgnu:=E2=80=9D 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? :-)

> OK!
>
>> From e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> 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 procedur=
e.
>> * 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@HIDDEN>
>> 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 sy=
stem
>> 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 t=
he
>> let* instead.  Make "--root" take precendence over the device field stri=
ng
>> representation of the root file system.
>> * doc/guix.texi (Initial RAM Disk): Document that "--root" can be left
>> unspecified.
>
> [...]
>
>>  @item --root=3D@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=E2=80=99ve been ca=
rrying
> =E2=80=98--root=E2=80=99 and I=E2=80=99m not sure if I=E2=80=99m forgetti=
ng 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.

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.

>
>>        (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=3D> root-fs file-system-type)
>> +                               "ext4"))
>> +             (root-device (and=3D> root-fs file-system-device))
>> +             (root-device-str (and=3D> 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=3D> 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 =E2=80=98file-system-device->string=E2=80=99 is lossy, I think we s=
hould do it the
> other way around: convert the =E2=80=98--root=E2=80=99 string to a <file-=
system>.
> Perhaps that bit can be moved to a separate procedure, like
> =E2=80=98root-string->file-system=E2=80=99.

Done!

> Also, the (or =E2=80=A6 "ext4") bit doesn=E2=80=99t sound great, but perh=
aps it=E2=80=99ll be
> unnecessary if we do with something as outlined above?

That bit was already there; it exists because we allow an operating
system definition to be made without any root file system (for use with
the 'guix system container' or 'guix system vm' commands IIRC).  What
could be simpler would be to always require such information to be
embedded in the operating system declaration: when an interactive user
command would need to modify the root file system, it could create a new
operating-system object, inheriting from the original one.

>> From af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> 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 par=
se 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 t=
he
>> 'file-system-options' field.
>
> The main issue I see with this change is that mount(2) takes raw strings
> for the options.  There=E2=80=99s a convention to have those strings look=
 like
> =E2=80=9CKEY1=3DVALUE1,KEY2=3DVALUE2=E2=80=9D, but it=E2=80=99s just a co=
nvention.
>
> As a rule of thumb, I=E2=80=99d 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. This should be
stressed in the manual, as someone attempting to pass file system
independent 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, since
the main interaction I observed between a file system object and my
system was the /etc/fstab file getting produced.

Doesn't targeting mount(2) mean that it becomes impossible to give all
the options someone would possibly want to produce their /etc/fstab
file?  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 the
file system independent mount(8) options into mount(2) flags or
vice-versa but targeting the higher level and going down makes more
sense to me.

>> +  ;; 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 "=3D")
>> +                 (apply cons (string-split param #\=3D))
>> +                 param))
>> +           option-list)))
>
> I think we=E2=80=99d want to split only on the first =E2=80=98=3D=E2=80=
=99 sign, meaning we should
> use =E2=80=98string-index=E2=80=99 etc. instead of =E2=80=98string-split=
=E2=80=99.

Good catch!

>> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> 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" ker=
nel
>> argument, and use it when calling `mount-root-file-system'.  Update doc.
>> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-opti=
ons"
>> 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?

> (Also, in hindsight, I think it was a mistake to call them
> =E2=80=98--something=E2=80=99.  Following the common naming convention, w=
e should rather
> call these options =E2=80=98gnu.something=E2=80=99.)

Is this convention detailed somewhere?  I haven't found it in 'Standards'.

>> From cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>> 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 understo=
od 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 fil=
ter
>> 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" "norelat=
ime"
>> +    "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosui=
d"
>> +    "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" =
"users"))
>
> I=E2=80=99d rather avoid it.  In general, as much as possible, I think we=
 should
> pass options to the kernel without trying to be =E2=80=9Csmart=E2=80=9D. =
 It=E2=80=99s 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




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 14 Feb 2020 17:22:37 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Fri Feb 14 12:22:37 2020
Received: from localhost ([127.0.0.1]:34640 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j2efl-0005ZS-4r
	for submit <at> debbugs.gnu.org; Fri, 14 Feb 2020 12:22:37 -0500
Received: from eggs.gnu.org ([209.51.188.92]:35048)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1j2efi-0005ZG-LR
 for 37305 <at> debbugs.gnu.org; Fri, 14 Feb 2020 12:22:35 -0500
Received: from fencepost.gnu.org ([2001:470:142:3::e]:36362)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1j2efd-0005Ld-HF; Fri, 14 Feb 2020 12:22:29 -0500
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=41592 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1j2efc-000259-TN; Fri, 14 Feb 2020 12:22:29 -0500
From: =?utf-8?Q?Ludovic_Court=C3=A8s?= <ludo@HIDDEN>
To: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Subject: Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN> <87lfp6b5cs.fsf_-_@HIDDEN>
X-URL: http://www.fdn.fr/~lcourtes/
X-Revolutionary-Date: 26 =?utf-8?Q?Pluvi=C3=B4se?= an 228 de la
 =?utf-8?Q?R=C3=A9volution?=
X-PGP-Key-ID: 0x090B11993D9AEBB5
X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc
X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4  0CFB 090B 1199 3D9A EBB5
X-OS: x86_64-pc-linux-gnu
Date: Fri, 14 Feb 2020 18:22:26 +0100
In-Reply-To: <87lfp6b5cs.fsf_-_@HIDDEN> (Maxim Cournoyer's message of "Thu, 
 13 Feb 2020 15:27:15 -0500")
Message-ID: <8736bdf5il.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -0.7 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.7 (-)

Hi Maxim!

Great to see Btrfs support improving; many people will love that!

Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:

> From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> Date: Sun, 17 Nov 2019 06:01:00 +0900
> Subject: [PATCH 1/9] gnu: tests: Reduce the time required to run the syst=
em
>  tests.
>
> When setting the GUIX_DEV_HACKS environment variable, the Guix package us=
ed
> inside the instrumented VMs recycles the binaries already found in the Gu=
ix
> 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 proce=
dure.
> * build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, wh=
en
> GUIX_DEV_HACKS is defined.

I understand the need, but I=E2=80=99d really like to avoid that; it=E2=80=
=99s too
fragile IMO.

But I have good news!  First, commit
887fd835a7c90f720d36a211478012547feaead0 really improved things by
avoiding the full =E2=80=98guix=E2=80=99 package rebuild (and we=E2=80=99re=
 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=E2=80=99s still room for improvement, but I=E2=80=99d rather work in =
those
directions.  WDYT?

> From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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 =E2=80=9Cgnu:=E2=80=9D prefix.)

OK!

> From e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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@HIDDEN>
> 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 sys=
tem
> 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=3D@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=E2=80=99ve been carr=
ying
=E2=80=98--root=E2=80=99 and I=E2=80=99m not sure if I=E2=80=99m forgetting=
 a good reason to do it that
way.

>        (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=3D> root-fs file-system-type)
> +                               "ext4"))
> +             (root-device (and=3D> root-fs file-system-device))
> +             (root-device-str (and=3D> root-device file-system-device->s=
tring))
> +             ;; --root takes precedence over the 'device' field of the r=
oot
> +             ;; <file-system> record.
> +             (root (or (find-long-option "--root" args)
> +                       root-device-str))
> +             (root-fs-flags (mount-flags->bit-mask
> +                             (or (and=3D> 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 =E2=80=98file-system-device->string=E2=80=99 is lossy, I think we sho=
uld do it the
other way around: convert the =E2=80=98--root=E2=80=99 string to a <file-sy=
stem>.
Perhaps that bit can be moved to a separate procedure, like
=E2=80=98root-string->file-system=E2=80=99.

Also, the (or =E2=80=A6 "ext4") bit doesn=E2=80=99t sound great, but perhap=
s it=E2=80=99ll be
unnecessary if we do with something as outlined above?

> From af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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 pars=
e a
> string.
>
> * gnu/system/file-systems.scm (<file-system>): Update the default value o=
f 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=E2=80=99s a convention to have those strings look l=
ike
=E2=80=9CKEY1=3DVALUE1,KEY2=3DVALUE2=E2=80=9D, but it=E2=80=99s just a conv=
ention.

As a rule of thumb, I=E2=80=99d 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?

> +  ;; 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 "=3D")
> +                 (apply cons (string-split param #\=3D))
> +                 param))
> +           option-list)))

I think we=E2=80=99d want to split only on the first =E2=80=98=3D=E2=80=99 =
sign, meaning we should
use =E2=80=98string-index=E2=80=99 etc. instead of =E2=80=98string-split=E2=
=80=99.

> From 67135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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" kern=
el
> argument, and use it when calling `mount-root-file-system'.  Update doc.
> * doc/guix.texi (Initial RAM Disk): Document the use of the "--root-optio=
ns"
> argument.

Hmm do we really need this extra option?  :-)

(Also, in hindsight, I think it was a mistake to call them
=E2=80=98--something=E2=80=99.  Following the common naming convention, we =
should rather
call these options =E2=80=98gnu.something=E2=80=99.)

> From cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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 understoo=
d by
> the command line program "mount", are not understood by the system call o=
f the
> same name, which is used in the initial RAM disk.
>
> * gnu/system/file-systems.scm (%file-system-independent-mount-options): N=
ew variable.
> (file-system-independent-mount-option?): New predicate.
> * gnu/build/linux-boot.scm (boot-system): Use the above predicate to filt=
er
> 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" "norelati=
me"
> +    "strictatime" "nostrictatime" "lazytime" "nolazytime" "suid" "nosuid"
> +    "silent" "loud" "owner" "remount" "ro" "rw" "sync" "user" "nouser" "=
users"))

I=E2=80=99d rather avoid it.  In general, as much as possible, I think we s=
hould
pass options to the kernel without trying to be =E2=80=9Csmart=E2=80=9D.  I=
t=E2=80=99s often the
safe strategy.

WDYT?

> From 6cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> Date: Sun, 14 Jul 2019 20:50:23 +0900
> Subject: [PATCH 8/9] bootloader: grub: Allow booting from a Btrfs subvolu=
me.
>
> * 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 n=
ew
> BTRFS-SUBVOLUME-PATH argument.
> * doc/guix.texi (File Systems): Add a Btrfs subsection to document the us=
e 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 resid=
es."

(Nitpick: s/path/file name/ :-))

It=E2=80=99s 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=E2=80=99t have a better idea, but it=E2=80=99d be great if Btrfs supp=
ort could be
made bootloader-independent, and if it could be somewhat
not-too-btrfs-specific, if that is possible at all.

Thoughts?

> +  (properties       file-system-properties        ; list of name-value p=
airs
> +                    (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))))
>=20=20
> +(define (btrfs-subvolume? fs)
> +  "Predicate to check if FS, a file-system object, is a Btrfs subvolume."
> +  (and-let* ((btrfs-file-system? (string=3D "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 =E2=80=98raise=E2=80=99 with =E2=80=98&message=E2=80=99 and =E2=
=80=98&fix-hint=E2=80=99 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=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 13 Feb 2020 20:27:29 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Thu Feb 13 15:27:29 2020
Received: from localhost ([127.0.0.1]:60528 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j2L55-0002Un-Ny
	for submit <at> debbugs.gnu.org; Thu, 13 Feb 2020 15:27:29 -0500
Received: from mail-qk1-f193.google.com ([209.85.222.193]:43860)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j2L52-0002UX-Du
 for 37305 <at> debbugs.gnu.org; Thu, 13 Feb 2020 15:27:26 -0500
Received: by mail-qk1-f193.google.com with SMTP id p7so7006697qkh.10
 for <37305 <at> debbugs.gnu.org>; Thu, 13 Feb 2020 12:27:24 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=0nRwqXQpuyYdADG1qh6Nw0GmonIRWRE1LhUKkOLPLAI=;
 b=VdDmGGBrSx3uL9yzYTcDwyNm6mYDIyUfEgWR3/WqiiAaYOa1BR9sBpBc1FL+w6n7vx
 XXNACkM3Cz/7ze4qHnY4Ggy6COCMbnEhZHxFj36hwDgqC/rqKufgozJQYdfML3HcaNdt
 /11wD1l78I+bLWC7L4maumRgVG2KikZsPZ7M3fC9FaaiE0nnIimceUs2wKQqiYZc2y/7
 1vam/HT6zy/5XTcxsYw16pAyWMHlTs/J+h5jEK0Ncvz+XD6xYvULDqPyfTblUtI08CQt
 7tpotAUGv7pwfJhjtAQcI3Xy1EYN6oWvc2HykmoZI6KkaF7hYhSyn4E1N+p82HfzMgup
 kRWA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=0nRwqXQpuyYdADG1qh6Nw0GmonIRWRE1LhUKkOLPLAI=;
 b=i79f4+EiO2a6nmdcgagpgT+F/EQRFzX6c+x9hdbsY0nb9PG8eIAhVakrissEWR1Jej
 KgxYvdXXN1TCkVYrEdzCbaCYqVZC75F4H1KbFOv1lbkGuTIEc/QgJmHZeM5YqpExFn9x
 0UYvnIkUse3oXrGJGE7ohK/Gld8SlLouj1kAxLMsFbQc4Fsj52tlTz6qc8osMn4e7wn+
 jj+5yYpd1aG9iHksBh/0N/xfxc9dw6tF0i76gyABw5pClQdEBRC5/GYmqJbqIRJRNjPc
 hryUgHCdYGVGh4BTdrBbF/+52l1dM1jz/yiDiwS0swA+s4tP+Mbgh3NqGliIwAB4n0Gx
 O57w==
X-Gm-Message-State: APjAAAUkY3pjoJ5HoKaaONp8qg5vgBbyd+B6ZVvVWP818hqCpcVQjULU
 c3/8T4iuJa6RgsRMp17N99rVgDwP
X-Google-Smtp-Source: APXvYqzk4vc+/PziT/EO64SAE8dTGaSf7HdvK+D3A4Zbyhcu43J35eTeirCpMRVfYS3mupWth6+zRQ==
X-Received: by 2002:a37:6752:: with SMTP id b79mr17822145qkc.224.1581625638806; 
 Thu, 13 Feb 2020 12:27:18 -0800 (PST)
Received: from kwak ([2607:fad8:4:6:afc9:fe0d:91fc:113b])
 by smtp.gmail.com with ESMTPSA id g11sm511131qtc.48.2020.02.13.12.27.16
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 13 Feb 2020 12:27:17 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] [PATCH V2] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
 <87k14sfaz7.fsf@HIDDEN>
Date: Thu, 13 Feb 2020 15:27:15 -0500
In-Reply-To: <87k14sfaz7.fsf@HIDDEN> (Maxim Cournoyer's message of "Wed, 12
 Feb 2020 03:47:40 -0500")
Message-ID: <87lfp6b5cs.fsf_-_@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="==-=-=";
 micalg=pgp-sha256; protocol="application/pgp-signature"
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: text/plain

I've fixed a few problems I've found with more extensive testing.

Attached is the version 2 of the patch series.


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-gnu-tests-Reduce-the-time-required-to-run-the-system.patch
Content-Transfer-Encoding: quoted-printable

From=203640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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 procedu=
re.
* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when
GUIX_DEV_HACKS is defined.
=2D--
 build-aux/run-system-tests.scm      | 11 ++++-
 gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scm
index b0cb3bd2bf..04b6fa29c3 100644
=2D-- 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 =C2=A9 2016, 2018, 2019 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -58,8 +59,16 @@ instance."
   ;; of tests to run in the usual way:
   ;;
   ;;   make check-system TESTS=3Dinstalled-os
+
+  ;; When the GUIX_DEV_HACKS environment variable is defined, override the
+  ;; package returned by `current-guix' with a flavor that saves recompili=
ng
+  ;; Guix from scratch and reuse the developer's checkout binaries.  The
+  ;; override "builds" about 20 times faster than the regular `current-gui=
x'
+  ;; package, which can help speed iterative development.
   (parameterize ((current-guix-package
=2D                  (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-man=
agement.scm
index 422d4f1959..bd2ed85189 100644
=2D-- 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 'so=
urce'."
                                 #:recursive? #t
                                 #:select? (force select?))))))))
=20
+(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 RE=
PL.
+         ;; 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 n=
icer
+             ;; 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 t=
o 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 t=
he
+                 ;; 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 profil=
e,
+                         ;; we could make this package inherit from the gu=
ix
+                         ;; 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.
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-gnu-linux-boot-Ensure-volatile-root-is-mounted-read-.patch
Content-Transfer-Encoding: quoted-printable

From=2097d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 gnu/build/linux-boot.scm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 3d40a7d05d..4fb711b8f2 100644
=2D-- 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-ROO=
T? is
 true, mount ROOT read-only and make it an overlay with a writable tmpfs us=
ing
 the kernel built-in overlayfs. FLAGS and OPTIONS indicates the options to =
use
=2Dto mount ROOT."
+to mount ROOT, and behave the same as for the `mount' procedure."
=20
   (if volatile-root?
       (begin
         (mkdir-p "/real-root")
=2D        (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")
=20
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0003-file-systems-Add-a-file-system-device-string-procedu.patch
Content-Transfer-Encoding: quoted-printable

From=20e8d6642d3597207657842c9ca4849f8660d06638 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 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(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index 01baa248a2..2e6d03272d 100644
=2D-- 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-DEVI=
CE."
   (list (string-append "--root=3D"
=2D                       (cond ((uuid? root-device)
=2D
=2D                              ;; Note: Always use the DCE format because=
 that's
=2D                              ;; what (gnu build linux-boot) expects for=
 the
=2D                              ;; '--root' kernel command-line option.
=2D                              (uuid->string (uuid-bytevector root-device)
=2D                                            'dce))
=2D                             ((file-system-label? root-device)
=2D                              (file-system-label->string root-device))
=2D                             (else root-device)))
+                       ;; Note: Always use the DCE format because that's w=
hat
+                       ;; (gnu build linux-boot) expects for the '--root'
+                       ;; kernel command-line option.
+                       (file-system-device->string root-device
+                                                   #:uuid-type 'dce))
         #~(string-append "--system=3D" #$system)
         #~(string-append "--load=3D" #$system "/boot")))
=20
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index d47a514b66..fc383d8a5a 100644
=2D-- 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.  Fo=
r example:
               (()
                #f)))))))
=20
+(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 t=
he
 store--e.g., if FS is the root file system."
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 81b2e06ba2..03a511cdde 100644
=2D-- 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)
=2D            (cond ((file-system-label? device)
=2D                   (file-system-label->string device))
=2D                  ((uuid? device)
=2D                   (uuid->string device))
=2D                  ((string? device)
=2D                   device)
=2D                  (else #f))
+            (file-system-device->string device)
             (file-system-options fs))))
=20
   (if (eq? type 'iso9660)
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index e69a3b6c97..b0386a1392 100644
=2D-- 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))
=2D              (cond ((uuid? root-device)
=2D                     (uuid->string root-device))
=2D                    ((file-system-label? root-device)
=2D                     (file-system-label->string root-device))
=2D                    (else
=2D                     root-device)))
+              (file-system-device->string root-device))
=20
       (format #t (G_ "  kernel: ~a~%") kernel)
=20
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0004-gnu-linux-boot-Refactor-boot-system.patch
Content-Transfer-Encoding: quoted-printable

From=204f6e3955957beb5287e9d5a5d33b74725836e1ac Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 doc/guix.texi            |  7 ++++---
 gnu/build/linux-boot.scm | 42 +++++++++++++++++++---------------------
 2 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 42d7cfa2e8..85cfabc2f3 100644
=2D-- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25917,9 +25917,10 @@ service activation programs and then spawns the GN=
U@tie{}Shepherd, the
 initialization system.
=20
 @item --root=3D@var{root}
=2DMount @var{root} as the root file system.  @var{root} can be a
=2Ddevice name like @code{/dev/sda1}, a file system label, or a file system
=2DUUID.
+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.
=20
 @item --system=3D@var{system}
 Have @file{/run/booted-system} and @file{/run/current-system} point to
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 4fb711b8f2..28697e7bbf 100644
=2D-- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -467,26 +467,6 @@ upon error."
   (define (root-mount-point? fs)
     (string=3D? (file-system-mount-point fs) "/"))
=20
=2D  (define root-fs-type
=2D    (or (any (lambda (fs)
=2D               (and (root-mount-point? fs)
=2D                    (file-system-type fs)))
=2D             mounts)
=2D        "ext4"))
=2D
=2D  (define root-fs-flags
=2D    (mount-flags->bit-mask (or (any (lambda (fs)
=2D                                      (and (root-mount-point? fs)
=2D                                           (file-system-flags fs)))
=2D                                    mounts)
=2D                               '())))
=2D
=2D  (define root-fs-options
=2D    (any (lambda (fs)
=2D           (and (root-mount-point? fs)
=2D                (file-system-options fs)))
=2D         mounts))
=2D
   (display "Welcome, this is GNU's early boot Guile.\n")
   (display "Use '--repl' for an initrd REPL.\n\n")
=20
@@ -495,7 +475,25 @@ upon error."
       (mount-essential-file-systems)
       (let* ((args    (linux-command-line))
              (to-load (find-long-option "--load" args))
=2D             (root    (find-long-option "--root" args)))
+             (root-fs (find root-mount-point? mounts))
+             (root-fs-type (or (and=3D> root-fs file-system-type)
+                               "ext4"))
+             (root-device (and=3D> root-fs file-system-device))
+             (root-device-str (and=3D> root-device file-system-device->str=
ing))
+             ;; --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=3D> 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))))
=20
         (when (member "--repl" args)
           (start-repl))
@@ -541,7 +539,7 @@ upon error."
                                       root-fs-type
                                       #:volatile-root? volatile-root?
                                       #:flags root-fs-flags
=2D                                      #:options root-fs-options))
+                                      #:options root-options))
             (mount "none" "/root" "tmpfs"))
=20
         ;; Mount the specified file systems.
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0005-file-systems-Represent-the-file-system-options-as-an.patch
Content-Transfer-Encoding: quoted-printable

From=20af61745d8b686755a5d9deb9e21c9eac624fb43e Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 85cfabc2f3..5d526b1aee 100644
=2D-- 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.
=20
=2D@item @code{options} (default: @code{#f})
=2DThis is either @code{#f}, or a string denoting mount options passed to t=
he
=2Dfile system driver.  @xref{Mount-Unmount-Remount,,, libc, The GNU C Libr=
ary
=2DReference Manual}, for details and run @command{man 8 mount} for options=
 for
=2Dvarious 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.
=20
 @item @code{mount?} (default: @code{#t})
 This value indicates whether to automatically mount the file system when
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index ee6375515f..cfa3898f83 100644
=2D-- 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)
                                 "")))))
=2D  (let ((type        (file-system-type fs))
=2D        (options     (file-system-options fs))
=2D        (source      (canonicalize-device-spec (file-system-device fs)))
=2D        (mount-point (string-append root "/"
=2D                                    (file-system-mount-point fs)))
=2D        (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))
=20
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 0c154d1c4e..6104b47870 100644
=2D-- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -313,22 +313,25 @@ seconds after @code{SIGTERM} has been sent are termin=
ated with
=20
 (define (file-system->fstab-entry file-system)
   "Return a @file{/etc/fstab} entry for @var{file-system}."
=2D  (string-append (match (file-system-device file-system)
=2D                   ((? file-system-label? label)
=2D                    (string-append "LABEL=3D"
=2D                                   (file-system-label->string label)))
=2D                   ((? uuid? uuid)
=2D                    (string-append "UUID=3D" (uuid->string uuid)))
=2D                   ((? string? device)
=2D                    device))
=2D                 "\t"
=2D                 (file-system-mount-point file-system) "\t"
=2D                 (file-system-type file-system) "\t"
=2D                 (or (file-system-options file-system) "defaults") "\t"
=2D
=2D                 ;; XXX: Omit the 'fs_freq' and 'fs_passno' fields becau=
se we
=2D                 ;; don't have anything sensible to put in there.
=2D                 ))
+  (let ((options (file-system-options file-system)))
+    (string-append (match (file-system-device file-system)
+                     ((? file-system-label? label)
+                      (string-append "LABEL=3D"
+                                     (file-system-label->string label)))
+                     ((? uuid? uuid)
+                      (string-append "UUID=3D" (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 becau=
se we
+                   ;; don't have anything sensible to put in there.
+                   )))
=20
 (define (file-systems->fstab file-systems)
   "Return a @file{/etc} entry for an @file{fstab} describing
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index fc383d8a5a..6dc0e6814e 100644
=2D-- a/gnu/system/file-systems.scm
+++ b/gnu/system/file-systems.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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 '()))
=2D  (options          file-system-options           ; string or #f
=2D                    (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)))
=20
+(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 "=3D")
+                 (apply cons (string-split param #\=3D))
+                 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 "=3D" 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 t=
he
 store--e.g., if FS is the root file system."
diff --git a/tests/file-systems.scm b/tests/file-systems.scm
index 4c28d0ebc5..b9f4f50aad 100644
=2D-- a/tests/file-systems.scm
+++ b/tests/file-systems.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright =C2=A9 2015, 2017 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -64,4 +65,27 @@
           (_ #f))
         (source-module-closure '((gnu system file-systems)))))
=20
+(define %fs-with-deprecated-options-string
+  (file-system
+    (device (file-system-label "btrfs-pool"))
+    (mount-point "/home")
+    (type "btrfs")
+    (options "autodefrag,subvol=3Dhome,compress=3Dlzo")))
+
+(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=3Droot,compress=3Dlzo"
+  (file-system-options->string
+   (file-system-options %fs)))
+
 (test-end)
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0006-gnu-linux-boot-Honor-the-root-options-kernel-argumen.patch
Content-Transfer-Encoding: quoted-printable

From=2067135c925b07f2e077b4cd852e07178691a10164 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 doc/guix.texi            | 10 ++++++++++
 gnu/build/linux-boot.scm | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5d526b1aee..d6bfbd7b55 100644
=2D-- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @comm=
and{modprobe} command
 must be a comma-separated list of module names---e.g.,
 @code{usbkbd,9pnet}.
=20
+@item --root-options=3D@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.  Our
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 28697e7bbf..f65e942ebc 100644
=2D-- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -2,6 +2,7 @@
 ;;; Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Guillaume Le Vaillant <glv@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE wit=
h 'loadkeys' (if
 KEYMAP-FILE is true), then setting up QEMU guest networking if
 QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file syste=
ms
 specified in MOUNTS, and finally booting into the new root if any.  The in=
itrd
=2Dsupports kernel command-line options '--load', '--root', and '--repl'.
+supports kernel command-line options '--load', '--root', '--root-options' =
and
+'--repl'.
=20
 Mount the root file system, specified by the '--root' command-line argumen=
t,
 if any.
@@ -490,10 +492,13 @@ upon error."
              (root-fs-options (if root-fs
                                   (file-system-options root-fs)
                                   '()))
=2D             (root-options (if (null? root-fs-options)
=2D                               #f
=2D                               (file-system-options->str
=2D                                root-fs-options))))
+             ;; --root-options takes precedence over the 'options' field o=
f 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)))))
=20
         (when (member "--repl" args)
           (start-repl))
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0007-gnu-linux-boot-Filter-out-file-system-independent-op.patch
Content-Transfer-Encoding: quoted-printable

From=20cb060af5ea56427e1fd63ced5f9c9edd3ae61f76 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 gnu/build/linux-boot.scm    |  3 ++-
 gnu/system/file-systems.scm | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index f65e942ebc..8e55797549 100644
=2D-- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -490,7 +490,8 @@ upon error."
                              (or (and=3D> root-fs file-system-flags)
                                  '())))
              (root-fs-options (if root-fs
=2D                                  (file-system-options root-fs)
+                                  (remove file-system-independent-mount-op=
tion?
+                                          (file-system-options root-fs))
                                   '()))
              ;; --root-options takes precedence over the 'options' field o=
f the
              ;; root <file-system> record.
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index 6dc0e6814e..2c3c159d04 100644
=2D-- a/gnu/system/file-systems.scm
+++ b/gnu/system/file-systems.scm
@@ -46,6 +46,7 @@
             file-system-location
=20
             file-system-type-predicate
+            file-system-independent-mount-option?
=20
             file-system-label
             file-system-label?
@@ -565,4 +566,20 @@ system has the given TYPE."
   (lambda (fs)
     (string=3D? (file-system-type fs) type)))
=20
+(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" "us=
ers"))
+
+(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
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0008-bootloader-grub-Allow-booting-from-a-Btrfs-subvolume.patch
Content-Transfer-Encoding: quoted-printable

From=206cf2ece21683e98544f8f46675aef58d5a7231fd Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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 pa=
th
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".
=2D--
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index d6bfbd7b55..f0956f965a 100644
=2D-- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11442,6 +11442,13 @@ a dependency of @file{/sys/fs/cgroup/cpu} and
=20
 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
=20
@@ -11491,6 +11498,113 @@ and unmount user-space FUSE file systems.  This r=
equires the
 @code{fuse.ko} kernel module to be loaded.
 @end defvr
=20
+@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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume directory)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 rootfs          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 gnu         (normal directory)
+        =E2=94=9C=E2=94=80=E2=94=80 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)
+=E2=94=9C=E2=94=80=E2=94=80 root-snapshots          (subvolume)
+    =E2=94=9C=E2=94=80=E2=94=80 root-current        (subvolume)
+        =E2=94=9C=E2=94=80=E2=94=80 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
=20
diff --git a/gnu/bootloader/depthcharge.scm b/gnu/bootloader/depthcharge.scm
index 58cc3f3932..0a50374bd9 100644
=2D-- a/gnu/bootloader/depthcharge.scm
+++ b/gnu/bootloader/depthcharge.scm
@@ -82,7 +82,8 @@
 (define* (depthcharge-configuration-file config entries
                                          #:key
                                          (system (%current-system))
=2D                                         (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.scm
index 5b4dd84965..6b5ff298e7 100644
=2D-- a/gnu/bootloader/extlinux.scm
+++ b/gnu/bootloader/extlinux.scm
@@ -28,7 +28,8 @@
 (define* (extlinux-configuration-file config entries
                                       #:key
                                       (system (%current-system))
=2D                                      (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-F=
S, a
 <file-system> object.  OLD-ENTRIES is taken to be a list of menu entries
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index b99f5fa4f4..c9794c35c2 100644
=2D-- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -4,6 +4,7 @@
 ;;; Copyright =C2=A9 2017 Leo Famulari <leo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Jan (janneke) Nieuwenhuizen <janneke@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -327,35 +328,46 @@ code."
 (define* (grub-configuration-file config entries
                                   #:key
                                   (system (%current-system))
=2D                                  (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 me=
nu
=2Dentries corresponding to old generations of the system."
+entries corresponding to old generations of the system.  BTRFS-SUBVOLUME-P=
ATH
+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)
=2D    (let ((device (menu-entry-device entry))
=2D          (device-mount-point (menu-entry-device-mount-point entry))
=2D          (label (menu-entry-label entry))
=2D          (kernel (menu-entry-linux entry))
=2D          (arguments (menu-entry-linux-arguments entry))
=2D          (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 poin=
t.
       ;; 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.
=2D      (let ((kernel  (strip-mount-point device-mount-point kernel))
=2D            (initrd  (strip-mount-point device-mount-point initrd)))
=2D        #~(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
 }~%"
=2D                  #$label
=2D                  #$(grub-root-search device kernel)
=2D                  #$kernel (string-join (list #$@arguments))
=2D                  #$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.scm
index 2e6d03272d..ebc8bf1db8 100644
=2D-- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -5,6 +5,7 @@
 ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Meiyo Peng <meiyo.peng@HIDDEN>
+;;; Copyright =C2=A9 2019 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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."
=2D  (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)))
=20
     (generate-config-file bootloader-conf (list entry)
=2D                          #:old-entries old-entries)))
+                          #:old-entries old-entries
+                          #:btrfs-subvolume-path (btrfs-store-subvolume-pa=
th
+                                                  file-systems))))
=20
 (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.scm
index 2c3c159d04..daef1c9d72 100644
=2D-- 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
=20
             file-system-type-predicate
             file-system-independent-mount-option?
+            btrfs-subvolume?
+            btrfs-store-subvolume-path
=20
             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 pai=
rs
+                    (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))))
=20
+(define (btrfs-subvolume? fs)
+  "Predicate to check if FS, a file-system object, is a Btrfs subvolume."
+  (and-let* ((btrfs-file-system? (string=3D "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 sto=
re
+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 t=
op
+level of the file system."
+
+  (define (find-mount-point-fs mount-point file-systems)
+    (find (lambda (fs)
+            (string=3D 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=3D> 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=3D> 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 here
diff --git a/gnu/tests/install.scm b/gnu/tests/install.scm
index d475bda2c7..b32130c2f3 100644
=2D-- 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))
=20
 ;;; Commentary:
@@ -811,6 +812,92 @@ build (current-guix) and then store a couple of full s=
ystem images.")
                          (command (qemu-command/writable-image image)))
       (run-basic-test %btrfs-root-os command "btrfs-root-os")))))
=20
+
+;;;
+;;; 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=3DttyS0"))
+    (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=3D--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.
=2D-=20
2.23.0


--=-=-=--

--==-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl5FsSMACgkQEmDkZILm
NWJF9g/+O6OPoFHKB/nuzm4PEpATEzzdFhpLbUXoq+pdUzybD+s+NFWgBmuLZjgG
p3XC5gFOPoOKOMaENdk3k37iOmUb5CZ2648Y7oX92nkkY/JEEtMlH4p5+DGWB8f8
jIQOzL6JPL8qXgcj4KbVPEN6l9aPogYGvTA5aAmRZOvO6sl1CHDkiaHZp8HlxOPp
0qcUtoUT9MGXk7pZ9Q2sHbACgcWJESYM2UW2XPrnvhbp2uV24vMNryjBRoJVLYk8
M1RjJzovEeNAOWeZ4I6cTMK7JuzgqJW/qDc575NtShvCKMbELRTR5YFs3cTnqHU4
q4wcz2KpToNQsFnbtM9yg1rnsQ8enkvELVIo2aRwBTnFbLEOo7EtCRZBonOVaaAz
vwQeugCECbGmZSBcpbU287EPyHFvnaNZNUXjS8rXHpc2phKLx/1SgTbVNEqNG/9s
1BTqNu65aouBTCz5NawPfqp5kaXXdQWoj+V/wUIfGHaP97jHhrlPFT5M/P3ANXP+
50KIVstTeVj7dDftKIQ+Ljhk69zj1WHh80BUZo6rjv+U24GVjJL/N3hl17+8EvBs
uoRJoqH2FaciU5hlCjm0XfF3Zng0h9Is5rPGqjpoIq8C++N9iGiL42WdqUWVmRur
ht/4kF8fLmCdr46zzBvgx64297EegO1dVUb5rkw51ZNg7358fIA=
=w4yc
-----END PGP SIGNATURE-----
--==-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 12 Feb 2020 08:47:52 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Feb 12 03:47:52 2020
Received: from localhost ([127.0.0.1]:57804 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1j1ngV-0008Ji-1X
	for submit <at> debbugs.gnu.org; Wed, 12 Feb 2020 03:47:52 -0500
Received: from mail-qk1-f193.google.com ([209.85.222.193]:35965)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1j1ngS-0008JV-K5
 for 37305 <at> debbugs.gnu.org; Wed, 12 Feb 2020 03:47:49 -0500
Received: by mail-qk1-f193.google.com with SMTP id w25so1316227qki.3
 for <37305 <at> debbugs.gnu.org>; Wed, 12 Feb 2020 00:47:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:cc:subject:references:date:in-reply-to:message-id
 :user-agent:mime-version;
 bh=XKv2g55ru1aZSrFdbEu74digtGxov61NKvpKWEeTZeU=;
 b=MrIGO4MEqTFlq2+M2ietGPHRRF4Yt/j8V+6v0kwwNYiR/1CZOTWs9Xc+HjOHMaJwZG
 4QAKgu31iGWhJA/YRl9rV4Zk3hd/hU+0nESJte+1W6BmZ4cHQbnAhQPzep6o2+eYEIgJ
 eSM8dS0/HxTOe5xUg4WVXOMdToPjqHpiBRw/9+e1UcA+9UMo9myBkTu4WCbaar32Df1s
 j2PmqPvP6nYN7iT2YmauCqXPxzRCLHNNVt1f0iAq78mx/KoD5TN7aQc8Q4AIvDfwvPk3
 J51BQZMst+oSuZyej8O50cxDSM72j/AW3fq+3LkJqHvB355ULnJkXgTDN1TGk+uJMLLy
 clYQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to
 :message-id:user-agent:mime-version;
 bh=XKv2g55ru1aZSrFdbEu74digtGxov61NKvpKWEeTZeU=;
 b=TpvAuuuK0NEZTp0f3SREaApAyYCUMcXoSUGSxtkNS9b3S0fs+PVAE6RLGKme6e0iMW
 QBLVRw5Evv7heQ+wWBOcEu/2IGpRKjTjbOpY4AXQvxSn9LkYr1j52sFaoDu5flHYFsR3
 QsXWaicYr9iTD0ZxRqnRz5IuVHJcGw56LkXKrUcPRRiY7h7+aPzrfxRYTMPdNgSvOR2v
 o3B6JwIIfuN8UL3mm/KR4ITZd8gJ5BCZWl9RsUvjmLECSojwQhtDoty5JhRN0hKBkTej
 bTwhi6HhVIDvGY18iM48X+m5V3rsrNAQXWzlhbDQKvEwb2l/pwTehlP/rU3eZPem0o60
 KEzA==
X-Gm-Message-State: APjAAAXHVCSaEaRYWpUj9XAfBsDVuJ8JPlp0RUvZbVTwqU7S/iH4iW80
 6Idgr6ZsZ26qj6coovuAbaH0/u0p
X-Google-Smtp-Source: APXvYqygqWX0ihTxbD+KeuV30wlXd5nc3KOWupAB7qDcOHH5O55/eQqNxDoVa6xPueXYataldAPn2A==
X-Received: by 2002:a37:2744:: with SMTP id n65mr9865174qkn.92.1581497262928; 
 Wed, 12 Feb 2020 00:47:42 -0800 (PST)
Received: from apteryx (dsl-154-45.b2b2c.ca. [66.158.154.45])
 by smtp.gmail.com with ESMTPSA id m68sm3478583qke.17.2020.02.12.00.47.41
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 12 Feb 2020 00:47:41 -0800 (PST)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: Ludovic =?utf-8?Q?Court=C3=A8s?= <ludo@HIDDEN>
Subject: Re: [bug#37305] [PATCH] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN> <87y2yg3t3s.fsf@HIDDEN>
Date: Wed, 12 Feb 2020 03:47:40 -0500
In-Reply-To: <87y2yg3t3s.fsf@HIDDEN> ("Ludovic
 \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\=
 \=\?utf-8\?Q\?s\?\= message of "Sun, 22 Sep 2019 23:43:03 +0200")
Message-ID: <87k14sfaz7.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--=-=-=
Content-Type: text/plain

Hello Ludovic!

My much delayed answer to your review are the attached, much improved
patches.

The new test passes and I'm already using this on one of my system successfully.

Thanks for your patience,

Maxim


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-gnu-tests-Reduce-the-time-required-to-run-the-system.patch
Content-Transfer-Encoding: quoted-printable

From 3640bea548826e1c1ec9b766da1fdfe4791d7452 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Sun, 17 Nov 2019 06:01:00 +0900
Subject: [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 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 procedu=
re.
* build-aux/run-system-tests.scm (tests-for-channel-instance): Use it, when
GUIX_DEV_HACKS is defined.
---
 build-aux/run-system-tests.scm      | 11 ++++-
 gnu/packages/package-management.scm | 66 +++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/build-aux/run-system-tests.scm b/build-aux/run-system-tests.scm
index 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 =C2=A9 2016, 2018, 2019 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -58,8 +59,16 @@ instance."
   ;; of tests to run in the usual way:
   ;;
   ;;   make check-system TESTS=3Dinstalled-os
+
+  ;; When the GUIX_DEV_HACKS environment variable is defined, override the
+  ;; package returned by `current-guix' with a flavor that saves recompili=
ng
+  ;; Guix from scratch and reuse the developer's checkout binaries.  The
+  ;; override "builds" about 20 times faster than the regular `current-gui=
x'
+  ;; 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-man=
agement.scm
index 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 'so=
urce'."
                                 #:recursive? #t
                                 #:select? (force select?))))))))
=20
+(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 RE=
PL.
+         ;; 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 n=
icer
+             ;; 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 t=
o 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 t=
he
+                 ;; 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 profil=
e,
+                         ;; we could make this package inherit from the gu=
ix
+                         ;; 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.
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-gnu-linux-boot-Ensure-volatile-root-is-mounted-read-.patch

From 97d8a635eba34c7cf0708e99bf77ef9bad1344bf Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 12:57:29 -0500
Subject: [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 is
present among the root file system flags when VOLATILE-ROOT? is #t.
---
 gnu/build/linux-boot.scm | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0003-file-systems-Add-a-file-system-device-string-procedu.patch

From 870277ade6c20546566161adbe3e6f4a5c4368a8 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 23:56:45 -0500
Subject: [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(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index 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.scm
index 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.scm
index 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.scm
index 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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0004-gnu-linux-boot-Refactor-boot-system.patch

From 347cccca292119104383aa7116b5eb7473d8a51b Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:00:06 -0500
Subject: [PATCH 4/8] 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.
---
 doc/guix.texi            |  7 ++++---
 gnu/build/linux-boot.scm | 42 +++++++++++++++++++---------------------
 2 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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 to
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0005-file-systems-Represent-the-file-system-options-as-an.patch
Content-Transfer-Encoding: quoted-printable

From 38286c910480a7102f9ae52c731eeea363f567f2 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Wed, 25 Sep 2019 22:43:41 +0900
Subject: [PATCH 5/8] 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.
---
 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(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 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.
=20
-@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 f=
or
-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.
=20
 @item @code{mount?} (default: @code{#t})
 This value indicates whether to automatically mount the file system when
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index 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))
=20
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 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 termin=
ated with
=20
 (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=3D"
-                                   (file-system-label->string label)))
-                   ((? uuid? uuid)
-                    (string-append "UUID=3D" (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=3D"
+                                     (file-system-label->string label)))
+                     ((? uuid? uuid)
+                      (string-append "UUID=3D" (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 becau=
se we
+                   ;; don't have anything sensible to put in there.
+                   )))
=20
 (define (file-systems->fstab file-systems)
   "Return a @file{/etc} entry for an @file{fstab} describing
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index 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 =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
+(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 "=3D")
+                 (apply cons (string-split param #\=3D))
+                 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 "=3D" 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 t=
he
 store--e.g., if FS is the root file system."
diff --git a/tests/file-systems.scm b/tests/file-systems.scm
index 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 =C2=A9 2015, 2017 Ludovic Court=C3=A8s <ludo@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -64,4 +65,27 @@
           (_ #f))
         (source-module-closure '((gnu system file-systems)))))
=20
+(define %fs-with-deprecated-options-string
+  (file-system
+    (device (file-system-label "btrfs-pool"))
+    (mount-point "/home")
+    (type "btrfs")
+    (options "autodefrag,subvol=3Dhome,compress=3Dlzo")))
+
+(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=3Droot,compress=3Dlzo"
+  (file-system-options->string
+   (file-system-options %fs)))
+
 (test-end)
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0006-gnu-linux-boot-Honor-the-root-options-kernel-argumen.patch
Content-Transfer-Encoding: quoted-printable

From de7043998f2a2877f47e7952a435b711a0cbe9b5 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:14:36 -0500
Subject: [PATCH 6/8] 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.
---
 doc/guix.texi            | 10 ++++++++++
 gnu/build/linux-boot.scm | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5d526b1aee..d6bfbd7b55 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -25935,6 +25935,16 @@ Instruct the initial RAM disk as well as the @comm=
and{modprobe} command
 must be a comma-separated list of module names---e.g.,
 @code{usbkbd,9pnet}.
=20
+@item --root-options=3D@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.  Our
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 28697e7bbf..f65e942ebc 100644
--- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -2,6 +2,7 @@
 ;;; Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
 ;;; Copyright =C2=A9 2019 Guillaume Le Vaillant <glv@HIDDEN>
+;;; Copyright =C2=A9 2020 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -452,7 +453,8 @@ LINUX-MODULE-DIRECTORY, then installing KEYMAP-FILE wit=
h 'loadkeys' (if
 KEYMAP-FILE is true), then setting up QEMU guest networking if
 QEMU-GUEST-NETWORKING? is true, calling PRE-MOUNT, mounting the file syste=
ms
 specified in MOUNTS, and finally booting into the new root if any.  The in=
itrd
-supports kernel command-line options '--load', '--root', and '--repl'.
+supports kernel command-line options '--load', '--root', '--root-options' =
and
+'--repl'.
=20
 Mount the root file system, specified by the '--root' command-line argumen=
t,
 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 o=
f 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)))))
=20
         (when (member "--repl" args)
           (start-repl))
--=20
2.25.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0007-gnu-linux-boot-Filter-out-file-system-independent-op.patch

From 549d585266e32cf413ae0511edd315f615f0c3a9 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Date: Tue, 11 Feb 2020 14:27:19 -0500
Subject: [PATCH 7/8] 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.
---
 gnu/build/linux-boot.scm    |  3 ++-
 gnu/system/file-systems.scm | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 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.scm
index 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


--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 22 Sep 2019 21:43:15 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Sep 22 17:43:15 2019
Received: from localhost ([127.0.0.1]:34586 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1iC9dT-0007Qc-9e
	for submit <at> debbugs.gnu.org; Sun, 22 Sep 2019 17:43:15 -0400
Received: from eggs.gnu.org ([209.51.188.92]:54564)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <ludo@HIDDEN>) id 1iC9dP-0007QK-JI
 for 37305 <at> debbugs.gnu.org; Sun, 22 Sep 2019 17:43:12 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e]:37890)
 by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from <ludo@HIDDEN>)
 id 1iC9dK-0003yv-2S; Sun, 22 Sep 2019 17:43:06 -0400
Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=54748 helo=ribbon)
 by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256)
 (Exim 4.82) (envelope-from <ludo@HIDDEN>)
 id 1iC9dJ-0007lx-Fn; Sun, 22 Sep 2019 17:43:05 -0400
From: =?utf-8?Q?Ludovic_Court=C3=A8s?= <ludo@HIDDEN>
To: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
Subject: Re: [bug#37305] [PATCH] Allow booting from a Btrfs subvolume.
References: <87sgpby4p9.fsf@HIDDEN>
Date: Sun, 22 Sep 2019 23:43:03 +0200
In-Reply-To: <87sgpby4p9.fsf@HIDDEN> (Maxim Cournoyer's message of "Thu, 05
 Sep 2019 09:20:02 +0900")
Message-ID: <87y2yg3t3s.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

Hi!

Maxim Cournoyer <maxim.cournoyer@HIDDEN> skribis:

> 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?

> From 6858efa540d89c54ce377bfa6a6882e551cd2e56 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> Date: Sun, 14 Jul 2019 20:50:23 +0900
> Subject: [PATCH 1/4] bootloader: grub: Allow booting from a Btrfs subvolu=
me.
>
> * gnu/bootloader/grub.scm (prepend-subvol, arguments->subvol): New proced=
ures.
> (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 u=
se of
> Btrfs subvolumes.

[...]

> +@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/

> --- a/gnu/bootloader/grub.scm
> +++ b/gnu/bootloader/grub.scm
> @@ -3,6 +3,7 @@
>  ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
>  ;;; Copyright =C2=A9 2017 Leo Famulari <leo@HIDDEN>
>  ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
> +;;; Copyright =C2=A9 2019 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
>  ;;;
>  ;;; 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))

=E2=80=98%not-comma=E2=80=99 is not a great API and not quite related to li=
nux-modules
:-), so it=E2=80=99s one of the rare cases where I=E2=80=99d rather keep it=
 private and
duplicate it if needed.

> +(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=3D> rootflags (cut string-tokenize <> %=
not-comma))))
> +    (and=3D> rootflags-options (cut find-long-option "subvol" <>))))

Maybe rename =E2=80=98arguments->subvol=E2=80=99 to =E2=80=98linux-argument=
s-btrfs-subvolume=E2=80=99 or
similar?

Is =E2=80=9Crootflags=E2=80=9D the commonly-used name here?

> +    (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 po=
int.
>        ;; 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 "sub=
vol"
> +      ;; 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 =E2=80=A6)
      (strip-mount-point =E2=80=A6))

than to hide the =E2=80=98if=E2=80=99 in =E2=80=98prepend-subvol=E2=80=99.

Regarding the interface, it=E2=80=99s the only time where we extract info f=
rom
the user-provided =E2=80=98kernel-arguments=E2=80=99 list.  Usually it=E2=
=80=99s the other way
around: we have =E2=80=98file-systems=E2=80=99, and from that we build up t=
he list of
kernel arguments.

Do you think it could be made to work similarly?  (I=E2=80=99m not familiar=
 with
Btrfs though.)  That way, we wouldn=E2=80=99t have to parse the kernel
arguments, the user wouldn=E2=80=99t have to fiddle explicitly with kernel
arguments, and the end result might more easily work with all the
bootloaders.

>  (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-stri=
ng
> +arguments are ignored."
>    (let ((opt (string-append option "=3D")))
> -    (and=3D> (find (cut string-prefix? opt <>)
> +    (and=3D> (find (lambda (arg)
> +                   (and (string? arg)
> +                        (string-prefix? opt arg)))
>                   arguments)
>             (lambda (arg)
>               (substring arg (+ 1 (string-index arg #\=3D)))))))

Ignoring non-strings makes for a weird API IMO.  :-)
I understand this is because, when using it on the host side, you may
now pass it gexps instead of strings.  But perhaps that calls for a new
procedure?

> From 3a628d1e731b2857a4c964484213cce980cb596f Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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!

> From 49ffe9a2645252bb708995169a9f1749f3982385 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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!

> From b56aea9c62b015c8a8b48827f9587b1578c83af3 Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
> 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 FLA=
GS
> and OPTIONS arguments; and document them.  Pass those to the `mount' call=
s.
> (boot-system): Parse the "rootflags" kernel argument, and use it when cal=
ling
> `mount-root-file-system'.
> * doc/guix.texi (Initial RAM Disk): Document the use of the "rootflags"
> argument.

We=E2=80=99ll have to wait for patch #1, but in the final patch set, it sho=
uld
probably come before patch #1, no?

Thank you!

Ludo=E2=80=99.




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at 37305 <at> debbugs.gnu.org:


Received: (at 37305) by debbugs.gnu.org; 8 Sep 2019 16:10:17 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sun Sep 08 12:10:17 2019
Received: from localhost ([127.0.0.1]:39072 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i6zlY-0002Oz-UR
	for submit <at> debbugs.gnu.org; Sun, 08 Sep 2019 12:10:17 -0400
Received: from mira.cbaines.net ([212.71.252.8]:55074)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <mail@HIDDEN>) id 1i6zlX-0002Oq-D6
 for 37305 <at> debbugs.gnu.org; Sun, 08 Sep 2019 12:10:16 -0400
Received: from localhost (cpc102582-walt20-2-0-cust14.13-2.cable.virginm.net
 [86.27.34.15])
 by mira.cbaines.net (Postfix) with ESMTPSA id 8B7CD1739C;
 Sun,  8 Sep 2019 17:10:14 +0100 (BST)
Received: from capella (localhost [127.0.0.1])
 by localhost (OpenSMTPD) with ESMTP id efc4814e;
 Sun, 8 Sep 2019 16:10:14 +0000 (UTC)
References: <87sgpby4p9.fsf@HIDDEN>
User-agent: mu4e 1.2.0; emacs 26.3
From: Christopher Baines <mail@HIDDEN>
To: maxim.cournoyer@HIDDEN
Subject: Re: [bug#37305] [PATCH] Allow booting from a Btrfs subvolume.
In-reply-to: <87sgpby4p9.fsf@HIDDEN>
Date: Sun, 08 Sep 2019 17:10:11 +0100
Message-ID: <87mufeojks.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
 micalg=pgp-sha512; protocol="application/pgp-signature"
X-Spam-Score: -0.0 (/)
X-Debbugs-Envelope-To: 37305
Cc: 37305 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--=-=-=
Content-Type: text/plain

Maxim Cournoyer <maxim.cournoyer@HIDDEN> writes:

> 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 system
test when I reported this bug [1], it's in the
0001-WIP-Btrfs-store-subvolume-test.patch file in the initial
message [2]. Maybe you could see if that passes with your changes here?

1: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=33517
2: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=33517#5

Chris

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQKTBAEBCgB9FiEEPonu50WOcg2XVOCyXiijOwuE9XcFAl11J+RfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDNF
ODlFRUU3NDU4RTcyMEQ5NzU0RTBCMjVFMjhBMzNCMEI4NEY1NzcACgkQXiijOwuE
9XeqCw//dzTr+fXTT2cQcmyIr6hHgN01PMo99uAkjkcg6wqa5sHmSAV7cilf4iQ5
GhkwUToC8swwoeXLplKB/3mSZ+Q70qkNazLOEDP6Ff6z+IXHVcbVMYbEdPb2ugri
diwnnFvBuRvH2n2JYjG8STkOfQWFcBEkL2+5Eed16KQ9OpSWyy3FHptxdpz+U6pa
GlXKkmd4zUOJ5Qg6UtYRDstohX4c2w9hMzbe1rViSrOlTVbWs3ExDm4zewY77z3W
ahVe26YK3tYBpXo+kyn8l/vYPLAzV92vSELHaKzSo40sxAczugjjIwTgB2UJDWyY
9SwRznty5DnfNgGB4DHd8QUjrmL+bNZ6SvfhFBHq1FNkGekHpo2Big3ysU1VA0II
aeTirw0H8/zS4SG6UuGpboZK4ItccbFmytrsGjiNZ5SyLlBISmXGCZejBLlHOzgj
mbsrgebene51W/H+6fSCXvlQatw7vVfnYBbhcAz86HdeeuU55+0PXAdbiSkqrHLk
+Y6YjM6FHPDTPNJaTKY7OkDSIxVmzPAoqduoQ67WVTE8Ig5AM/XKA3p7tfL6vxqF
A+a3pcgeWl/CcUMOsHiU1QnWAtezIjQ2levvcCHB/wgnDqPAYgwNs7arKXMHLoSr
jbWySATWSoLKr7eLiNzJCcSrfogBtxLcPm6OQEsx8Jap0k6a6Xo=
=y5iw
-----END PGP SIGNATURE-----
--=-=-=--




Information forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 5 Sep 2019 00:20:33 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Wed Sep 04 20:20:33 2019
Received: from localhost ([127.0.0.1]:34517 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1i5fVo-00050l-Hr
	for submit <at> debbugs.gnu.org; Wed, 04 Sep 2019 20:20:33 -0400
Received: from lists.gnu.org ([209.51.188.17]:39369)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1i5fVm-00050Y-BU
 for submit <at> debbugs.gnu.org; Wed, 04 Sep 2019 20:20:31 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:43319)
 by lists.gnu.org with esmtp (Exim 4.90_1)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1i5fVi-0006I9-Nr
 for guix-patches@HIDDEN; Wed, 04 Sep 2019 20:20:30 -0400
X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org
X-Spam-Level: 
X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM,
 SPOOFED_FREEMAIL,URIBL_BLOCKED autolearn=disabled version=3.3.2
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
 (envelope-from <maxim.cournoyer@HIDDEN>) id 1i5fVf-0008F7-8G
 for guix-patches@HIDDEN; Wed, 04 Sep 2019 20:20:26 -0400
Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:38839)
 by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)
 (Exim 4.71) (envelope-from <maxim.cournoyer@HIDDEN>)
 id 1i5fVZ-00086L-Dv
 for guix-patches@HIDDEN; Wed, 04 Sep 2019 20:20:19 -0400
Received: by mail-pg1-x542.google.com with SMTP id d10so348754pgo.5
 for <guix-patches@HIDDEN>; Wed, 04 Sep 2019 17:20:10 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
 h=from:to:subject:date:message-id:user-agent:mime-version;
 bh=TF6dtkuToyBsY9lP2ee7eiZxRBUfrz7/pOdlFL0if9Q=;
 b=DV+oUQwxtFZt8wniGLxvGRO1SEHf6ATuW07qqtyMRWnSVXYBEB0YCl3CyWqUbQeMHu
 +lnquCbiVlDpx8U6fQLQrY2T+mb20boWljSAWRxJnSh519xOanIyx4EZZOrjyLrRCS+3
 Xgo/2/zCTnEsMrpfXybb4tIT7rm0x6La1NHh4NtWasp18J841evmmRPmmafCO2lYQ8E4
 lgYDYc7Dpk/efwipABVcS2ybHLVlwdygnCQarJQzZ37JzMf+Xb9JJ1I8+iQU9S/WHley
 cKV7m7FZrs+3Iu1+fqgYYsGB04JkLFY/H/Lf9Rmj7mXcjW4TG/1nRcGxT8I8d1lNSyyy
 At5g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:subject:date:message-id:user-agent
 :mime-version;
 bh=TF6dtkuToyBsY9lP2ee7eiZxRBUfrz7/pOdlFL0if9Q=;
 b=O911fKpeqHoNKuvy1Lk+QyveD7rAiCrswEB7bgViiQkfSXN4LqGJjaQFmc8ukXOJRV
 a73uCd/UdxGnkj/6Dm1UWynItNKrnPXuGVAYYq46omNecN98aIUjEX5tFnhdcNThnAWu
 Jfu+7ynppgYMSUNGJTbZfmelpZSlxDZP9KEEIoY51oqjL3JYhx8vR7Cg5UJs4ysVfKNn
 OHSDf2p2BPet0tkazChUchMcdVJZZCWj3rHapl0YqzCrMtakp2NrGXKvRkGgD5v1k8xC
 FJN2DCppQE0BPPGZuwyhwsHDOu24a0+hMs8wL5ULalVt94WqEuzDvSsq2VfOheSnDBgw
 Zelg==
X-Gm-Message-State: APjAAAUlRh6Q4Sr8VLaqYsP3UQPsBx6k7HHPw9VZrk4ozBmHjJWY6Xei
 W3PIJU6jw68ZejOy+iQSXtdGJZNp
X-Google-Smtp-Source: APXvYqyxADqvf7AOh6R+wT/iPEFBoa8WEk0YfckRLYmS5T9Q2nduyJY2dlGOsaUQopOR8Qk3f3iHiQ==
X-Received: by 2002:a65:6904:: with SMTP id s4mr674337pgq.33.1567642808972;
 Wed, 04 Sep 2019 17:20:08 -0700 (PDT)
Received: from x200 ([240f:c7:38e9:1:314b:485c:9ba4:72c6])
 by smtp.gmail.com with ESMTPSA id d15sm231367pfo.118.2019.09.04.17.20.06
 for <guix-patches@HIDDEN>
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Wed, 04 Sep 2019 17:20:07 -0700 (PDT)
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
To: guix-patches <guix-patches@HIDDEN>
Subject: [PATCH] Allow booting from a Btrfs subvolume.
Date: Thu, 05 Sep 2019 09:20:02 +0900
Message-ID: <87sgpby4p9.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="==-=-=";
 micalg=pgp-sha256; protocol="application/pgp-signature"
X-detected-operating-system: by eggs.gnu.org: Genre and OS details not
 recognized.
X-Received-From: 2607:f8b0:4864:20::542
X-Spam-Score: -1.3 (-)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -2.3 (--)

--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: text/plain

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.


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0001-bootloader-grub-Allow-booting-from-a-Btrfs-subvolume.patch
Content-Transfer-Encoding: quoted-printable

From=206858efa540d89c54ce377bfa6a6882e551cd2e56 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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 procedur=
es.
(grub-configuration-file): Use ARGUMENTS->SUBVOL to extract the subvolume n=
ame
from the kernel arguments, and prepend it to the kernel and initrd paths us=
ing
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.
=2D--
 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

diff --git a/doc/guix.texi b/doc/guix.texi
index 707c2ba700..cc7c91ac92 100644
=2D-- 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@*
=2DCopyright @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
=20
+@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-po=
ol},
+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=3Drootfs")
+  (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.
=20
@@ -24868,6 +24882,19 @@ when you boot it on your system.
 @code{grub-bootloader} allows you to boot in particular Intel-based machin=
es
 in ``legacy'' BIOS mode.
=20
+@cindex rootflags, Grub
+@cindex Btrfs root subvolume, Grub
+To allow using a Btrfs @emph{subvolume} for the root partition, the Grub-b=
ased
+bootloaders can use a subvolume @emph{name} passed using the @code{rootfla=
gs}
+kernel argument, e.g.:
+
+@example
+(kernel-arguments '("rootflags=3Dsubvol=3D@var{root-subvolume-name}"))
+@end example
+
+to correctly populate the @code{kernel} and @code{initrd} fields of the Gr=
ub
+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.scm
index d984d5f5e3..dee6028dd0 100644
=2D-- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -3,6 +3,7 @@
 ;;; Copyright =C2=A9 2016 Chris Marusich <cmmarusich@HIDDEN>
 ;;; Copyright =C2=A9 2017 Leo Famulari <leo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
+;;; Copyright =C2=A9 2019 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; 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)))
=20
+(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)))))
=20
+(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=3D> rootflags (cut string-tokenize <> %no=
t-comma))))
+    (and=3D> 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 syste=
m."
   (define all-entries
     (append entries (bootloader-configuration-menu-entries config)))
   (define (menu-entry->gexp entry)
=2D    (let ((device (menu-entry-device entry))
=2D          (device-mount-point (menu-entry-device-mount-point entry))
=2D          (label (menu-entry-label entry))
=2D          (kernel (menu-entry-linux entry))
=2D          (arguments (menu-entry-linux-arguments entry))
=2D          (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 poin=
t.
       ;; 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.
=2D      (let ((kernel  (strip-mount-point device-mount-point kernel))
=2D            (initrd  (strip-mount-point device-mount-point initrd)))
+
+      ;; Also, in case a subvolume name could be extracted from the "subvo=
l"
+      ;; 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 ~a
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index f273957d78..7a30ebcef1 100644
=2D-- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -92,9 +92,12 @@
=20
 (define (find-long-option option arguments)
   "Find OPTION among ARGUMENTS, where OPTION is something like \"--load\".
=2DReturn 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 "=3D")))
=2D    (and=3D> (find (cut string-prefix? opt <>)
+    (and=3D> (find (lambda (arg)
+                   (and (string? arg)
+                        (string-prefix? opt arg)))
                  arguments)
            (lambda (arg)
              (substring arg (+ 1 (string-index arg #\=3D)))))))
diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm
index a149eff329..5f2efe7484 100644
=2D-- 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)
=2D  #:export (dot-ko
+  #:export (%not-comma
+            dot-ko
             ensure-dot-ko
             module-formal-name
             module-aliases
diff --git a/tests/grub.scm b/tests/grub.scm
new file mode 100644
index 0000000000..81453b00ab
=2D-- /dev/null
+++ b/tests/grub.scm
@@ -0,0 +1,51 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright =C2=A9 2019 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
+;;;
+;;; 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=3Dfoo=3Dbar,subvol=3D@,bar=3Dbaz")))
+
+(test-equal "No subvolume from arguments"
+  #f
+  (arguments->subvol '("rootflags=3Dfoo=3Dbar")))
+
+(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=3Dsubvol=3Drootfs")))
+
+(test-end "grub")
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
 filename=0002-build-initrd-Fix-write-cpio-archive-return-value.patch
Content-Transfer-Encoding: quoted-printable

From=203a628d1e731b2857a4c964484213cce980cb596f Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 gnu/build/linux-initrd.scm | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gnu/build/linux-initrd.scm b/gnu/build/linux-initrd.scm
index 3aaa06d3a0..ea7de58553 100644
=2D-- 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, r=
eturn OUTPUT."
       (cpio:write-cpio-archive files port
                                #:file->header cpio:file->cpio-header*)))
=20
=2D  (or (not compress?)
=2D
+  (if compress?
       ;; Gzip insists on adding a '.gz' suffix and does nothing if the inp=
ut
       ;; 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, r=
eturn OUTPUT."
                (unless gz-suffix?
                  (rename-file (string-append output ".gz") output))
                output)))
=2D
       output))
=20
 (define (cache-compiled-file-name file)
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=0003-linux-boot-Fix-typo.patch
Content-Transfer-Encoding: quoted-printable

From=2049ffe9a2645252bb708995169a9f1749f3982385 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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.
=2D--
 gnu/build/linux-boot.scm | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 7a30ebcef1..b4e6421b27 100644
=2D-- 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-RO=
OT?
=2Dis true, mount ROOT read-only and make it a overlay with a writable tmpfs
=2Dusing 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")
=2D-=20
2.23.0


--=-=-=
Content-Type: text/x-patch; charset=utf-8
Content-Disposition: attachment;
 filename=0004-linux-boot-Honor-rootflags-kernel-argument.patch
Content-Transfer-Encoding: quoted-printable

From=20b56aea9c62b015c8a8b48827f9587b1578c83af3 Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@HIDDEN>
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 calli=
ng
`mount-root-file-system'.
* doc/guix.texi (Initial RAM Disk): Document the use of the "rootflags"
argument.
=2D--
 doc/guix.texi            | 19 +++++++++++++++++++
 gnu/build/linux-boot.scm | 22 +++++++++++++---------
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index cc7c91ac92..1e093b38a0 100644
=2D-- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -24761,6 +24761,25 @@ Instruct the initial RAM disk as well as the @comm=
and{modprobe} command
 must be a comma-separated list of module names---e.g.,
 @code{usbkbd,9pnet}.
=20
+@item rootflags=3D@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{optio=
ns}
+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 subvol=
ume
+named ``rootfs'' as the root file system, and to enable automatic file
+defragmentation:
+
+@example
+rootflags=3Dsubvol=3Drootfs,autodefrag
+@end example
+
+Specifying the subvolume to mount by its name, as shown above, is also use=
d 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.  Our
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index b4e6421b27..b2d8f74a71 100644
=2D-- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright =C2=A9 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Cour=
t=C3=A8s <ludo@HIDDEN>
 ;;; Copyright =C2=A9 2017 Mathieu Othacehe <m.othacehe@HIDDEN>
+;;; Copyright =C2=A9 2019 Maxim Cournoyer <maxim.cournoyer@HIDDEN>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -360,15 +361,16 @@ the last argument of `mknod'."
           (filter-map string->number (scandir "/proc")))))
=20
 (define* (mount-root-file-system root type
+                                 #:optional (flags 0) options
                                  #:key volatile-root?)
=2D  "Mount the root file system of type TYPE at device ROOT.  If VOLATILE-=
ROOT?
=2Dis true, mount ROOT read-only and make it an overlay with a writable tmp=
fs
=2Dusing the kernel built-in overlayfs."
=2D
+  "Mount the root file system of type TYPE at device ROOT.  The optional F=
LAGS
+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")
=2D        (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")
=20
@@ -385,11 +387,11 @@ using the kernel built-in overlayfs."
                "lowerdir=3D/real-root,upperdir=3D/rw-root/upper,workdir=3D=
/rw-root/work"))
       (begin
         (check-file-system root type)
=2D        (mount root "/root" type)))
+        (mount root "/root" type flags options)))
=20
   ;; Make sure /root/etc/mtab is a symlink to /proc/self/mounts.
   (false-if-exception
=2D    (delete-file "/root/etc/mtab"))
+   (delete-file "/root/etc/mtab"))
   (mkdir-p "/root/etc")
   (symlink "/proc/self/mounts" "/root/etc/mtab"))
=20
@@ -483,7 +485,8 @@ upon error."
      (mount-essential-file-systems)
      (let* ((args    (linux-command-line))
             (to-load (find-long-option "--load" args))
=2D            (root    (find-long-option "--root" args)))
+            (root    (find-long-option "--root" args))
+            (rootflags (find-long-option "rootflags" args)))
=20
        (when (member "--repl" args)
          (start-repl))
@@ -526,7 +529,8 @@ upon error."
                              ((uuid root) =3D> identity)
                              (else (file-system-label root)))))
              (mount-root-file-system (canonicalize-device-spec root)
=2D                                     root-fs-type
+                                     root-fs-type 0
+                                     rootflags
                                      #:volatile-root? volatile-root?))
            (mount "none" "/root" "tmpfs"))
=20
=2D-=20
2.23.0


--=-=-=--

--==-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEJ9WGpPiQCFQyn/CfEmDkZILmNWIFAl1wVLIACgkQEmDkZILm
NWLKPhAAixwXUlhjtluKkuXgMqow/tjWQf2O0fpWJB+UrmZjJvVDWkpIsR6fOjpn
+/RdR7cDp4SqlhsNr15CwWIt0NYbNcSZGwgcVD/59Hj5YER2Nl/gBdgw8wV1jBbQ
nkW45+PhCko5WBahxOB4F53VWdPJ5YzO5mLRNSbAvH7+mRqdyctLZmqkSRfGmbb3
4/ndo3399GMzhgS1h4hc+t+jsBwFfj9SmaVNZbAyXB/5gmyCSvmcwYFMrfYaCHGT
7ZOSw/khhCKzGuzXyE8fsYsybOHuWkD2fDrOHLW9lv4F9+VyIoZgY1gAdoddAmPy
At0kxr+Lpeqf9ujlJu494A8hG+DpmgeMP2zp4pCVPcTN5S/LNqvBhzlifyf7bynj
cI5Lv15C6YNibT8Su/v27XSo4heZm8GsCtpVLkjzVJAFeQnoedFelIgot/nLAuHU
2CSEe0ZUC0IC5ltmB16T/5POVBF0dqWBgKa0xXRVyY202f6AyhY3OE3z929kgiD4
w8oBHNed2Oxq7ZTc2WdTsgJ5C1IJod+sUr6R6BtdVTZKXgH6ijA7hf35rBUSKSh5
6YgzG1J0/KoaWSICfGLUgJ8DRX7s+vDFjBCxem68ZLhwvp0vvQAyhDSEGxdeOFeB
nXbrtg0YbM4R2VJr8Ic5bcKovzlhtuwINu2Ku+Weu/6BSegyVes=
=rD4K
-----END PGP SIGNATURE-----
--==-=-=--




Acknowledgement sent to Maxim Cournoyer <maxim.cournoyer@HIDDEN>:
New bug report received and forwarded. Copy sent to guix-patches@HIDDEN. Full text available.
Report forwarded to guix-patches@HIDDEN:
bug#37305; Package guix-patches. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Tue, 31 Mar 2020 01:30:03 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.