make uevent-watch use devout instead of direct netlink

This commit is contained in:
Daniel Barlow 2024-04-26 22:00:31 +01:00
parent 80628a3d90
commit 1b6a05aec5
5 changed files with 63 additions and 180 deletions

View file

@ -13,10 +13,14 @@ in {
notification-fd = 10; notification-fd = 10;
run = "${pkgs.devout}/bin/devout /run/devout.sock 4"; run = "${pkgs.devout}/bin/devout /run/devout.sock 4";
}; };
mdevd-coldplug = oneshot { coldplug = oneshot {
name ="mdev-coldplug"; name ="coldplug";
up = "${pkgs.mdevd}/bin/mdevd-coldplug -O 4"; # would love to know what mdevd-coldplug/udevadm trigger does
dependencies = [devout]; # that this doesn't
up = ''
for i in $(find /sys -name uevent); do ( echo change > $i ) ; done
'';
dependencies = [devout mdevd];
}; };
}; };
}; };

View file

@ -44,7 +44,10 @@ in {
in svc // { in svc // {
build = args: build = args:
let args' = 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' ; in svc.build args' ;
}; };

View file

@ -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 ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1 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=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
SUBSYSTEM=block SUBSYSTEM=block
MAJOR=8 DEVNAME=/dev/sdb1
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
DEVTYPE=partition DEVTYPE=partition
DISKSEQ=2 DISKSEQ=33
PARTN=1 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 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=bind ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:13.0/usb1/1-1/1-1:1.0/host0/target0:0:0/0:0:0:0 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=scsi SUBSYSTEM=block
DEVTYPE=scsi_device DEVNAME=/dev/sdb1
DRIVER=sd DEVTYPE=partition
MODALIAS=scsi:t-0x00 DISKSEQ=33
SEQNUM=1529 PARTN=1
SEQNUM=82386
PARTNAME=backup-disk
MAJOR=8
MINOR=17

View file

@ -1,11 +1,6 @@
(local { : view} (require :fennel)) (local watch (require :watch))
(import-macros { : expect= } :anoia.assert)
(local subject (require :watch)) ;; Events come from the devout socket as an initial summary line
;; Events come from the netlink socket as an initial summary line
;; followed by a NUL character followed by newline-separated key=value ;; followed by a NUL character followed by newline-separated key=value
;; pairs. For ease of editing we don't have NULs in events.txt, ;; pairs. For ease of editing we don't have NULs in events.txt,
;; so we need to massage it into shape here ;; so we need to massage it into shape here
@ -27,8 +22,11 @@
;; this tests event parsing but not whether anything ;; this tests event parsing but not whether anything
;; happens as a result of processing them ;; happens as a result of processing them
(subject.run-with-fh (watch.run-with-fh
{ :read (next-event) } {
:read (next-event)
:write (fn [payload] )
}
["-s" "foo" "-n" (os.getenv "TMPDIR") "partname=backup-disk" ] ["-s" "foo" "-n" (os.getenv "TMPDIR") "partname=backup-disk" ]
) )

View file

@ -1,25 +1,19 @@
(local { : assoc : system : dirname } (require :anoia)) (local { : assoc : system : dirname } (require :anoia))
(local { : mktree : rmtree : symlink } (require :anoia.fs)) (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] (fn parse-args [args]
(match args (match args
["-s" service & rest] (assoc (parse-args rest) :service service) ["-s" service & rest] (assoc (parse-args rest) :service service)
["-n" path & rest] (assoc (parse-args rest) :linkname path) ["-n" path & rest] (assoc (parse-args rest) :linkname path)
matches { :matches (collect [_ m (ipairs matches)] (parse-match m)) } matches { :matches (table.concat matches " ") }
_ nil)) _ nil))
(fn %% [fmt ...] (string.format fmt ...)) (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) (var up :unknown)
(fn start-service [devname linkname service] (fn start-service [devname linkname service]
@ -54,17 +48,30 @@
(mktree (dirname parameters.linkname)) (mktree (dirname parameters.linkname))
(var finished? false) (var finished? false)
(print "registering for events" (fh:write parameters.matches))
(while (not finished?) (while (not finished?)
(let [e (parse-uevent (fh:read 5000))] (let [e (parse-uevent (fh:read))]
(when (event-matches? parameters e) (when e
(let [wanted? (. {:add true :change true} e.action)] (let [wanted? (. {:add true :change true} e.action)]
(toggle-service e.devname parameters.linkname parameters.service wanted?))) (toggle-service e.devname parameters.linkname parameters.service wanted?)))
(set finished? (= e nil)) (set finished? (= e nil))
)))) ))))
(fn run [args] (fn unix-connect [pathname]
(let [nellie (require :nellie) (let [addr (string.pack "=Hz" AF_LOCAL pathname)]
netlink (nellie.open 4)] (match (ll.socket AF_LOCAL SOCK_STREAM 0)
(run-with-fh netlink arg))) 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 }