summaryrefslogtreecommitdiff
path: root/gnu/installer/parted.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/installer/parted.scm')
-rw-r--r--gnu/installer/parted.scm55
1 files changed, 53 insertions, 2 deletions
diff --git a/gnu/installer/parted.scm b/gnu/installer/parted.scm
index fcc936a391..51fa7cf9d9 100644
--- a/gnu/installer/parted.scm
+++ b/gnu/installer/parted.scm
@@ -319,6 +319,25 @@ PARTED-OBJECT field equals PARTITION, return #f if not found."
partition))
user-partitions))
+(define (read-partition-uuid/retry file-name)
+ "Call READ-PARTITION-UUID with 5 retries spaced by 1 second. This is useful
+if the partition table is updated by the kernel at the time this function is
+called, causing the underlying /dev to be absent."
+ (define max-retries 5)
+
+ (let loop ((retry max-retries))
+ (catch #t
+ (lambda ()
+ (read-partition-uuid file-name))
+ (lambda _
+ (if (> retry 0)
+ (begin
+ (sleep 1)
+ (loop (- retry 1)))
+ (error
+ (format #f (G_ "Could not open ~a after ~a retries~%.")
+ file-name max-retries)))))))
+
;;
;; Devices
@@ -360,12 +379,44 @@ fail. See rereadpt function in wipefs.c of util-linux for an explanation."
(define %min-device-size
(* 2 GIBIBYTE-SIZE)) ;2GiB
+(define (mapped-device? device)
+ "Return #true if DEVICE is a mapped device, false otherwise."
+ (string-prefix? "/dev/dm-" device))
+
+;; TODO: Use DM_TABLE_DEPS ioctl instead of dmsetup.
+(define (mapped-device-parent-partition device)
+ "Return the parent partition path of the mapped DEVICE."
+ (let* ((command `("dmsetup" "deps" ,device "-o" "devname"))
+ (parent #f)
+ (handler
+ (lambda (input)
+ ;; We are parsing an output that should look like:
+ ;; 1 dependencies : (sda2)
+ (let ((result
+ (string-match "\\(([^\\)]+)\\)"
+ (get-string-all input))))
+ (and result
+ (set! parent
+ (format #f "/dev/~a"
+ (match:substring result 1))))))))
+ (run-external-command-with-handler handler command)
+ parent))
+
(define (eligible-devices)
"Return all the available devices except the install device and the devices
which are smaller than %MIN-DEVICE-SIZE."
(define the-installer-root-partition-path
- (installer-root-partition-path))
+ (let ((root (installer-root-partition-path)))
+ (cond
+ ((mapped-device? root)
+ ;; If the partition is a mapped device (/dev/dm-X), locate the parent
+ ;; partition. It is the case when Ventoy is used to host the
+ ;; installation image.
+ (let ((parent (mapped-device-parent-partition root)))
+ (installer-log-line "mapped device ~a -> ~a" parent root)
+ parent))
+ (else root))))
(define (small-device? device)
(let ((length (device-length device))
@@ -1108,7 +1159,7 @@ Return #t if all the statements are valid."
(need-formatting?
(user-partition-need-formatting? user-partition)))
(or need-formatting?
- (read-partition-uuid file-name)
+ (read-partition-uuid/retry file-name)
(raise
(condition
(&cannot-read-uuid