From 1b6a05aec5b5f08f46081e2a57c6ccf3cb35cd04 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Fri, 26 Apr 2024 22:00:31 +0100 Subject: [PATCH] make uevent-watch use devout instead of direct netlink --- modules/mdevd.nix | 12 ++- modules/mount/default.nix | 5 +- pkgs/uevent-watch/events.txt | 169 +++++------------------------------ pkgs/uevent-watch/test.fnl | 16 ++-- pkgs/uevent-watch/watch.fnl | 41 +++++---- 5 files changed, 63 insertions(+), 180 deletions(-) diff --git a/modules/mdevd.nix b/modules/mdevd.nix index 73e81d3..e674763 100644 --- a/modules/mdevd.nix +++ b/modules/mdevd.nix @@ -13,10 +13,14 @@ in { notification-fd = 10; run = "${pkgs.devout}/bin/devout /run/devout.sock 4"; }; - mdevd-coldplug = oneshot { - name ="mdev-coldplug"; - up = "${pkgs.mdevd}/bin/mdevd-coldplug -O 4"; - dependencies = [devout]; + coldplug = oneshot { + name ="coldplug"; + # would love to know what mdevd-coldplug/udevadm trigger does + # that this doesn't + up = '' + for i in $(find /sys -name uevent); do ( echo change > $i ) ; done + ''; + dependencies = [devout mdevd]; }; }; }; diff --git a/modules/mount/default.nix b/modules/mount/default.nix index 76e1cf5..50e9ef2 100644 --- a/modules/mount/default.nix +++ b/modules/mount/default.nix @@ -44,7 +44,10 @@ in { in svc // { build = args: let args' = args // { - dependencies = (args.dependencies or []) ++ [config.services.mdevd]; + dependencies = (args.dependencies or []) ++ [ + config.services.mdevd + config.services.devout + ]; }; in svc.build args' ; }; diff --git a/pkgs/uevent-watch/events.txt b/pkgs/uevent-watch/events.txt index 3da77b6..2df5c51 100644 --- a/pkgs/uevent-watch/events.txt +++ b/pkgs/uevent-watch/events.txt @@ -1,154 +1,25 @@ -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1 +add@/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1 ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1 -SUBSYSTEM=usb -MAJOR=189 -MINOR=1 -DEVNAME=bus/usb/001/002 -DEVTYPE=usb_device -PRODUCT=46f4/1/0 -TYPE=0/0/0 -BUSNUM=001 -DEVNUM=002 -SEQNUM=1513 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0 -SUBSYSTEM=usb -DEVTYPE=usb_interface -PRODUCT=46f4/1/0 -TYPE=0/0/0 -INTERFACE=8/6/80 -MODALIAS=usb:v46F4p0001d0000dc00dsc00dp00ic08isc06ip50in00 -SEQNUM=1514 - -add@/devices/virtual/workqueue/scsi_tmf_0 -ACTION=add -DEVPATH=/devices/virtual/workqueue/scsi_tmf_0 -SUBSYSTEM=workqueue -SEQNUM=1515 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0 -SUBSYSTEM=scsi -DEVTYPE=scsi_host -SEQNUM=1516 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/scsi_host/host0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/scsi_host/host0 -SUBSYSTEM=scsi_host -SEQNUM=1517 - -bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0 -ACTION=bind -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0 -SUBSYSTEM=usb -DEVTYPE=usb_interface -DRIVER=usb-storage -PRODUCT=46f4/1/0 -TYPE=0/0/0 -INTERFACE=8/6/80 -MODALIAS=usb:v46F4p0001d0000dc00dsc00dp00ic08isc06ip50in00 -SEQNUM=1518 - -bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1 -ACTION=bind -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1 -SUBSYSTEM=usb -MAJOR=189 -MINOR=1 -DEVNAME=bus/usb/001/002 -DEVTYPE=usb_device -DRIVER=usb -PRODUCT=46f4/1/0 -TYPE=0/0/0 -BUSNUM=001 -DEVNUM=002 -SEQNUM=1519 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0 -SUBSYSTEM=scsi -DEVTYPE=scsi_target -SEQNUM=1520 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -SUBSYSTEM=scsi -DEVTYPE=scsi_device -MODALIAS=scsi:t-0x00 -SEQNUM=1521 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_device/0:0:0:0 -SUBSYSTEM=scsi_device -SEQNUM=1522 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/scsi_disk/0:0:0:0 -SUBSYSTEM=scsi_disk -SEQNUM=1523 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/bsg/0:0:0:0 -SUBSYSTEM=bsg -MAJOR=252 -MINOR=0 -DEVNAME=bsg/0:0:0:0 -SEQNUM=1524 - -change@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -ACTION=change -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -SUBSYSTEM=scsi -SDEV_UA=POWER_ON_RESET_OCCURRED -DEVTYPE=scsi_device -DRIVER=sd -MODALIAS=scsi:t-0x00 -SEQNUM=1525 - -add@/devices/virtual/bdi/8:0 -ACTION=add -DEVPATH=/devices/virtual/bdi/8:0 -SUBSYSTEM=bdi -SEQNUM=1526 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda +DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1 SUBSYSTEM=block -MAJOR=8 -MINOR=0 -DEVNAME=sda -DEVTYPE=disk -DISKSEQ=2 -SEQNUM=1527 - -add@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 -ACTION=add -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1 -SUBSYSTEM=block -MAJOR=8 -MINOR=1 -DEVNAME=sda1 +DEVNAME=/dev/sdb1 DEVTYPE=partition -DISKSEQ=2 +DISKSEQ=33 PARTN=1 -SEQNUM=1528 +SEQNUM=82381 +MAJOR=8 +PARTNAME=backup-disk +MINOR=17 -bind@/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -ACTION=bind -DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 -SUBSYSTEM=scsi -DEVTYPE=scsi_device -DRIVER=sd -MODALIAS=scsi:t-0x00 -SEQNUM=1529 +remove@/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1 +ACTION=remove +DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/host1/target1:0:0/1:0:0:0/block/sdb/sdb1 +SUBSYSTEM=block +DEVNAME=/dev/sdb1 +DEVTYPE=partition +DISKSEQ=33 +PARTN=1 +SEQNUM=82386 +PARTNAME=backup-disk +MAJOR=8 +MINOR=17 diff --git a/pkgs/uevent-watch/test.fnl b/pkgs/uevent-watch/test.fnl index eaebc33..a39f35c 100644 --- a/pkgs/uevent-watch/test.fnl +++ b/pkgs/uevent-watch/test.fnl @@ -1,11 +1,6 @@ -(local { : view} (require :fennel)) -(import-macros { : expect= } :anoia.assert) +(local watch (require :watch)) -(local subject (require :watch)) - - - -;; Events come from the netlink socket as an initial summary line +;; Events come from the devout socket as an initial summary line ;; followed by a NUL character followed by newline-separated key=value ;; pairs. For ease of editing we don't have NULs in events.txt, ;; so we need to massage it into shape here @@ -27,8 +22,11 @@ ;; this tests event parsing but not whether anything ;; happens as a result of processing them -(subject.run-with-fh - { :read (next-event) } +(watch.run-with-fh + { + :read (next-event) + :write (fn [payload] ) + } ["-s" "foo" "-n" (os.getenv "TMPDIR") "partname=backup-disk" ] ) diff --git a/pkgs/uevent-watch/watch.fnl b/pkgs/uevent-watch/watch.fnl index 1988596..a222185 100644 --- a/pkgs/uevent-watch/watch.fnl +++ b/pkgs/uevent-watch/watch.fnl @@ -1,25 +1,19 @@ (local { : assoc : system : dirname } (require :anoia)) (local { : mktree : rmtree : symlink } (require :anoia.fs)) +(local { : AF_LOCAL : SOCK_STREAM } (require :anoia.net.constants)) +(local ll (require :lualinux)) -(fn parse-match [s] (string.match s "(.-)=(.+)")) +(local { : view } (require :fennel)) (fn parse-args [args] (match args ["-s" service & rest] (assoc (parse-args rest) :service service) ["-n" path & rest] (assoc (parse-args rest) :linkname path) - matches { :matches (collect [_ m (ipairs matches)] (parse-match m)) } + matches { :matches (table.concat matches " ") } _ nil)) (fn %% [fmt ...] (string.format fmt ...)) -(fn event-matches? [params e] - (and - e - (accumulate [match? true - name value (pairs params.matches)] - (and match? (= value (. e name)))))) - - (var up :unknown) (fn start-service [devname linkname service] @@ -54,17 +48,30 @@ (mktree (dirname parameters.linkname)) (var finished? false) + (print "registering for events" (fh:write parameters.matches)) + (while (not finished?) - (let [e (parse-uevent (fh:read 5000))] - (when (event-matches? parameters e) + (let [e (parse-uevent (fh:read))] + (when e (let [wanted? (. {:add true :change true} e.action)] (toggle-service e.devname parameters.linkname parameters.service wanted?))) (set finished? (= e nil)) )))) -(fn run [args] - (let [nellie (require :nellie) - netlink (nellie.open 4)] - (run-with-fh netlink arg))) +(fn unix-connect [pathname] + (let [addr (string.pack "=Hz" AF_LOCAL pathname)] + (match (ll.socket AF_LOCAL SOCK_STREAM 0) + sock (doto sock (ll.connect addr)) + (nil err) (error err)))) -{ : run : run-with-fh : event-matches? } + +(fn run [args] + (let [fd (assert (unix-connect "/run/devout.sock")) + devout { + :read #(ll.read fd) + :write #(ll.write fd $2) + :close #(ll.close fd) + }] + (run-with-fh devout arg))) + +{ : run : run-with-fh }