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.
This commit is contained in:
Ludovic Courtès 2016-10-27 13:44:13 +02:00
parent b800b8da21
commit 49baaff4d2
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 19 additions and 16 deletions

View File

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