Harden HDMI recovery and add tested user installer release tooling

This commit is contained in:
admin committed 2026-09-23 09:16:57 +02:00
1 parent 73e727ef4c
commit d963224cb7
17 files changed
+903 -646

No files matched your search

+50 -101
View File
@@ -1,115 +1,64 @@
#!/usr/bin/env bash
set -u
set -uo pipefail
LOGTAG="revive-monitor-drm-watch"
CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/revive-monitor/config.env"
FIX_SCRIPT="${REVIVE_MONITOR_FIX_SCRIPT:-$HOME/.local/bin/revive-monitor-fix}"
# Defaults. Override in ~/.config/revive-monitor/config.env
DEBOUNCE_SECONDS="30"
if [[ -r "$CONFIG_FILE" ]]; then
# shellcheck disable=SC1090
source "$CONFIG_FILE"
LOGTAG=revive-monitor-drm-watch
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
COMMON="$SCRIPT_DIR/../lib/hyprland-hdmi-revive/common.sh"
[[ -f "$COMMON" ]] || COMMON="$SCRIPT_DIR/../lib/common.sh"
# shellcheck source=lib/common.sh
source "$COMMON" || exit 1
load_config || exit 1
require_commands udevadm stdbuf timeout loginctl flock stat || exit 1
prepare_runtime || exit 1
if [[ -n "${REVIVE_MONITOR_FIX_SCRIPT:-}" ]]; then
FIX_SCRIPT="$REVIVE_MONITOR_FIX_SCRIPT"
else
FIX_SCRIPT="$SCRIPT_DIR/revive-monitor-fix"
[[ -e "$FIX_SCRIPT" ]] || FIX_SCRIPT="$SCRIPT_DIR/revive-monitor-fix.sh"
fi
STATE_DIR="${XDG_RUNTIME_DIR:-/tmp}/revive-monitor"
LAST_RUN_FILE="$STATE_DIR/last-drm-hotplug-run"
mkdir -p "$STATE_DIR"
log() {
logger -t "$LOGTAG" -- "$*"
}
get_active_wayland_session() {
local sid
local name
local type
local active
local vt
while read -r sid; do
[[ -n "$sid" ]] || continue
name="$(loginctl show-session "$sid" -p Name --value 2>/dev/null)"
[[ "$name" == "$USER" ]] || continue
type="$(loginctl show-session "$sid" -p Type --value 2>/dev/null)"
[[ "$type" == "wayland" ]] || continue
active="$(loginctl show-session "$sid" -p Active --value 2>/dev/null)"
[[ "$active" == "yes" ]] || continue
vt="$(loginctl show-session "$sid" -p VTNr --value 2>/dev/null)"
if [[ "$vt" =~ ^[1-9][0-9]*$ ]]; then
printf '%s:%s\n' "$sid" "$vt"
return 0
fi
done < <(
loginctl list-sessions --no-legend --no-pager 2>/dev/null | awk '{print $1}'
)
return 1
}
run_recovery() {
local session_info
local session_id
local graphical_vt
local now
local last="0"
local diff
if ! session_info="$(get_active_wayland_session)"; then
log "No active Wayland session - DRM hotplug ignored"
return 0
fi
session_id="${session_info%%:*}"
graphical_vt="${session_info##*:}"
now="$(date +%s)"
if [[ -r "$LAST_RUN_FILE" ]]; then
last="$(cat "$LAST_RUN_FILE" 2>/dev/null || printf '0')"
fi
[[ "$last" =~ ^[0-9]+$ ]] || last="0"
diff=$((now - last))
if (( diff < DEBOUNCE_SECONDS )); then
log "DRM hotplug ignored because of debounce (${diff}s)"
return 0
fi
printf '%s\n' "$now" > "$LAST_RUN_FILE"
log "DRM hotplug detected - Wayland session $session_id on VT $graphical_vt"
"$FIX_SCRIPT" "$graphical_vt"
log "Recovery after DRM hotplug finished"
}
if ! command -v udevadm >/dev/null 2>&1; then
log "udevadm not found"
exit 1
fi
if [[ ! -x "$FIX_SCRIPT" ]]; then
log "Recovery script is not executable: $FIX_SCRIPT"
exit 1
fi
exec 8>"$STATE_DIR/watcher.lock" || exit 1
if ! flock -n 8; then
log 'Another watcher is running or the watcher lock is unavailable'
exit 1
fi
log "Listening for DRM hotplug events"
run_recovery() {
local session_info now status
session_info="$(get_active_wayland_session)" || {
log 'No active Wayland session - DRM hotplug ignored'
return 0
}
now=$SECONDS
if (( last_run >= 0 && now - last_run < DEBOUNCE_SECONDS )); then
log 'DRM hotplug ignored because of debounce'
return 0
fi
log "DRM hotplug detected - Wayland session ${session_info%%:*} on VT ${session_info##*:}"
"$FIX_SCRIPT" "${session_info##*:}"
status=$?
# Measure from completion, so events queued during our own VT refresh are suppressed.
last_run=$SECONDS
if (( status != 0 )); then
log "Recovery after DRM hotplug failed (exit $status)"
else
log 'Recovery helper finished; see its log for completion or skip reason'
fi
}
log 'Listening for DRM hotplug events'
# pipefail propagates a failed producer. EOF (even exit 0) is unexpected for
# this long-running service and must also trigger Restart=on-failure.
stdbuf -oL udevadm monitor --kernel --property --subsystem-match=drm |
while IFS= read -r line; do
last_run=${last_run:--1}
case "$line" in
HOTPLUG=1)
run_recovery
;;
HOTPLUG=1) run_recovery ;;
esac
done
status=$?
log "DRM event stream ended (exit $status) - requesting service restart"
exit 1