Goal
The daemon reacts to seats being added or removed at runtime (hot-plugged GPU docks,
USB-attached seat devices, external monitors).
Scope
- udev DRM monitor — add a
udev_monitor fd to the event loop; receive
drm uevents for display connector changes (add / remove / change).
- Seat added/removed — subscribe to logind's
SeatNew and SeatRemoved
D-Bus signals; call seat_add() / seat_remove() and start or stop the
greeter accordingly.
- CanGraphical gate — query logind's
CanGraphical property on each seat
before starting a greeter. Skip seats where the property is false (no monitor
attached). Subscribe to PropertiesChanged to start/stop greeters when
monitors are plugged or unplugged.
- Display detection —
drm_seat_has_display() sysfs enumeration to detect
connected connectors before starting a greeter on a non-seat0 seat. Check at
both initial seat discovery and greeter restart — this is what prevents
crash-loops on monitorless seats, and once it is in place the default
restart-delay can be reduced from 2 s to ~0.5 s.
Removes the /* SHORTCUT */ from Phase 2 (no hotplug monitoring).
Design notes
The first Phase 11 attempt revealed several architectural issues that need
to be resolved up-front before writing action code:
- Two event sources (udev DRM +
CanGraphical PropertiesChanged) overlap for
the same real-world events, causing a double-SIGTERM hazard. Decide which
source is authoritative for each decision before wiring up callbacks.
sd_bus_slot * must be saved so PropertiesChanged subscriptions can be
cancelled on seat removal.
seat_remove() with a static array invalidates struct seat * pointers
held in event userdata. Consider switching to a linked list first.
See tmp/dev-hotplug-issues.md for the full set of issues identified during
the first attempt (branch dev-hotplug).
Verification
Run atrium. Plug/unplug a USB seat device; confirm the event is detected
and the seat is started/stopped accordingly. Confirm monitorless seats are
skipped cleanly. Test hotplug with an active session on an adjacent seat.
Goal
The daemon reacts to seats being added or removed at runtime (hot-plugged GPU docks,
USB-attached seat devices, external monitors).
Scope
udev_monitorfd to the event loop; receivedrmuevents for display connector changes (add/remove/change).SeatNewandSeatRemovedD-Bus signals; call
seat_add()/seat_remove()and start or stop thegreeter accordingly.
CanGraphicalproperty on each seatbefore starting a greeter. Skip seats where the property is false (no monitor
attached). Subscribe to
PropertiesChangedto start/stop greeters whenmonitors are plugged or unplugged.
drm_seat_has_display()sysfs enumeration to detectconnected connectors before starting a greeter on a non-seat0 seat. Check at
both initial seat discovery and greeter restart — this is what prevents
crash-loops on monitorless seats, and once it is in place the default
restart-delaycan be reduced from 2 s to ~0.5 s.Removes the
/* SHORTCUT */from Phase 2 (no hotplug monitoring).Design notes
The first Phase 11 attempt revealed several architectural issues that need
to be resolved up-front before writing action code:
CanGraphicalPropertiesChanged) overlap forthe same real-world events, causing a double-SIGTERM hazard. Decide which
source is authoritative for each decision before wiring up callbacks.
sd_bus_slot *must be saved soPropertiesChangedsubscriptions can becancelled on seat removal.
seat_remove()with a static array invalidatesstruct seat *pointersheld in event userdata. Consider switching to a linked list first.
See
tmp/dev-hotplug-issues.mdfor the full set of issues identified duringthe first attempt (branch
dev-hotplug).Verification
Run
atrium. Plug/unplug a USB seat device; confirm the event is detectedand the seat is started/stopped accordingly. Confirm monitorless seats are
skipped cleanly. Test hotplug with an active session on an adjacent seat.