diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm index 8f0f3eb2fc..8efe6e5f9c 100644 --- a/gnu/build/linux-boot.scm +++ b/gnu/build/linux-boot.scm @@ -25,6 +25,7 @@ (define-module (gnu build linux-boot) #:autoload (system repl repl) (start-repl) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) + #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:use-module (ice-9 rdelim) @@ -44,7 +45,6 @@ (define-module (gnu build linux-boot) make-static-device-nodes configure-qemu-networking - device-number boot-system)) ;;; Commentary: @@ -134,14 +134,9 @@ (define (string->major:minor string) ;; is found on the command line; our canonicalize-device-spec gives ;; up after 20 seconds. We could emulate the former by looping… (device (canonicalize-device-spec spec)) - (rdev (stat:rdev (stat device))) - ;; For backwards compatibility, device numbering is a baroque affair. - ;; This is the full 64-bit scheme used by glibc's . - (major (logior (ash (logand #x00000000000fff00 rdev) -8) - (ash (logand #xfffff00000000000 rdev) -32))) - (minor (logior (logand #x00000000000000ff rdev) - (ash (logand #x00000ffffff00000 rdev) -12)))) - (format #f "~a:~a" major minor))) + (rdev (stat:rdev (stat device)))) + (let-values (((major minor) (device-number->major+minor rdev))) + (format #f "~a:~a" major minor)))) ;; Write the resume DEVICE to this magic file, using the MAJOR:MINOR device ;; numbers if possible. The kernel will immediately try to resume from it. @@ -392,11 +387,6 @@ (define* (configure-qemu-networking #:optional (interface "eth0")) (logand (network-interface-flags sock interface) IFF_UP))) -(define (device-number major minor) - "Return the device number for the device with MAJOR and MINOR, for use as -the last argument of `mknod'." - (+ (* major 256) minor)) - (define (pidof program) "Return the PID of the first presumed instance of PROGRAM." (let ((program (basename program))) diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm index ac1b0c2eea..99a3b45004 100644 --- a/guix/build/syscalls.scm +++ b/guix/build/syscalls.scm @@ -7,6 +7,7 @@ ;;; Copyright © 2020 Julien Lepiller ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2021 Chris Marusich +;;; Copyright © 2021 Tobias Geerinckx-Rice ;;; ;;; This file is part of GNU Guix. ;;; @@ -56,6 +57,9 @@ (define-module (guix build syscalls) restart-on-EINTR + device-number + device-number->major+minor + mount? mount-device-number mount-source @@ -448,6 +452,29 @@ (define-as-needed proc (lambda* (args ...) body ...))) (module-define! (current-module) 'variable value) (module-export! (current-module) '(variable))))))) + +;;; +;;; Block devices. +;;; + +;; Convert between major:minor pairs and packed ‘device number’ representation. +;; XXX These aren't syscalls, but if you squint very hard they are part of the +;; FFI or however you want to justify me not finding a better fit… :-) +(define (device-number major minor) ; see glibc's + "Return the device number for the device with MAJOR and MINOR, for use as +the last argument of `mknod'." + (logior (ash (logand #x00000fff major) 8) + (ash (logand #xfffff000 major) 32) + (logand #x000000ff minor) + (ash (logand #xffffff00 minor) 12))) + +(define (device-number->major+minor device) ; see glibc's + "Return two values: the major and minor device numbers that make up DEVICE." + (values (logior (ash (logand #x00000000000fff00 device) -8) + (ash (logand #xfffff00000000000 device) -32)) + (logior (logand #x00000000000000ff device) + (ash (logand #x00000ffffff00000 device) -12)))) + ;;; ;;; File systems. @@ -628,7 +655,7 @@ (define (mounts) (define (string->device-number str) (match (string-split str #\:) (((= string->number major) (= string->number minor)) - (+ (* major 256) minor)))) + (device-number major minor)))) (call-with-input-file "/proc/self/mountinfo" (lambda (port) diff --git a/guix/cpio.scm b/guix/cpio.scm index 8038a11f3c..d4a7d5f1e0 100644 --- a/guix/cpio.scm +++ b/guix/cpio.scm @@ -18,6 +18,8 @@ ;;; along with GNU Guix. If not, see . (define-module (guix cpio) + #:use-module ((guix build syscalls) #:select (device-number + device-number->major+minor)) #:use-module ((guix build utils) #:select (dump-port)) #:use-module (srfi srfi-9) #:use-module (srfi srfi-11) @@ -129,8 +131,8 @@ (define* (make-cpio-header #:key (nlink 1) (mtime 0) (size 0) (dev 0) (rdev 0) (name-size 0)) "Return a new cpio file header." - (let-values (((major minor) (device->major+minor dev)) - ((rmajor rminor) (device->major+minor rdev))) + (let-values (((major minor) (device-number->major+minor dev)) + ((rmajor rminor) (device-number->major+minor rdev))) (%make-cpio-header MAGIC inode mode uid gid nlink mtime @@ -154,21 +156,6 @@ (define (mode->type mode) (else (error "unsupported file type" mode))))) -(define (device-number major minor) ; see glibc's - "Return the device number for the device with MAJOR and MINOR, for use as -the last argument of `mknod'." - (logior (ash (logand #x00000fff major) 8) - (ash (logand #xfffff000 major) 32) - (logand #x000000ff minor) - (ash (logand #xffffff00 minor) 12))) - -(define (device->major+minor device) ; see glibc's - "Return two values: the major and minor device numbers that make up DEVICE." - (values (logior (ash (logand #x00000000000fff00 device) -8) - (ash (logand #xfffff00000000000 device) -32)) - (logior (logand #x00000000000000ff device) - (ash (logand #x00000ffffff00000 device) -12)))) - (define* (file->cpio-header file #:optional (file-name file) #:key (stat lstat)) "Return a cpio header corresponding to the info returned by STAT for FILE,