diff options
| author | Mikhail Tsykalov <tsymsh@gmail.com> | 2020-11-06 12:47:37 +0300 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2020-11-26 00:05:39 +0100 |
| commit | 788df2ecd62d5c2fc0d94928f45c947e6393e20b (patch) | |
| tree | c91868513806a53c7780b835fd767282cec31ebe /gnu/system | |
| parent | 0a1da4652d9bb93d530ca52710f30b5d05a4251d (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.scm | 10 | ||||
| -rw-r--r-- | gnu/system/mapped-devices.scm | 174 |
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 | ||
| 99 | specifications 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 |
| 240 | TARGET (e.g., \"/dev/md0\"), using 'mdadm'." | 268 | TARGET (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. |
