all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: cmmarusich@gmail.com
To: guix-devel@gnu.org
Subject: [PATCH 03/10] Refactor grub.cfg generation logic
Date: Fri, 28 Oct 2016 03:07:20 -0700	[thread overview]
Message-ID: <20161028100727.1182-4-cmmarusich@gmail.com> (raw)
In-Reply-To: <20161028100727.1182-1-cmmarusich@gmail.com>

From: Chris Marusich <cmmarusich@gmail.com>

This enables the implementation of 'guix system switch-generation' and 'guix
system roll-back'.  Those new commands will only be able to determine the
store device and mount point for a given system generation by reading them
from that generation's boot parameters file, which does not contain a
<file-system> object.  This change makes it possible for those commands
regenerate grub.cfg using that information.

* gnu/system.scm (operating-system-grub.cfg): Instead of passing store-fs
  directly as a parameter to grub-configuration-file, pass in its mount point
  and (basically) its device.

* gnu/system/grub.scm (strip-mount-point, eye-candy, grub-root-search,
  grub-configuration-file, previous-grub-entries): Refactor these procedures
  to take a mount point and/or (basically) a device as parameters instead of a
  full-fledged <file-system> object.
---
 gnu/system.scm          | 10 ++++-
 gnu/system/grub.scm     | 98 ++++++++++++++++++++++++++-----------------------
 guix/scripts/system.scm |  3 +-
 3 files changed, 63 insertions(+), 48 deletions(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index f9f63a0..0d8c25a 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -728,6 +728,10 @@ listed in OS.  The C library expects to find it under
       ((system      (operating-system-derivation os))
        (root-fs ->  (operating-system-root-file-system os))
        (store-fs -> (operating-system-store-file-system os))
+       (grub-root-search-device -> (case (file-system-title store-fs)
+                                         ((uuid) (file-system-device store-fs))
+                                         ((label) (file-system-device store-fs))
+                                         (else #f)))
        (label ->    (kernel->grub-label (operating-system-kernel os)))
        (kernel ->   (operating-system-kernel-file os))
        (initrd      (operating-system-initrd-file os))
@@ -736,7 +740,7 @@ listed in OS.  The C library expects to find it under
                            (file-system-device root-fs)))
        (entries ->  (list (menu-entry
                            (label label)
-                           (device #f) ;; stub value, not used yet
+                           (device grub-root-search-device)
                            (linux kernel)
                            (linux-arguments
                             (cons* (string-append "--root=" root-device)
@@ -746,7 +750,9 @@ listed in OS.  The C library expects to find it under
                                    (operating-system-kernel-arguments os)))
                            (initrd initrd)))))
     (grub-configuration-file (operating-system-bootloader os)
-                             store-fs entries
+                             (file-system-mount-point store-fs)
+                             grub-root-search-device
+                             entries
                              #:old-entries old-entries)))
 
 (define (operating-system-parameters-file os)
diff --git a/gnu/system/grub.scm b/gnu/system/grub.scm
index 859f33a..d45fdca 100644
--- a/gnu/system/grub.scm
+++ b/gnu/system/grub.scm
@@ -62,16 +62,15 @@
 ;;;
 ;;; Code:
 
-(define (strip-mount-point fs file)
-  "Strip the mount point of FS from FILE, which is a gexp or other lowerable
+(define (strip-mount-point mount-point file)
+  "Strip MOUNT-POINT from FILE, which is a gexp or other lowerable
 object denoting a file name."
-  (let ((mount-point (file-system-mount-point fs)))
-    (if (string=? mount-point "/")
-	file
-	#~(let ((file #$file))
-            (if (string-prefix? #$mount-point file)
-                (substring #$file #$(string-length mount-point))
-                file)))))
+  (if (string=? mount-point "/")
+      file
+      #~(let ((file #$file))
+          (if (string-prefix? #$mount-point file)
+              (substring #$file #$(string-length mount-point))
+              file))))
 
 (define-record-type* <grub-image>
   grub-image make-grub-image
@@ -164,12 +163,15 @@ WIDTH/HEIGHT, or #f if none was found."
         (with-monad %store-monad
           (return #f)))))
 
-(define (eye-candy config root-fs system port)
-  "Return in %STORE-MONAD a gexp that writes to PORT (a port-valued gexp) the
-'grub.cfg' part concerned with graphics mode, background images, colors, and
-all that.  ROOT-FS is a file-system object denoting the root file system where
-the store is.  SYSTEM must be the target system string---e.g.,
-\"x86_64-linux\"."
+(define (eye-candy config store-fs-mount-point store-device system port)
+  "Return a gexp that writes to PORT (a port-valued gexp) the 'grub.cfg' part
+concerned with graphics mode, background images, colors, and all that.
+STORE-FS-MOUNT-POINT is the mount point of the file system containing the
+store.  STORE-DEVICE is a file system UUID, a file system label, or #f.  The
+value of STORE-DEVICE determines the GRUB search command that will be used to
+find and set the GRUB root; for details, please refer to the
+'grub-root-search' procedure's docstring.  SYSTEM must be the target system
+string---e.g., \"x86_64-linux\"."
   (define setup-gfxterm-body
     ;; Intel systems need to be switched into graphics mode, whereas most
     ;; other modern architectures have no other mode and therefore don't need
@@ -193,7 +195,7 @@ the store is.  SYSTEM must be the target system string---e.g.,
                      (symbol->string (assoc-ref colors 'bg)))))
 
   (define font-file
-    (strip-mount-point root-fs
+    (strip-mount-point store-fs-mount-point
                        (file-append grub "/share/grub/unicode.pf2")))
 
   (mlet* %store-monad ((image (grub-background-image config)))
@@ -201,7 +203,7 @@ the store is.  SYSTEM must be the target system string---e.g.,
                  #~(format #$port "
 function setup_gfxterm {~a}
 
-# Set 'root' to the partition that contains /gnu/store.
+# Set GRUB's 'root' to the device that contains the store.
 ~a
 
 if loadfont ~a; then
@@ -217,10 +219,10 @@ else
   set menu_color_highlight=white/blue
 fi~%"
                            #$setup-gfxterm-body
-                           #$(grub-root-search root-fs font-file)
+                           #$(grub-root-search store-device font-file)
                            #$font-file
 
-                           #$(strip-mount-point root-fs image)
+                           #$(strip-mount-point store-fs-mount-point image)
                            #$(theme-colors grub-theme-color-normal)
                            #$(theme-colors grub-theme-color-highlight))))))
 
@@ -229,57 +231,63 @@ fi~%"
 ;;; Configuration file.
 ;;;
 
-(define (grub-root-search root-fs file)
-  "Return the GRUB 'search' command to look for ROOT-FS, which contains FILE,
-a gexp.  The result is a gexp that can be inserted in the grub.cfg-generation
+(define (grub-root-search device file)
+  "Return a GRUB 'search' command (@pxref{search,,, grub, GNU GRUB manual})
+which will find the device indicated by DEVICE and which will set GRUB's
+'root' to it (@pxref{root,,, grub, GNU GRUB manual}).  DEVICE may be a file
+system UUID or label, in which case the search command will find the device
+containing the specified file system and set the root to it, or it may be #f,
+in which case the search command will find the device containing the specified
+FILE.  The result is a gexp that can be inserted into grub.cfg-generation
 code."
   ;; Usually FILE is a file name gexp like "/gnu/store/…-linux/vmlinuz", but
   ;; it can also be something like "(hd0,msdos1)/vmlinuz" in the case of
   ;; custom menu entries.  In the latter case, don't emit a 'search' command.
-  (if (and (string? file) (not (string-prefix? "/" file)))
-      ""
-      (case (file-system-title root-fs)
-        ;; Preferably refer to ROOT-FS by its UUID or label.  This is more
-        ;; efficient and less ambiguous, see <>.
-        ((uuid)
-         (format #f "search --fs-uuid --set ~a"
-                 (uuid->string (file-system-device root-fs))))
-        ((label)
-         (format #f "search --label --set ~a"
-                 (file-system-device root-fs)))
+  (cond ((and (string? file) (not (string-prefix? "/" file)))
+         "")
+        ((not device)
+         #~(format #f "search --file --set ~a" #$file))
+        ((string? device)
+         (format #f "search --label --set ~a" device))
         (else
-         ;; As a last resort, look for any device containing FILE.
-         #~(format #f "search --file --set ~a" #$file)))))
+         (format #f "search --fs-uuid --set ~a" (uuid->string device)))))
 
-(define* (grub-configuration-file config store-fs entries
+(define* (grub-configuration-file config
+                                  store-fs-mount-point
+                                  store-device
+                                  entries
                                   #:key
                                   (system (%current-system))
                                   (old-entries '()))
   "Return the GRUB configuration file corresponding to CONFIG, a
-<grub-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."
+<grub-configuration> object.  STORE-FS-MOUNT-POINT is the mount point of the
+file system containing the store.  STORE-DEVICE is a file system UUID, a file
+system label, or #f.  The value of STORE-DEVICE determines the GRUB search
+command that will be used to find and set the GRUB root; for details, please
+refer to the 'grub-root-search' procedure's docstring.  OLD-ENTRIES is taken
+to be a list of menu entries corresponding to old generations of the system."
   (define all-entries
     (append entries (grub-configuration-menu-entries config)))
 
   (define entry->gexp
     (match-lambda
      (($ <menu-entry> label device linux arguments initrd)
-      ;; Use the right file names for LINUX and STORE-FS in case STORE-FS is
-      ;; not the "/" file system.
-      (let ((linux  (strip-mount-point store-fs linux))
-            (initrd (strip-mount-point store-fs initrd)))
+      ;; Use the right paths in case the file system containing the store is
+      ;; not mounted at "/".
+      (let ((linux  (strip-mount-point store-fs-mount-point linux))
+            (initrd (strip-mount-point store-fs-mount-point initrd)))
         #~(format port "menuentry ~s {
   ~a
   linux ~a ~a
   initrd ~a
 }~%"
                   #$label
-                  #$(grub-root-search store-fs linux)
+                  #$(grub-root-search device linux)
                   #$linux (string-join (list #$@arguments))
                   #$initrd)))))
 
-  (mlet %store-monad ((sugar (eye-candy config store-fs system #~port)))
+  (mlet %store-monad
+      ((sugar (eye-candy config store-fs-mount-point store-device system #~port)))
     (define builder
       #~(call-with-output-file #$output
           (lambda (port)
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 8f0b8cd..4edaa0f 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -375,6 +375,7 @@ it atomically, and then run OS's activation script."
                                 read-boot-parameters))
             (label            (boot-parameters-label params))
             (root             (boot-parameters-root-device params))
+            (store            (boot-parameters-store-device params))
             (root-device      (if (bytevector? root)
                                   (uuid->string root)
                                   root))
@@ -385,7 +386,7 @@ it atomically, and then run OS's activation script."
         (label (string-append label " (#"
                               (number->string number) ", "
                               (seconds->string time) ")"))
-        (device #f) ; stub value, not used yet
+        (device store)
         (linux kernel)
         (linux-arguments
          (cons* (string-append "--root=" root-device)
-- 
2.9.2

  parent reply	other threads:[~2016-10-28 10:07 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-28 10:07 Add system roll-back and switch-generation commands cmmarusich
2016-10-28 10:07 ` [PATCH 01/10] * gnu/system.scm (<boot-parameters>): Add 'store-device' and 'store-fs-mount-point' cmmarusich
2016-10-30  0:12   ` Ludovic Courtès
2016-10-30  9:41     ` Chris Marusich
2016-10-30 22:19       ` Ludovic Courtès
2016-11-02  5:48         ` Follow-up: Add system roll-back and switch-generation commands cmmarusich
2016-11-02  5:48           ` [PATCH 1/5] profiles: Extract a procedure for getting relative generation numbers cmmarusich
2016-11-06 16:56             ` Ludovic Courtès
2016-11-02  5:48           ` [PATCH 2/5] system: Rename previous-grub-entries to profile-grub-entries cmmarusich
2016-11-06 16:56             ` Ludovic Courtès
2016-11-02  5:48           ` [PATCH 3/5] system: Optionally limit the entries returned by profile-grub-entries cmmarusich
2016-11-06 16:57             ` Ludovic Courtès
2016-11-02  5:48           ` [PATCH 4/5] install: Extract procedure: install-grub-config cmmarusich
2016-11-06 16:59             ` Ludovic Courtès
2016-11-06 21:00             ` Danny Milosavljevic
2016-11-07  1:25               ` Chris Marusich
2016-11-07 10:32                 ` Danny Milosavljevic
2016-11-02  5:48           ` [PATCH 5/5] system: Add 'guix system' actions: switch-generation and roll-back cmmarusich
2016-11-03  4:51             ` One more patch: doc: Add details to the 'guix system switch-generation' section Chris Marusich
2016-11-06 17:13             ` [PATCH 5/5] system: Add 'guix system' actions: switch-generation and roll-back Ludovic Courtès
2016-11-07  3:17               ` Chris Marusich
2016-11-03  0:19         ` [PATCH 01/10] * gnu/system.scm (<boot-parameters>): Add 'store-device' and 'store-fs-mount-point' Leo Famulari
2016-11-03  4:36           ` Chris Marusich
2016-11-03 10:35             ` Chris Marusich
2016-11-03 22:34               ` Danny Milosavljevic
2016-11-04  3:34                 ` Chris Marusich
2016-11-04  3:55                   ` Chris Marusich
2016-11-03 13:10           ` Fix a boot problem reported by ng0 cmmarusich
2016-11-03 13:10             ` [PATCH] system: Avoid using device paths in <menu-entry> device field cmmarusich
2016-11-04 15:49               ` Leo Famulari
2016-11-06 16:51               ` Ludovic Courtès
2016-10-28 10:07 ` [PATCH 02/10] Add 'device' field to <menu-entry> cmmarusich
2016-10-28 10:07 ` cmmarusich [this message]
2016-10-28 10:07 ` [PATCH 04/10] Extract procedure: relative-generation-spec->number cmmarusich
2016-10-28 10:07 ` [PATCH 05/10] Rename previous-grub-entries to grub-entries cmmarusich
2016-10-28 10:07 ` [PATCH 06/10] grub-entries: take a list of numbers on input cmmarusich
2016-10-28 10:07 ` [PATCH 07/10] Factor out procedure: install-grub-config cmmarusich
2016-10-28 10:07 ` [PATCH 08/10] Implement switch-generation and roll-back cmmarusich
2016-10-28 10:07 ` [PATCH 09/10] Rename grub-entries to profile-grub-entries cmmarusich
2016-10-28 10:07 ` [PATCH 10/10] Mention new 'guix system' features in the manual cmmarusich
2016-10-29 21:13 ` Add system roll-back and switch-generation commands Ludovic Courtès
2016-10-29 21:22   ` Chris Marusich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161028100727.1182-4-cmmarusich@gmail.com \
    --to=cmmarusich@gmail.com \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.