From 4aad05bbe2205065d306464e7dd552b4a8b6d31c Mon Sep 17 00:00:00 2001 From: Yunjie Ye Date: Wed, 24 Jun 2026 03:08:59 +0800 Subject: [PATCH] Add daemon process watchdog with crash rate-limiting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the daemon crashes, all existing app connections are permanently lost (Binder death triggers service reference clears and manager suicide). However persistent state lives on disk and new processes can still get a fresh binder — so restarting the daemon still recovers meaningful functionality. - service.sh: wrap the unshare launch in a rate-limited watchdog loop. If the daemon crashes more than 3 times within 60 seconds, the watchdog enters a 3-minute cooldown before retrying and resets the counter. Normal restarts use a 5-second delay. The loop runs in background (&) so Magisk late_start is never blocked. - daemon: drop 'exec' so that when app_process exits, control returns to the daemon script, which finishes, allowing the watchdog in service.sh to iterate. --- zygisk/module/daemon | 4 ++-- zygisk/module/service.sh | 32 +++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/zygisk/module/daemon b/zygisk/module/daemon index faca6adef..4bfe79019 100644 --- a/zygisk/module/daemon +++ b/zygisk/module/daemon @@ -42,5 +42,5 @@ fi [ "$debug" = "true" ] && log -p d -t "Vector" "Starting daemon $*" -# Launch the daemon -exec /system/bin/app_process $java_options /system/bin --nice-name=lspd org.matrix.vector.daemon.VectorDaemon "$@" >/dev/null 2>&1 +# Launch the daemon (no exec so the watchdog loop in service.sh can restart it) +/system/bin/app_process $java_options /system/bin --nice-name=lspd org.matrix.vector.daemon.VectorDaemon "$@" >/dev/null 2>&1 diff --git a/zygisk/module/service.sh b/zygisk/module/service.sh index e49f8859b..061beba4a 100644 --- a/zygisk/module/service.sh +++ b/zygisk/module/service.sh @@ -1,6 +1,32 @@ -# Extract the directory path and change directory +# Extract the directory path and change directory MODDIR="${0%/*}" cd "$MODDIR" || exit 1 -# Start the daemon directly in the background within a private mount namespace -unshare --propagation slave -m "$MODDIR/daemon" --system-server-max-retry=3 "$@" & +# Watchdog loop: automatically restart the daemon if it crashes. +# Each iteration creates a fresh mount namespace (unshare -m), so no stale +# mount points accumulate. +# +# Rate-limiting: if the daemon crashes more than 3 times within any 60-second +# window the watchdog enters a 3-minute cooldown before retrying, then resets +# the counter. Otherwise it restarts after a 5-second pause. +fails=0 +window_start=$(date +%s) +while true; do + unshare --propagation slave -m "$MODDIR/daemon" --system-server-max-retry=3 "$@" + # daemon exited (crashed) + now=$(date +%s) + fails=$((fails + 1)) + if [ $((now - window_start)) -le 60 ] && [ $fails -gt 3 ]; then + # exceeded crash budget → cooldown + sleep 180 + fails=0 + window_start=$(date +%s) + elif [ $((now - window_start)) -gt 60 ]; then + # window expired, reset + fails=1 + window_start=$now + sleep 5 + else + sleep 5 + fi +done &