mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 05:18:07 -05:00
mapped-devices: Ensure 'cryptsetup open' gets a tty.
Fixes <https://issues.guix.gnu.org/54770>.
Regression introduced in 400c9ed3d7
.
Previously, for an encrypted /home (say), "cryptsetup open" would be
invoked by shepherd, with /dev/null as its standard input. It would
thus run in non-interactive mode and, instead of asking for a
passphrase, fail with:
Nothing to read on input.
This change ensures it runs in interactive mode.
* gnu/build/file-systems.scm (system*/console, system*/tty): New
procedures.
* gnu/system/mapped-devices.scm (open-luks-device): Use 'system*/tty'
instead of 'system*'.
This commit is contained in:
parent
df473496ed
commit
931f13840b
2 changed files with 56 additions and 23 deletions
|
@ -1,5 +1,5 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2014-2018, 2020-2022 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016, 2017 David Craven <david@craven.ch>
|
||||
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
|
||||
;;; Copyright © 2019 Guillaume Le Vaillant <glv@posteo.net>
|
||||
|
@ -54,6 +54,7 @@ (define-module (gnu build file-systems)
|
|||
|
||||
bind-mount
|
||||
|
||||
system*/tty
|
||||
mount-flags->bit-mask
|
||||
check-file-system
|
||||
mount-file-system
|
||||
|
@ -67,6 +68,33 @@ (define-module (gnu build file-systems)
|
|||
;;;
|
||||
;;; Code:
|
||||
|
||||
(define (system*/console program . args)
|
||||
"Run PROGRAM with ARGS in a tty on top of /dev/console. The return value is
|
||||
as for 'system*'."
|
||||
(match (primitive-fork)
|
||||
(0
|
||||
(dynamic-wind
|
||||
(const #t)
|
||||
(lambda ()
|
||||
(login-tty (open-fdes "/dev/console" O_RDWR))
|
||||
(apply execlp program program args))
|
||||
(lambda ()
|
||||
(primitive-_exit 127))))
|
||||
(pid
|
||||
(cdr (waitpid pid)))))
|
||||
|
||||
(define (system*/tty program . args)
|
||||
"Run PROGRAM with ARGS, creating a tty if its standard input isn't one.
|
||||
The return value is as for 'system*'.
|
||||
|
||||
This is necessary for commands such as 'cryptsetup open' or 'fsck' that may
|
||||
need to interact with the user but might be invoked from shepherd, where
|
||||
standard input is /dev/null."
|
||||
(apply (if (isatty? (current-input-port))
|
||||
system*
|
||||
system*/console)
|
||||
program args))
|
||||
|
||||
(define (bind-mount source target)
|
||||
"Bind-mount SOURCE at TARGET."
|
||||
(mount source target "" MS_BIND))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
|
||||
;;; Copyright © 2017, 2018 Mark H Weaver <mhw@netris.org>
|
||||
;;;
|
||||
|
@ -202,7 +202,8 @@ (define (open-luks-device source targets)
|
|||
;; XXX: 'use-modules' should be at the top level.
|
||||
(use-modules (rnrs bytevectors) ;bytevector?
|
||||
((gnu build file-systems)
|
||||
#:select (find-partition-by-luks-uuid))
|
||||
#:select (find-partition-by-luks-uuid
|
||||
system*/tty))
|
||||
((guix build utils) #:select (mkdir-p)))
|
||||
|
||||
;; Create '/run/cryptsetup/' if it does not exist, as device locking
|
||||
|
@ -211,28 +212,32 @@ (define (open-luks-device source targets)
|
|||
|
||||
;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling the
|
||||
;; whole world inside the initrd (for when we're in an initrd).
|
||||
(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup")
|
||||
"open" "--type" "luks"
|
||||
;; 'cryptsetup open' requires standard input to be a tty to allow
|
||||
;; for interaction but shepherd sets standard input to /dev/null;
|
||||
;; thus, explicitly request a tty.
|
||||
(zero? (system*/tty
|
||||
#$(file-append cryptsetup-static "/sbin/cryptsetup")
|
||||
"open" "--type" "luks"
|
||||
|
||||
;; Note: We cannot use the "UUID=source" syntax here
|
||||
;; because 'cryptsetup' implements it by searching the
|
||||
;; udev-populated /dev/disk/by-id directory but udev may
|
||||
;; be unavailable at the time we run this.
|
||||
(if (bytevector? source)
|
||||
(or (let loop ((tries-left 10))
|
||||
(and (positive? tries-left)
|
||||
(or (find-partition-by-luks-uuid source)
|
||||
;; If the underlying partition is
|
||||
;; not found, try again after
|
||||
;; waiting a second, up to ten
|
||||
;; times. FIXME: This should be
|
||||
;; dealt with in a more robust way.
|
||||
(begin (sleep 1)
|
||||
(loop (- tries-left 1))))))
|
||||
(error "LUKS partition not found" source))
|
||||
source)
|
||||
;; Note: We cannot use the "UUID=source" syntax here
|
||||
;; because 'cryptsetup' implements it by searching the
|
||||
;; udev-populated /dev/disk/by-id directory but udev may
|
||||
;; be unavailable at the time we run this.
|
||||
(if (bytevector? source)
|
||||
(or (let loop ((tries-left 10))
|
||||
(and (positive? tries-left)
|
||||
(or (find-partition-by-luks-uuid source)
|
||||
;; If the underlying partition is
|
||||
;; not found, try again after
|
||||
;; waiting a second, up to ten
|
||||
;; times. FIXME: This should be
|
||||
;; dealt with in a more robust way.
|
||||
(begin (sleep 1)
|
||||
(loop (- tries-left 1))))))
|
||||
(error "LUKS partition not found" source))
|
||||
source)
|
||||
|
||||
#$target)))))))
|
||||
#$target)))))))
|
||||
|
||||
(define (close-luks-device source targets)
|
||||
"Return a gexp that closes TARGET, a LUKS device."
|
||||
|
|
Loading…
Reference in a new issue