summaryrefslogtreecommitdiff
path: root/gnu/system
diff options
context:
space:
mode:
authorMikhail Tsykalov <tsymsh@gmail.com>2020-11-06 12:47:37 +0300
committerLudovic Courtès <ludo@gnu.org>2020-11-26 00:05:39 +0100
commit788df2ecd62d5c2fc0d94928f45c947e6393e20b (patch)
treec91868513806a53c7780b835fd767282cec31ebe /gnu/system
parent0a1da4652d9bb93d530ca52710f30b5d05a4251d (diff)
mapped-devices: Allow target to be list of strings.
* gnu/system/mapped-devices.scm (<mapped-device>): Rename constructor to %mapped-device. [target]: Remove field. [targets]: New field. Adjust users. (mapped-device-compatibility-helper, mapped-device): New macros. (mapped-device-target): New deprecated procedure. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu/system')
-rw-r--r--gnu/system/linux-initrd.scm10
-rw-r--r--gnu/system/mapped-devices.scm174
2 files changed, 108 insertions, 76 deletions
diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm
index b8a30c0abc6..3e2f1282ccc 100644
--- a/gnu/system/linux-initrd.scm
+++ b/gnu/system/linux-initrd.scm
@@ -195,11 +195,11 @@ upon error."
195 (define device-mapping-commands 195 (define device-mapping-commands
196 ;; List of gexps to open the mapped devices. 196 ;; List of gexps to open the mapped devices.
197 (map (lambda (md) 197 (map (lambda (md)
198 (let* ((source (mapped-device-source md)) 198 (let* ((source (mapped-device-source md))
199 (target (mapped-device-target md)) 199 (targets (mapped-device-targets md))
200 (type (mapped-device-type md)) 200 (type (mapped-device-type md))
201 (open (mapped-device-kind-open type))) 201 (open (mapped-device-kind-open type)))
202 (open source target))) 202 (open source targets)))
203 mapped-devices)) 203 mapped-devices))
204 204
205 (define kodir 205 (define kodir
diff --git a/gnu/system/mapped-devices.scm b/gnu/system/mapped-devices.scm
index 31c50c4e40f..8b5aec983d1 100644
--- a/gnu/system/mapped-devices.scm
+++ b/gnu/system/mapped-devices.scm
@@ -28,6 +28,7 @@
28 formatted-message 28 formatted-message
29 &fix-hint 29 &fix-hint
30 &error-location)) 30 &error-location))
31 #:use-module (guix deprecation)
31 #:use-module (gnu services) 32 #:use-module (gnu services)
32 #:use-module (gnu services shepherd) 33 #:use-module (gnu services shepherd)
33 #:use-module (gnu system uuid) 34 #:use-module (gnu system uuid)
@@ -42,10 +43,12 @@
42 #:use-module (srfi srfi-35) 43 #:use-module (srfi srfi-35)
43 #:use-module (ice-9 match) 44 #:use-module (ice-9 match)
44 #:use-module (ice-9 format) 45 #:use-module (ice-9 format)
45 #:export (mapped-device 46 #:export (%mapped-device
47 mapped-device
46 mapped-device? 48 mapped-device?
47 mapped-device-source 49 mapped-device-source
48 mapped-device-target 50 mapped-device-target
51 mapped-device-targets
49 mapped-device-type 52 mapped-device-type
50 mapped-device-location 53 mapped-device-location
51 54
@@ -70,15 +73,36 @@
70;;; 73;;;
71;;; Code: 74;;; Code:
72 75
73(define-record-type* <mapped-device> mapped-device 76(define-record-type* <mapped-device> %mapped-device
74 make-mapped-device 77 make-mapped-device
75 mapped-device? 78 mapped-device?
76 (source mapped-device-source) ;string | list of strings 79 (source mapped-device-source) ;string | list of strings
77 (target mapped-device-target) ;string 80 (targets mapped-device-targets) ;list of strings
78 (type mapped-device-type) ;<mapped-device-kind> 81 (type mapped-device-type) ;<mapped-device-kind>
79 (location mapped-device-location 82 (location mapped-device-location
80 (default (current-source-location)) (innate))) 83 (default (current-source-location)) (innate)))
81 84
85(define-syntax mapped-device-compatibility-helper
86 (syntax-rules (target)
87 ((_ () (fields ...))
88 (%mapped-device fields ...))
89 ((_ ((target exp) rest ...) (others ...))
90 (%mapped-device others ...
91 (targets (list exp))
92 rest ...))
93 ((_ (field rest ...) (others ...))
94 (mapped-device-compatibility-helper (rest ...)
95 (others ... field)))))
96
97(define-syntax-rule (mapped-device fields ...)
98 "Build an <mapped-device> record, automatically converting 'target' field
99specifications to 'targets'."
100 (mapped-device-compatibility-helper (fields ...) ()))
101
102(define-deprecated (mapped-device-target md)
103 mapped-device-targets
104 (car (mapped-device-targets md)))
105
82(define-record-type* <mapped-device-type> mapped-device-kind 106(define-record-type* <mapped-device-type> mapped-device-kind
83 make-mapped-device-kind 107 make-mapped-device-kind
84 mapped-device-kind? 108 mapped-device-kind?
@@ -97,14 +121,14 @@
97 (shepherd-service-type 121 (shepherd-service-type
98 'device-mapping 122 'device-mapping
99 (match-lambda 123 (match-lambda
100 (($ <mapped-device> source target 124 (($ <mapped-device> source targets
101 ($ <mapped-device-type> open close)) 125 ($ <mapped-device-type> open close))
102 (shepherd-service 126 (shepherd-service
103 (provision (list (symbol-append 'device-mapping- (string->symbol target)))) 127 (provision (list (symbol-append 'device-mapping- (string->symbol (string-join targets "-")))))
104 (requirement '(udev)) 128 (requirement '(udev))
105 (documentation "Map a device node using Linux's device mapper.") 129 (documentation "Map a device node using Linux's device mapper.")
106 (start #~(lambda () #$(open source target))) 130 (start #~(lambda () #$(open source targets)))
107 (stop #~(lambda _ (not #$(close source target)))) 131 (stop #~(lambda _ (not #$(close source targets))))
108 (respawn? #f)))))) 132 (respawn? #f))))))
109 133
110(define (device-mapping-service mapped-device) 134(define (device-mapping-service mapped-device)
@@ -162,48 +186,52 @@ option of @command{guix system}.\n")
162;;; Common device mappings. 186;;; Common device mappings.
163;;; 187;;;
164 188
165(define (open-luks-device source target) 189(define (open-luks-device source targets)
166 "Return a gexp that maps SOURCE to TARGET as a LUKS device, using 190 "Return a gexp that maps SOURCE to TARGET as a LUKS device, using
167'cryptsetup'." 191'cryptsetup'."
168 (with-imported-modules (source-module-closure 192 (with-imported-modules (source-module-closure
169 '((gnu build file-systems))) 193 '((gnu build file-systems)))
170 #~(let ((source #$(if (uuid? source) 194 (match targets
171 (uuid-bytevector source) 195 ((target)
172 source))) 196 #~(let ((source #$(if (uuid? source)
173 ;; XXX: 'use-modules' should be at the top level. 197 (uuid-bytevector source)
174 (use-modules (rnrs bytevectors) ;bytevector? 198 source)))
175 ((gnu build file-systems) 199 ;; XXX: 'use-modules' should be at the top level.
176 #:select (find-partition-by-luks-uuid))) 200 (use-modules (rnrs bytevectors) ;bytevector?
177 201 ((gnu build file-systems)
178 ;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling the 202 #:select (find-partition-by-luks-uuid)))
179 ;; whole world inside the initrd (for when we're in an initrd). 203
180 (zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") 204 ;; Use 'cryptsetup-static', not 'cryptsetup', to avoid pulling the
181 "open" "--type" "luks" 205 ;; whole world inside the initrd (for when we're in an initrd).
182 206 (zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup")
183 ;; Note: We cannot use the "UUID=source" syntax here 207 "open" "--type" "luks"
184 ;; because 'cryptsetup' implements it by searching the 208
185 ;; udev-populated /dev/disk/by-id directory but udev may 209 ;; Note: We cannot use the "UUID=source" syntax here
186 ;; be unavailable at the time we run this. 210 ;; because 'cryptsetup' implements it by searching the
187 (if (bytevector? source) 211 ;; udev-populated /dev/disk/by-id directory but udev may
188 (or (let loop ((tries-left 10)) 212 ;; be unavailable at the time we run this.
189 (and (positive? tries-left) 213 (if (bytevector? source)
190 (or (find-partition-by-luks-uuid source) 214 (or (let loop ((tries-left 10))
191 ;; If the underlying partition is 215 (and (positive? tries-left)
192 ;; not found, try again after 216 (or (find-partition-by-luks-uuid source)
193 ;; waiting a second, up to ten 217 ;; If the underlying partition is
194 ;; times. FIXME: This should be 218 ;; not found, try again after
195 ;; dealt with in a more robust way. 219 ;; waiting a second, up to ten
196 (begin (sleep 1) 220 ;; times. FIXME: This should be
197 (loop (- tries-left 1)))))) 221 ;; dealt with in a more robust way.
198 (error "LUKS partition not found" source)) 222 (begin (sleep 1)
199 source) 223 (loop (- tries-left 1))))))
200 224 (error "LUKS partition not found" source))
201 #$target))))) 225 source)
202 226
203(define (close-luks-device source target) 227 #$target)))))))
228
229(define (close-luks-device source targets)
204 "Return a gexp that closes TARGET, a LUKS device." 230 "Return a gexp that closes TARGET, a LUKS device."
205 #~(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup") 231 (match targets
206 "close" #$target))) 232 ((target)
233 #~(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup")
234 "close" #$target)))))
207 235
208(define* (check-luks-device md #:key 236(define* (check-luks-device md #:key
209 needed-for-boot? 237 needed-for-boot?
@@ -235,36 +263,40 @@ option of @command{guix system}.\n")
235 (close close-luks-device) 263 (close close-luks-device)
236 (check check-luks-device))) 264 (check check-luks-device)))
237 265
238(define (open-raid-device sources target) 266(define (open-raid-device sources targets)
239 "Return a gexp that assembles SOURCES (a list of devices) to the RAID device 267 "Return a gexp that assembles SOURCES (a list of devices) to the RAID device
240TARGET (e.g., \"/dev/md0\"), using 'mdadm'." 268TARGET (e.g., \"/dev/md0\"), using 'mdadm'."
241 #~(let ((sources '#$sources) 269 (match targets
242 270 ((target)
243 ;; XXX: We're not at the top level here. We could use a 271 #~(let ((sources '#$sources)
244 ;; non-top-level 'use-modules' form but that doesn't work when the 272
245 ;; code is eval'd, like the Shepherd does. 273 ;; XXX: We're not at the top level here. We could use a
246 (every (@ (srfi srfi-1) every)) 274 ;; non-top-level 'use-modules' form but that doesn't work when the
247 (format (@ (ice-9 format) format))) 275 ;; code is eval'd, like the Shepherd does.
248 (let loop ((attempts 0)) 276 (every (@ (srfi srfi-1) every))
249 (unless (every file-exists? sources) 277 (format (@ (ice-9 format) format)))
250 (when (> attempts 20) 278 (let loop ((attempts 0))
251 (error "RAID devices did not show up; bailing out" 279 (unless (every file-exists? sources)
252 sources)) 280 (when (> attempts 20)
253 281 (error "RAID devices did not show up; bailing out"
254 (format #t "waiting for RAID source devices~{ ~a~}...~%" 282 sources))
255 sources) 283
256 (sleep 1) 284 (format #t "waiting for RAID source devices~{ ~a~}...~%"
257 (loop (+ 1 attempts)))) 285 sources)
258 286 (sleep 1)
259 ;; Use 'mdadm-static' rather than 'mdadm' to avoid pulling its whole 287 (loop (+ 1 attempts))))
260 ;; closure (80 MiB) in the initrd when a RAID device is needed for boot. 288
261 (zero? (apply system* #$(file-append mdadm-static "/sbin/mdadm") 289 ;; Use 'mdadm-static' rather than 'mdadm' to avoid pulling its whole
262 "--assemble" #$target sources)))) 290 ;; closure (80 MiB) in the initrd when a RAID device is needed for boot.
263 291 (zero? (apply system* #$(file-append mdadm-static "/sbin/mdadm")
264(define (close-raid-device sources target) 292 "--assemble" #$target sources))))))
293
294(define (close-raid-device sources targets)
265 "Return a gexp that stops the RAID device TARGET." 295 "Return a gexp that stops the RAID device TARGET."
266 #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm") 296 (match targets
267 "--stop" #$target))) 297 ((target)
298 #~(zero? (system* #$(file-append mdadm-static "/sbin/mdadm")
299 "--stop" #$target)))))
268 300
269(define raid-device-mapping 301(define raid-device-mapping
270 ;; The type of RAID mapped devices. 302 ;; The type of RAID mapped devices.