5 Commits
Author SHA1 Message Date
Joachim Wiberg 292e87c0d1 keventd: serve org.finit.Device1 on /run/keventd/bus
The udev parity gaps that were blocked on IPC -- settle, trigger,
info, queue introspection, runtime rule reload -- become bus methods.
keventd serves its own socket the way Finit serves /run/finit/bus:
brokerless, libink, one socket per daemon, no forwarding between the
two.

  Settle(u) -> b      parked until the queue drains or the timeout
                      passes; true when settled
  Trigger(s, s)       replay events, action + subsystem glob
  Info(s) -> a{ss}    /run/udev/data properties for a devpath
  RulesReload() -> u  re-read rules dirs, returns rule count
  QueueEmpty (b), SeqnumProcessed (t) properties
  DeviceProcessed (ss) signal after each fully handled event

The queue state is the highest kernel seqnum keventd has handled,
baselined at startup, against /sys/kernel/uevent_seqnum.  keventd -S
now asks the running daemon first and falls back to seqnum polling.
In passive mode Trigger and RulesReload refuse.  Adds
link_call_connection() for the park bookkeeping.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:43 +02:00
Joachim Wiberg 0111dc2178 keventd: convert main loop to libuev
Replace the raw poll() + global running/reload_rules flag dance with
libuev.  All four signals (SIGUSR1, SIGTERM, SIGHUP, SIGCHLD) are now
handled via uev_signal_init() -- libuev uses signalfd internally so the
handlers run in normal main-loop context, not async signal context.

The SIGCHLD handler waitpid(-1, WNOHANG) reaps any subprocess (modprobe
loads, rule RUN+= helpers) instead of the old SIG_IGN auto-reap trick.
Synchronous waitpid() in modprobe_load() and run_program() still works
because signalfd queues the signal -- it only reaches sigchld_cb on the
next main-loop iteration.

The netlink receive loop becomes uevent_cb() registered via uev_io_init(),
with the receive buffer passed via the watcher's arg slot (avoids
file-static state).  ENOBUFS and EINTR/EAGAIN are still tolerated, any
other recv() error still panic()s.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:32 +02:00
Joachim Wiberg 4e914dd8a9 keventd: ship curated udev rules derived from eudev 3.2.14
Add 27 stock rules installed to /lib/udev/rules.d/.  Rules invoking
/lib/udev/<helper> fall back to keventd builtins (path_id, usb_id,
blkid, hwdb, kmod, net_id, input_id) when the helper binary is absent;
user-supplied helpers in /lib/udev/ still take precedence.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:31 +02:00
Joachim Wiberg 67d61a8282 keventd: add udev rules engine
Transform keventd from a power-supply monitor + basic hotplug handler into
a full udev-compatible device manager.

Rules engine (rules.c):
- Full .rules file parser covering all udev key types: ACTION, KERNEL,
  SUBSYSTEM, DEVPATH, ENV, ATTR, SYSCTL, TAG, RESULT, PROGRAM, TEST,
  parent-chain KERNELS/SUBSYSTEMS/ATTRS/DRIVERS, and more
- Pattern matching: plain string, fnmatch glob, and pipe-separated alternatives
- Operators: ==, !=, =, +=, -=, :=
- Assignments: NAME=, MODE=, OWNER=, GROUP=, SYMLINK+=, ENV{k}=, TAG+=, RUN+=
- IMPORT{program|file|builtin|parent|cmdline|db}=
- PROGRAM= with stdout capture for subsequent RESULT== matching
- GOTO=/LABEL= flow control
- Loads *.rules from /lib/udev/rules.d, /run/udev/rules.d, /etc/udev/rules.d
  and an optional extra directory (-r DIR); reloads on SIGHUP

Builtin framework (builtin.c):
- kmod:     load module by MODALIAS or explicit alias
- hwdb:     match device against *.hwdb text files in udev hwdb dirs; builds
	    correct lookup key per subsystem — evdev:input:b*v*p*e* for input,
	    usb:v*p* for USB, raw modalias for PCI/platform
- path_id:  build stable ID_PATH / ID_PATH_TAG from sysfs topology (PCI, USB,
	    ATA, NVMe, platform, ACPI, virtio)
- usb_id:   read idVendor/idProduct/bcdDevice/serial from sysfs; look up
	    ID_VENDOR_FROM_DATABASE and ID_MODEL_FROM_DATABASE from usb.ids
	    (hwdata package) when available; silent fallback when absent
- input_id: classify input devices (keyboard, mouse, joystick, touchscreen,
	    touchpad) from evdev capability bitmasks in sysfs
- net_id:   generate predictable names — MAC-based enx<mac> and PCI-slot-based
	    enp<bus>s<dev>[f<func>]
- blkid:    probe filesystem type, UUID, and label via libblkid; sets ID_FS_*
	    and ID_PART_TABLE_* properties

Network interface renaming (uevent.c):
- netdev_add() renames interfaces via SIOCSIFNAME when a NAME= rule matched,
  then sets the Finit dev/ condition on the final name; and any setup using
  persistent interface naming via udev rules

Device node and symlink improvements (uevent.c):
- NAME=, MODE=, OWNER=, GROUP= overrides from matched rules applied at
  mknod/chown time, falling back to the built-in permission table
- SYMLINK+= links from rules applied alongside built-in by-id/by-path links

Device property database (udevdb.c):
- Persist per-device E:/S:/I: records to /run/udev/data/ on ADD/CHANGE,
  delete on REMOVE; IMPORT{db}= restores saved properties into event env

Build:
- libblkid (util-linux) is now required for keventd

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:31 +02:00
Joachim Wiberg dda0d5c763 Relocate keventd from src/ to keventd/
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-08-16 22:03:31 +02:00