Hello! AIUI this will solve lack of /dev/fuse at startup (among other things), right? I always wondered why it wasn’t showing up automatically.
Danny Milosavljevic <[email protected]> skribis: > * gnu/build/linux-boot.scm (make-static-device-nodes): New variable. > --- > gnu/build/linux-boot.scm | 63 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm > index 2547f1e0a..f6eea96e3 100644 > --- a/gnu/build/linux-boot.scm > +++ b/gnu/build/linux-boot.scm > @@ -24,6 +24,8 @@ > #:use-module (srfi srfi-1) > #:use-module (srfi srfi-26) > #:use-module (ice-9 match) > + #:use-module (ice-9 rdelim) > + #:use-module (ice-9 popen) > #:use-module (ice-9 ftw) > #:use-module (guix build utils) > #:use-module ((guix build syscalls) > @@ -35,6 +37,7 @@ > linux-command-line > find-long-option > make-essential-device-nodes > + make-static-device-nodes > configure-qemu-networking > > bind-mount > @@ -105,6 +108,66 @@ with the given MAJOR number, starting with MINOR." > 'block-special #o644 (device-number major (+ minor i))) > (loop (+ i 1))))) > > +(define (tmpfiles-mknod name type mode-string device-number-string) > + "Given a NAME, TYPE, MODE-STRING, DEVICE-NUMBER-STRING, > + call mknod with the respective numbers." > + (let* ((mode (string->number mode-string 8)) > + (device-number-parts (string-split device-number-string #\:))) > + (match device-number-parts > + ((major-device-number-string minor-device-number-string) > + (let ((major-device-number (string->number major-device-number-string)) > + (minor-device-number (string->number > minor-device-number-string))) > + (mknod name type #o660 (device-number major-device-number > + minor-device-number)))) > + (_ #f)))) That’s a surprising name ;-), and I would suggest separating parsing from node creation (see below). > +(define (log-static-device-system-error name callback) > + "Call CALLBACK. If it fails, print an error message." > + (catch 'system-error > + (lambda () > + (callback)) > + (lambda args > + (format #t "could not create node '~a'~%" name)))) Rather: (define (report-system-error . args) (let ((errno (system-error-errno args))) (format (current-error-port) "could not create…: ~a~%" (strerror errno)))) (define-syntax-rule (catch-system-error exp) (catch 'system-error (lambda () exp) report-system-error)) (The term ‘callback’ is never used in Scheme; we just write ‘proc’ or ‘thunk’.) > +(define* (make-static-device-nodes kmod-executable-name) > + "Invoke and handle 'kmod static-nodes' output." > + ;; "kmod static-nodes --format=tmpfiles" output format: > + ;; c! /dev/fuse 0600 - - - 10:229 > + ;; d /dev/vfio 0755 - - - I checked what kmod does and in fact it just reads $LINUX_MODULE_DIRECTORY/*/modules.devname, which has a format similar to what you’re parsing here: --8<---------------cut here---------------start------------->8--- $ cat $LINUX_MODULE_DIRECTORY/*/modules.devname # Device nodes to trigger on-demand module loading. autofs4 autofs c10:235 fuse fuse c10:229 cuse cuse c10:203 btrfs btrfs-control c10:234 userio userio c10:240 vfio vfio/vfio c10:196 hci_vhci vhci c10:137 uhid uhid c10:239 vhost_net vhost-net c10:238 vhost_vsock vhost-vsock c10:241 snd_timer snd/timer c116:33 snd_seq snd/seq c116:1 --8<---------------cut here---------------end--------------->8--- Could we read that directly instead of invoking ‘kmod’? What about having a ‘static-device-nodes’ procedure that would parse that and return a list of <device-node>, where: ;; TYPE is 'char or 'block, MAJOR and MINOR are integers. (define-record-type <device-node> (device-node name type major minor module) device-node? …) and then: (define create-device-node (match-lambda (($ <device-node> name type major minor) (mknod …)))) finally: (for-each create-device-node (static-device-nodes)) ? Thanks for fixing this! Ludo’.
