summaryrefslogtreecommitdiff
path: root/gnu/build
diff options
context:
space:
mode:
authorRutherther <rutherther@ditigal.xyz>2026-02-04 19:19:19 +0100
committerMaxim Cournoyer <maxim@guixotic.coop>2026-02-23 11:46:09 +0900
commite3d8fc1147d03b6e6a47f8f1976068ad0faec9ab (patch)
tree8bcde4a5676f5a83d3dee9dc2d3da68ef0c5e0f1 /gnu/build
parentd45da4a5e932aba8d59e08e29ff3db2a3c2179c3 (diff)
file-systems: mount-file-system: Guard against missing devices.
When a device with a UUID is missing, canonicalize-device-spec will throw an error. This error is not handled for mount-may-fail? devices. That means that if you use UUID device and it isn't available, the boot will hang on the user-file-systems not being started. All user services depend on that service. Also added a test for this behavior. * gnu/build/file-systems.scm (mount-file-system): Guard canonicalize-device-spec call. (canonicalize-device-spec): Throw &partition-lookup-error on missing partition. (&partition-lookup-error): New variable. * gnu/tests/base.scm (%test-missing-file-system): New variable. Change-Id: I3b8d652251cef421cff6d2fdafb8d9d7d1fc74b5 Reported-By: renbus, on IRC Signed-off-by: Maxim Cournoyer <maxim@guixotic.coop>
Diffstat (limited to 'gnu/build')
-rw-r--r--gnu/build/file-systems.scm80
1 files changed, 54 insertions, 26 deletions
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index d25b798b117..72d7f5f2601 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -37,6 +37,7 @@
37 #:use-module (guix i18n) 37 #:use-module (guix i18n)
38 #:use-module (rnrs io ports) 38 #:use-module (rnrs io ports)
39 #:use-module (rnrs bytevectors) 39 #:use-module (rnrs bytevectors)
40 #:use-module (ice-9 exceptions)
40 #:use-module (ice-9 match) 41 #:use-module (ice-9 match)
41 #:use-module (ice-9 rdelim) 42 #:use-module (ice-9 rdelim)
42 #:use-module (ice-9 regex) 43 #:use-module (ice-9 regex)
@@ -45,6 +46,8 @@
45 #:autoload (system repl repl) (start-repl) 46 #:autoload (system repl repl) (start-repl)
46 #:use-module (srfi srfi-1) 47 #:use-module (srfi srfi-1)
47 #:use-module (srfi srfi-26) 48 #:use-module (srfi srfi-26)
49 #:use-module (srfi srfi-34)
50 #:use-module (srfi srfi-35)
48 #:export (disk-partitions 51 #:export (disk-partitions
49 partition-label-predicate 52 partition-label-predicate
50 partition-uuid-predicate 53 partition-uuid-predicate
@@ -65,6 +68,9 @@
65 68
66 cleanly-unmounted-ext2? 69 cleanly-unmounted-ext2?
67 70
71 partition-lookup-error?
72 &partition-lookup-error
73
68 bind-mount 74 bind-mount
69 75
70 system*/tty 76 system*/tty
@@ -1182,6 +1188,10 @@ were found."
1182(define find-partition-by-luks-uuid 1188(define find-partition-by-luks-uuid
1183 (find-partition luks-partition-uuid-predicate)) 1189 (find-partition luks-partition-uuid-predicate))
1184 1190
1191(define-condition-type &partition-lookup-error &condition
1192 partition-lookup-error?
1193 (spec partition-lookup-error-spec))
1194
1185 1195
1186(define (canonicalize-device-spec spec) 1196(define (canonicalize-device-spec spec)
1187 "Return the device name corresponding to SPEC, which can be a <uuid>, a 1197 "Return the device name corresponding to SPEC, which can be a <uuid>, a
@@ -1201,7 +1211,9 @@ file name or an nfs-root containing ':/')."
1201 ;; Some devices take a bit of time to appear, most notably USB 1211 ;; Some devices take a bit of time to appear, most notably USB
1202 ;; storage devices. Thus, wait for the device to appear. 1212 ;; storage devices. Thus, wait for the device to appear.
1203 (if (> count max-trials) 1213 (if (> count max-trials)
1204 (error "failed to resolve partition" (fmt spec)) 1214 (raise (condition
1215 (&partition-lookup-error
1216 (spec (fmt spec)))))
1205 (begin 1217 (begin
1206 (format #t "waiting for partition '~a' to appear...~%" 1218 (format #t "waiting for partition '~a' to appear...~%"
1207 (fmt spec)) 1219 (fmt spec))
@@ -1319,6 +1331,14 @@ corresponds to the symbols listed in FLAGS."
1319 (() 1331 (()
1320 0)))) 1332 0))))
1321 1333
1334(define kind-and-args-exception?
1335 (exception-predicate &exception-with-kind-and-args))
1336
1337(define (system-error? exception)
1338 "Return true if EXCEPTION is a Guile 'system-error exception."
1339 (and (kind-and-args-exception? exception)
1340 (eq? 'system-error (exception-kind exception))))
1341
1322(define* (mount-file-system fs #:key (root "/root") 1342(define* (mount-file-system fs #:key (root "/root")
1323 (check? (file-system-check? fs)) 1343 (check? (file-system-check? fs))
1324 (skip-check-if-clean? 1344 (skip-check-if-clean?
@@ -1339,8 +1359,8 @@ corresponds to the symbols listed in FLAGS."
1339 (host-part (string-take source idx)) 1359 (host-part (string-take source idx))
1340 ;; Strip [] from around host if present 1360 ;; Strip [] from around host if present
1341 (host (match (string-split host-part (string->char-set "[]")) 1361 (host (match (string-split host-part (string->char-set "[]"))
1342 (("" h "") h) 1362 (("" h "") h)
1343 ((h) h))) 1363 ((h) h)))
1344 (inet-addr (host-to-ip host "nfs"))) 1364 (inet-addr (host-to-ip host "nfs")))
1345 ;; Mounting an NFS file system requires passing the address 1365 ;; Mounting an NFS file system requires passing the address
1346 ;; of the server in the addr= option 1366 ;; of the server in the addr= option
@@ -1426,26 +1446,37 @@ corresponds to the symbols listed in FLAGS."
1426 "," 'prefix) 1446 "," 'prefix)
1427 ""))))) 1447 "")))))
1428 1448
1429 (let* ((type (file-system-type fs)) 1449 (guard (c ((partition-lookup-error? c)
1430 (source (canonicalize-device-spec (file-system-device fs))) 1450 (format (current-error-port)
1431 (target (string-append root "/" 1451 "could not find the partition: ~a~%"
1432 (file-system-mount-point fs))) 1452 (partition-lookup-error-spec c))
1433 (flags (logior (mount-flags->bit-mask (file-system-flags fs)) 1453 (unless (file-system-mount-may-fail? fs)
1434 1454 (raise c)))
1435 ;; For bind mounts, preserve the original flags such 1455 ((system-error? c)
1436 ;; as MS_NOSUID, etc. Failing to do that, the 1456 (format (current-error-port)
1437 ;; MS_REMOUNT call below fails with EPERM. 1457 "could not mount partition ~a: ~a~%"
1438 ;; See <https://bugs.gnu.org/46292> 1458 (file-system-device fs)
1439 (if (memq 'bind-mount (file-system-flags fs)) 1459 (exception-message c))
1440 (statfs-flags->mount-flags 1460 (unless (file-system-mount-may-fail? fs)
1441 (file-system-mount-flags (statfs source))) 1461 (raise c))))
1442 0))) 1462 (let* ((type (file-system-type fs))
1443 (options (file-system-options fs))) 1463 (source (canonicalize-device-spec (file-system-device fs)))
1444 (when check? 1464 (target (string-append root "/"
1445 (check-file-system source type (not skip-check-if-clean?) repair)) 1465 (file-system-mount-point fs)))
1466 (flags (logior (mount-flags->bit-mask (file-system-flags fs))
1467
1468 ;; For bind mounts, preserve the original flags such
1469 ;; as MS_NOSUID, etc. Failing to do that, the
1470 ;; MS_REMOUNT call below fails with EPERM.
1471 ;; See <https://bugs.gnu.org/46292>
1472 (if (memq 'bind-mount (file-system-flags fs))
1473 (statfs-flags->mount-flags
1474 (file-system-mount-flags (statfs source)))
1475 0)))
1476 (options (file-system-options fs)))
1477 (when check?
1478 (check-file-system source type (not skip-check-if-clean?) repair))
1446 1479
1447 (catch 'system-error
1448 (lambda ()
1449 ;; Create the mount point. Most of the time this is a directory, but 1480 ;; Create the mount point. Most of the time this is a directory, but
1450 ;; in the case of a bind mount, a regular file or socket may be 1481 ;; in the case of a bind mount, a regular file or socket may be
1451 ;; needed. 1482 ;; needed.
@@ -1474,10 +1505,7 @@ corresponds to the symbols listed in FLAGS."
1474 (when (and (= MS_BIND (logand flags MS_BIND)) 1505 (when (and (= MS_BIND (logand flags MS_BIND))
1475 (= MS_RDONLY (logand flags MS_RDONLY))) 1506 (= MS_RDONLY (logand flags MS_RDONLY)))
1476 (let ((flags (logior MS_REMOUNT flags))) 1507 (let ((flags (logior MS_REMOUNT flags)))
1477 (mount source target type flags options)))) 1508 (mount source target type flags options))))))
1478 (lambda args
1479 (or (file-system-mount-may-fail? fs)
1480 (apply throw args))))))
1481 1509
1482(define %device-name-regexp "/dev/[hsvw]d([abcd])([0-9]*)") 1510(define %device-name-regexp "/dev/[hsvw]d([abcd])([0-9]*)")
1483(define %hurd-device-name-regexp "part:([0-9]*):device:[hw]d([0-9]*)") 1511(define %hurd-device-name-regexp "part:([0-9]*):device:[hw]d([0-9]*)")