add shikane-watchdog user service to auto-recover shikane deadlocks

This commit is contained in:
jozamudi committed 2026-09-28 14:04:22 -07:00
1 parent e3643c3ae2
commit e338d15922
5 files changed
+88

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
# shikane-watchdog: auto-recover shikane from its deadlock bug.
#
# Bug (shikane 1.1.1): if a variant application is discarded mid-way
# (e.g. by a failing DP atomic commit), the daemon gets stuck in
# VariantInProgress/Discarded and keeps logging
# [WARN shikane::variant] Received invalid input AtomicChangeDone at state Discarded
# `shikanectl reload` does not recover it; a service restart does
# (re-applies the active profile in ~1s).
#
# A healthy daemon's last state-machine line is "VariantApplied".
set -u
unit=shikane
stuck=0
logs3=$(journalctl --user -u "$unit" -q --since "-3min" 2>/dev/null)
[ -z "$logs3" ] && exit 0
latest3=$(printf '%s\n' "$logs3" | grep 'daemon::state_machine' | tail -1)
if [ -n "$latest3" ]; then
case "$latest3" in
*VariantApplied*)
: ;; # healthy
*)
# InProgress/Discarded within the last 3 min: only a deadlock
# if the WARN signature is present (a legitimate slow transition
# has no WARN)
printf '%s\n' "$logs3" | grep -q 'invalid input' && stuck=1
;;
esac
else
# No state change in the last 3 min — check the last known state
last10=$(journalctl --user -u "$unit" -q --since "-10min" 2>/dev/null \
| grep 'daemon::state_machine' | tail -1)
case "$last10" in
'' | *VariantApplied*)
: ;; # stable and applied, or nothing to check
*)
stuck=1 ;; # stuck in-progress/discarded for >3 min
esac
fi
if [ "$stuck" -eq 1 ]; then
echo "shikane-watchdog: shikane stuck, restarting" >&2
systemctl --user restart "$unit"
fi
@@ -0,0 +1,6 @@
[Unit]
Description=shikane watchdog - restart shikane if its state machine is stuck
[Service]
Type=oneshot
ExecStart=/home/work/.config/sway/scripts/shikane-watchdog.sh
@@ -0,0 +1,10 @@
[Unit]
Description=Run shikane watchdog every 2 minutes
[Timer]
OnBootSec=2min
OnUnitInactiveSec=2min
AccuracySec=5s
[Install]
WantedBy=timers.target
@@ -0,0 +1 @@
/home/work/.config/systemd/user/shikane-watchdog.timer
+22
View File
@@ -11,3 +11,25 @@ stow .
```
If stow is not installed use ./install.sh from .dotfiles repo
# User services
## shikane-watchdog
`.config/systemd/user/shikane-watchdog.timer` (every 2 min, user unit)
runs `.config/sway/scripts/shikane-watchdog.sh`, which restarts the
`shikane` user service if its state machine is stuck.
Why: shikane 1.1.1 deadlocks when a profile application is discarded
mid-way (e.g. by a failing DP atomic commit on the external display).
The daemon then keeps logging
`[WARN shikane::variant] Received invalid input AtomicChangeDone at state Discarded`
and `shikanectl reload` no longer recovers it. The watchdog detects
that signature in the journal and runs `systemctl --user restart shikane`
(re-applies the active profile in ~1s). It never restarts a healthy
or legitimately transitioning daemon.
```console
systemctl --user status shikane-watchdog.timer # check it's active
systemctl --user disable --now shikane-watchdog.timer # disable
```