From mboxrd@z Thu Jan 1 00:00:00 1970 From: ludo@gnu.org (Ludovic =?UTF-8?Q?Court=C3=A8s?=) Subject: bug#21843: Generated grub.cfg does not support encrypted roots Date: Wed, 27 Apr 2016 22:58:59 +0200 Message-ID: <87y47ywyy4.fsf@gnu.org> References: <87twozi0ql.fsf@gnu.org> <20160308192104.GA22722@solar> <20160308193309.GA2251@solar> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:41752) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1avWZ4-000128-A0 for bug-guix@gnu.org; Wed, 27 Apr 2016 17:00:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1avWZ1-0002gk-3x for bug-guix@gnu.org; Wed, 27 Apr 2016 17:00:06 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:38420) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1avWZ1-0002gW-0z for bug-guix@gnu.org; Wed, 27 Apr 2016 17:00:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1avWZ0-0007yP-QG for bug-guix@gnu.org; Wed, 27 Apr 2016 17:00:02 -0400 Sender: "Debbugs-submit" Resent-Message-ID: In-Reply-To: <20160308193309.GA2251@solar> (Andreas Enge's message of "Tue, 8 Mar 2016 20:33:09 +0100") List-Id: Bug reports for GNU Guix List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guix-bounces+gcggb-bug-guix=m.gmane.org@gnu.org Sender: "bug-Guix" To: Andreas Enge Cc: 21843@debbugs.gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Andreas Enge skribis: > What is needed are the following two lines at the beginning of grub.cfg: > > insmod luks > cryptomount -u 1aa... The attached patch does exactly that when the =E2=80=98mapped-device=E2=80= =99 source is a UUID, as is the case with the modified bare-bones.tmpl example: --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/gnu/system.scm b/gnu/system.scm index 768ca9c..da41ba6 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -210,6 +210,16 @@ as 'needed-for-boot'." (string=? (file-system-device fs) target))) file-systems))) +(define (file-system-mapped-device file-system devices) + "Return the mapped-device among DEVICES that backs FILE-SYSTEM, or #f." + (and (eq? 'device (file-system-title file-system)) + (string-prefix? "/dev/mapper/" (file-system-device file-system)) + (let ((name (string-drop (file-system-device file-system) + (string-length "/dev/mapper/")))) + (find (lambda (md) + (string=? (mapped-device-target md) name)) + devices)))) + (define (operating-system-user-mapped-devices os) "Return the subset of mapped devices that can be installed in user-land--i.e., those not needed during boot." @@ -674,6 +684,15 @@ listed in OS. The C library expects to find it under "Return the file system that contains the store of OS." (store-file-system (operating-system-file-systems os))) +(define (grub-config-for-store-file-system os) + (let ((md (file-system-mapped-device (operating-system-store-file-system os) + (operating-system-mapped-devices os)))) + (if md + (let* ((type (mapped-device-type md)) + (grub (mapped-device-kind-grub type))) + (grub (mapped-device-source md) (mapped-device-target md))) + '()))) + (define* (operating-system-grub.cfg os #:optional (old-entries '())) "Return the GRUB configuration file for OS. Use OLD-ENTRIES to populate the \"old entries\" menu." @@ -694,7 +713,8 @@ listed in OS. The C library expects to find it under #~(string-append "--load=" #$system "/boot") (operating-system-kernel-arguments os))) - (initrd #~(string-append #$system "/initrd")))))) + (initrd #~(string-append #$system "/initrd")) + (extra-lines (grub-config-for-store-file-system os)))))) (grub-configuration-file (operating-system-bootloader os) store-fs entries #:old-entries old-entries))) diff --git a/gnu/system/examples/bare-bones.tmpl b/gnu/system/examples/bare-bones.tmpl index 87e8d1e..b85593d 100644 --- a/gnu/system/examples/bare-bones.tmpl +++ b/gnu/system/examples/bare-bones.tmpl @@ -13,9 +13,13 @@ ;; Assuming /dev/sdX is the target hard disk, and "my-root" is ;; the label of the target root file system. (bootloader (grub-configuration (device "/dev/sdX"))) + (mapped-devices (list (mapped-device + (source (uuid "cb67fc72-0d54-4c88-9d4b-b225f30b0f44")) + (target "foo") + (type luks-device-mapping)))) (file-systems (cons (file-system - (device "my-root") - (title 'label) + (device "/dev/mapper/foo") + (title 'device) (mount-point "/") (type "ext4")) %base-file-systems)) diff --git a/gnu/system/grub.scm b/gnu/system/grub.scm index 45b46ca..60cc044 100644 --- a/gnu/system/grub.scm +++ b/gnu/system/grub.scm @@ -114,7 +114,9 @@ (linux menu-entry-linux) (linux-arguments menu-entry-linux-arguments (default '())) ; list of string-valued gexps - (initrd menu-entry-initrd)) ; file name of the initrd as a gexp + (initrd menu-entry-initrd) ; file name of the initrd as a gexp + (extra-lines menu-entry-extra-lines ; list of string-valued gexps + (default '()))) ;;; @@ -253,13 +255,14 @@ corresponding to old generations of the system." (define entry->gexp (match-lambda - (($ label linux arguments initrd) - #~(format port "menuentry ~s { + (($ label linux arguments initrd extra-lines) + #~(format port "menuentry ~s {~{~% ~a~} ~a linux ~a/~a ~a initrd ~a }~%" #$label + (list #$@extra-lines) #$(grub-root-search store-fs #~(string-append #$linux "/" #$linux-image-name)) @@ -268,22 +271,25 @@ corresponding to old generations of the system." (mlet %store-monad ((sugar (eye-candy config store-fs system #~port))) (define builder - #~(call-with-output-file #$output - (lambda (port) - #$sugar - (format port " + #~(begin + (use-modules (ice-9 format)) + + (call-with-output-file #$output + (lambda (port) + #$sugar + (format port " set default=~a set timeout=~a~%" - #$(grub-configuration-default-entry config) - #$(grub-configuration-timeout config)) - #$@(map entry->gexp all-entries) + #$(grub-configuration-default-entry config) + #$(grub-configuration-timeout config)) + #$@(map entry->gexp all-entries) - #$@(if (pair? old-entries) - #~((format port " + #$@(if (pair? old-entries) + #~((format port " submenu \"GNU system, old configurations...\" {~%") - #$@(map entry->gexp old-entries) - (format port "}~%")) - #~())))) + #$@(map entry->gexp old-entries) + (format port "}~%")) + #~()))))) (gexp->derivation "grub.cfg" builder))) diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm index 450b473..ddb6c8d 100644 --- a/gnu/system/mapped-devices.scm +++ b/gnu/system/mapped-devices.scm @@ -22,7 +22,11 @@ #:use-module (gnu services) #:use-module (gnu services shepherd) #:autoload (gnu packages cryptsetup) (cryptsetup) + #:autoload (gnu build file-systems) (uuid->string) #:use-module (srfi srfi-1) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:use-module (rnrs bytevectors) #:use-module (ice-9 match) #:export (mapped-device mapped-device? @@ -34,6 +38,7 @@ mapped-device-kind? mapped-device-kind-open mapped-device-kind-close + mapped-device-kind-grub device-mapping-service-type device-mapping-service @@ -59,7 +64,9 @@ mapped-device-kind? (open mapped-device-kind-open) ;source target -> gexp (close mapped-device-kind-close ;source target -> gexp - (default (const #~(const #f))))) + (default (const #~(const #f)))) + (grub mapped-device-kind-grub ;source target -> gexp list + (default #f))) ;| #f ;;; @@ -121,10 +128,21 @@ #~(zero? (system* (string-append #$cryptsetup "/sbin/cryptsetup") "close" #$target))) +(define (grub-luks-device source target) + (if (bytevector? source) + (list "insmod luks" + (string-append "cryptomount -u " (uuid->string source))) + (raise + (condition + (&message + (message (format #f "LUKS mapped-device source must be a UUID: ~s" + source))))))) + (define luks-device-mapping ;; The type of LUKS mapped devices. (mapped-device-kind (open open-luks-device) - (close close-luks-device))) + (close close-luks-device) + (grub grub-luks-device))) ;;; mapped-devices.scm ends here --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable A good way to test it (not as root!) is: --8<---------------cut here---------------start------------->8--- $ ./pre-inst-env guix system reconfigure gnu/system/examples/bare-bones.tmpl /gnu/store/fm8lbh7r3j05bkd6kbnc9xwph6rmy0rz-system /gnu/store/9l0dfdxj7ybck63r9zrgnxbyryn6f0kh-grub.cfg /gnu/store/myrc5cinlhpj2yilhzv5y0szz2ax2i6z-grub-2.00 guix system: error: symlink: Mankas permeso: "/var/guix/profiles/system-192= -link" --8<---------------cut here---------------end--------------->8--- The generated grub.cfg whose name appears above has this entry: --8<---------------cut here---------------start------------->8--- menuentry "GNU with Linux-Libre 4.5.2 (beta)" { insmod luks cryptomount -u cb67fc72-0d54-4c88-9d4b-b225f30b0f44 search --file --set /gnu/store/dd2qbz6a5pszwnzay3s8mm9yim531nz0-linux-lib= re-4.5.2/bzImage linux /gnu/store/dd2qbz6a5pszwnzay3s8mm9yim531nz0-linux-libre-4.5.2/bzIma= ge --root=3D/dev/mapper/foo --system=3D/gnu/store/fm8lbh7r3j05bkd6kbnc9xwph= 6rmy0rz-system --load=3D/gnu/store/fm8lbh7r3j05bkd6kbnc9xwph6rmy0rz-system/= boot initrd /gnu/store/fm8lbh7r3j05bkd6kbnc9xwph6rmy0rz-system/initrd } --8<---------------cut here---------------end--------------->8--- Now, I haven=E2=80=99t tested this in reality and would appreciate help her= e. We may have to add the patch to =E2=80=98guix-devel=E2=80=99 in (gnu packag= es package-management) to test it. Ludo=E2=80=99. --=-=-=--