summary refs log tree commit diff
path: root/gnu
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2016-10-27 13:44:13 +0200
committerLudovic Courtès <ludo@gnu.org>2016-10-27 13:48:52 +0200
commit49baaff4d2995cc4455843d7249894cb7456d8d5 (patch)
treedb58901f797cd38f1726889c9704cf2d3ecad532 /gnu
parentb800b8da2123fb6877c706a06e531b7266aee507 (diff)
downloadguix-49baaff4d2995cc4455843d7249894cb7456d8d5.tar.gz
file-systems: 'disk-partitions' detected partitions from mapped devices.
Previously, partitions of mdadm- or cryptsetup-produced block devices
would not be returned by 'disk-partitions'.

* gnu/build/file-systems.scm (disk-partitions)[last-character]: New
procedure.
[partition?]: Add 'name' parameter and rewrite.  Adjust caller.
* gnu/build/file-systems.scm (ENOENT-safe): Silently ignore ENOMEDIUM.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/build/file-systems.scm35
1 files changed, 19 insertions, 16 deletions
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index f1fccbdf2e..bfc353ae6b 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -192,15 +192,15 @@ not valid header was found."
 
 (define (disk-partitions)
   "Return the list of device names corresponding to valid disk partitions."
-  (define (partition? major minor)
-    (let ((marker (format #f "/sys/dev/block/~a:~a/partition" major minor)))
-      (catch 'system-error
-        (lambda ()
-          (not (zero? (call-with-input-file marker read))))
-        (lambda args
-          (if (= ENOENT (system-error-errno args))
-              #f
-              (apply throw args))))))
+  (define (last-character str)
+    (string-ref str (- (string-length str) 1)))
+
+  (define (partition? name major minor)
+    ;; Select device names that end in a digit, like libblkid's 'probe_all'
+    ;; function does.  Checking for "/sys/dev/block/MAJOR:MINOR/partition"
+    ;; doesn't work for partitions coming from mapped devices.
+    (and (char-set-contains? char-set:digit (last-character name))
+         (> major 2)))                      ;ignore RAM disks and floppy disks
 
   (call-with-input-file "/proc/partitions"
     (lambda (port)
@@ -217,7 +217,7 @@ not valid header was found."
               (match (string-tokenize line)
                 (((= string->number major) (= string->number minor)
                   blocks name)
-                 (if (partition? major minor)
+                 (if (partition? name major minor)
                      (loop (cons name parts))
                      (loop parts))))))))))
 
@@ -232,12 +232,15 @@ warning and #f as the result."
         ;; When running on the hand-made /dev,
         ;; 'disk-partitions' could return partitions for which
         ;; we have no /dev node.  Handle that gracefully.
-        (if (= ENOENT (system-error-errno args))
-            (begin
-              (format (current-error-port)
-                      "warning: device '~a' not found~%" device)
-              #f)
-            (apply throw args))))))
+        (let ((errno (system-error-errno args)))
+          (cond ((= ENOENT errno)
+                 (format (current-error-port)
+                         "warning: device '~a' not found~%" device)
+                 #f)
+                ((= ENOMEDIUM errno)              ;for removable media
+                 #f)
+                (else
+                 (apply throw args))))))))
 
 (define (partition-predicate read field =)
   "Return a predicate that returns true if the FIELD of partition header that