aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/build/linux-initrd.scm50
1 files changed, 44 insertions, 6 deletions
diff --git a/guix/build/linux-initrd.scm b/guix/build/linux-initrd.scm
index d7de9c14ee..05f6bf14bf 100644
--- a/guix/build/linux-initrd.scm
+++ b/guix/build/linux-initrd.scm
@@ -204,12 +204,50 @@ were found."
(disk-partitions))
(cut string-append "/dev/" <>)))
-(define (canonicalize-device-spec spec)
- "Given SPEC, a string such as \"/dev/sda1\" or \"my-root-part\", return the
-corresponding device name."
- (if (string-prefix? "/" spec)
- spec
- (or (find-partition-by-label spec) spec)))
+(define* (canonicalize-device-spec spec #:optional (title 'any))
+ "Return the device name corresponding to SPEC. TITLE is a symbol, one of
+the following:
+
+ • 'device', in which case SPEC is known to designate a device node--e.g.,
+ \"/dev/sda1\";
+ • 'label', in which case SPEC is known to designate a partition label--e.g.,
+ \"my-root-part\";
+ • 'any', in which case SPEC can be anything.
+"
+ (define max-trials
+ ;; Number of times we retry partition label resolution.
+ 7)
+
+ (define canonical-title
+ ;; The realm of canonicalization.
+ (if (eq? title 'any)
+ (if (string-prefix? "/" spec)
+ 'device
+ 'label)
+ title))
+
+ (case canonical-title
+ ((device)
+ ;; Nothing to do.
+ spec)
+ ((label)
+ ;; Resolve the label.
+ (let loop ((count 0))
+ (let ((device (find-partition-by-label spec)))
+ (or device
+ ;; Some devices take a bit of time to appear, most notably USB
+ ;; storage devices. Thus, wait for the device to appear.
+ (if (> count max-trials)
+ (begin
+ (format (current-error-port)
+ "failed to resolve partition label: ~s~%" spec)
+ (start-repl))
+ (begin
+ (sleep 1)
+ (loop (+ 1 count))))))))
+ ;; TODO: Add support for UUIDs.
+ (else
+ (error "unknown device title" title))))
(define* (make-disk-device-nodes base major #:optional (minor 0))
"Make the block device nodes around BASE (something like \"/root/dev/sda\")