fix: passive health check + hop=0 in stabilization pass

Active PINGs on pineapd's command socket collided with the stock daemon's
own socket writes ('[PineAp] Error writing'), making the daemon watchdog
SIGTERM pineapd every ~30s while hopping. Monitor now checks pidof only
(no socket writes) and the stabilization pass pins wlan1mon hop=0.
This commit is contained in:
2026-08-18 21:05:39 -05:00
parent 4c5b459f72
commit ce1f6a8442
2 changed files with 18 additions and 12 deletions
@@ -3347,10 +3347,11 @@ def _stabilize_pineapd():
1. SSID-pool broadcast (segfault, ~15s cadence)
2. wlan2mon: a 6GHz monitor this hardware never creates; hopping the
missing iface segfaults pineapd
3. wlan1mon fast-hopping the 6GHz channel list (ASIO io thread exit)
The pool list itself is also cleared: collect refills it, and a large
pool was observed crashing even with broadcast disabled.
Returns a human-readable description of what was changed."""
3. wlan1mon fast-hopping (stalls the command socket; the stock daemon's
watchdog then SIGTERMs pineapd every ~30s)
4. a large refilled pool (collect refills it; crashes observed even
with broadcast disabled)
The pool list itself is cleared. Returns what changed."""
actions = []
wanted = {
'pineapd.@ssidpool[0].disable': '1',
@@ -3358,6 +3359,7 @@ def _stabilize_pineapd():
'pineapd.wlan2mon.hop': '0',
'pineapd.wlan1mon.bands': '5',
'pineapd.wlan0mon.bands': '2',
'pineapd.wlan1mon.hop': '0',
}
for key, value in wanted.items():
rc, out, err = device_run(['uci', 'get', key])
@@ -3394,12 +3396,13 @@ def health_check():
"""One health pass. Returns the health dict. Fix actions are
rate-limited by HEALTH_FIX_COOLDOWN.
The stock SSID-pool broadcast segfaults pineapd on this firmware; when
pineapd is unreachable the pool broadcast is disabled before restarting,
since it is the only known crash cause."""
The check is PASSIVE (pidof) — actively pinging pineapd's command
socket every 15s collides with the stock daemon's own socket writes
('[PineAp] Error writing' -> daemon watchdog SIGTERMs pineapd).
"""
h = _health
rc, out, err = device_run([HAK5CMD, 'PING'], timeout=10)
h['pineap_up'] = rc == 0 and 'PONG' in (out or '')
rc, out, err = device_run(['pidof', 'pineapd'], timeout=10)
h['pineap_up'] = rc == 0 and bool((out or '').strip())
if h['pineap_up']:
return dict(h)
now = time.time()