Files
chromebox_10th_audio_driver/scripts/kaisa-audio-hdmi-watchdog.sh

135 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# When VERIFY fails: PCI reset (root) + doctor --fix (desktop user), then re-verify.
# Run as your desktop user (same as kaisa-audio-doctor.sh). Reset step needs:
# sudo -n /path/to/reset-sof-hdmi-pci.sh
# (configure NOPASSWD for that absolute path).
#
# Typical:
# ./scripts/kaisa-audio-hdmi-watchdog.sh
# ./scripts/kaisa-audio-hdmi-watchdog.sh --loop --interval 300
#
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RESET_SCRIPT="${KAISA_RESET_SCRIPT:-${REPO_ROOT}/scripts/reset-sof-hdmi-pci.sh}"
DOCTOR="${REPO_ROOT}/scripts/kaisa-audio-doctor.sh"
LOG_DIR="${KAISA_LOG_DIR:-${REPO_ROOT}/_logs}"
CONNECTED_ARGS=(--only-connected)
LOOPS=1
INTERVAL_SEC="${KAISA_WATCHDOG_INTERVAL:-120}"
LOOP_FOREVER=0
log() { printf '[%s] %s\n' "$(date '+%F %T')" "$*"; }
usage() {
sed -n '1,40p' "$0" | sed -n '/^# /s/^# //p'
cat <<EOF
Options:
--loop Repeat until interrupted (sleep --interval between cycles)
--loops N Run N cycles (default: 1)
--interval SEC Sleep between cycles in --loop mode (default: ${INTERVAL_SEC})
--all-hdmi Do not pass --only-connected (verify/fix may probe pcm2/3/4; riskier)
-h, --help This help
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--loop) LOOP_FOREVER=1; shift ;;
--loops)
LOOPS="${2:?}"
shift 2
;;
--interval)
INTERVAL_SEC="${2:?}"
shift 2
;;
--all-hdmi) CONNECTED_ARGS=(); shift ;;
-h|--help) usage; exit 0 ;;
*)
echo "Unknown option: $1" >&2
usage >&2
exit 2
;;
esac
done
if ! [[ "${LOOPS}" =~ ^[0-9]+$ ]] || [[ "${LOOPS}" -lt 1 ]]; then
echo "ERROR: --loops must be a positive integer" >&2
exit 2
fi
if [[ "${EUID}" -eq 0 ]]; then
echo "ERROR: run as desktop user, not root (doctor --fix needs user session)." >&2
exit 1
fi
if [[ ! -x "${DOCTOR}" ]]; then
echo "ERROR: missing doctor: ${DOCTOR}" >&2
exit 1
fi
if [[ ! -f "${RESET_SCRIPT}" ]]; then
echo "ERROR: missing reset script: ${RESET_SCRIPT}" >&2
exit 1
fi
mkdir -p "${LOG_DIR}"
run_one_cycle() {
local cycle="${1:?}"
local ts
ts="$(date +%Y%m%d_%H%M%S)"
local v1 f1 v2
v1="${LOG_DIR}/kaisa-watchdog_${ts}_c${cycle}_verify.log"
f1="${LOG_DIR}/kaisa-watchdog_${ts}_c${cycle}_fix.log"
v2="${LOG_DIR}/kaisa-watchdog_${ts}_c${cycle}_reverify.log"
log "cycle ${cycle}: verify -> ${v1}"
if "${DOCTOR}" --verify "${CONNECTED_ARGS[@]}" --verify-strict -o "${v1}"; then
log "cycle ${cycle}: verify OK"
return 0
fi
log "cycle ${cycle}: verify FAILED -> sudo -n reset (${RESET_SCRIPT})"
if ! sudo -n "${RESET_SCRIPT}"; then
log "ERROR: sudo -n reset failed (password / NOPASSWD path?)"
return 1
fi
log "cycle ${cycle}: doctor --fix -> ${f1}"
"${DOCTOR}" --fix "${CONNECTED_ARGS[@]}" -o "${f1}" || true
log "cycle ${cycle}: re-verify -> ${v2}"
if "${DOCTOR}" --verify "${CONNECTED_ARGS[@]}" --verify-strict -o "${v2}"; then
log "cycle ${cycle}: re-verify OK after reset+fix"
return 0
fi
log "cycle ${cycle}: re-verify still FAILED (see ${v2})"
return 1
}
cycle=0
while true; do
cycle=$((cycle + 1))
if run_one_cycle "${cycle}"; then
:
else
log "cycle ${cycle}: recovery did not achieve clean verify"
fi
if [[ "${LOOP_FOREVER}" -eq 0 ]]; then
if [[ "${cycle}" -ge "${LOOPS}" ]]; then
break
fi
fi
if [[ "${LOOP_FOREVER}" -eq 1 ]] || [[ "${cycle}" -lt "${LOOPS}" ]]; then
log "sleep ${INTERVAL_SEC}s before next cycle"
sleep "${INTERVAL_SEC}"
fi
done
log "watchdog finished (${cycle} cycle(s))"