fix(reliability): supervisor re-parks stock-resurrected dummy STA on interval
This commit is contained in:
@@ -4719,6 +4719,7 @@ def _mem_percent(path='/proc/meminfo'):
|
|||||||
|
|
||||||
MEM_WARN_PERCENT = 85
|
MEM_WARN_PERCENT = 85
|
||||||
MEM_WARN_STREAK = 5
|
MEM_WARN_STREAK = 5
|
||||||
|
HEALTH_STA_PARK_INTERVAL = 4 # every Nth health tick (~1/min at 15s poll)
|
||||||
|
|
||||||
|
|
||||||
def health_check():
|
def health_check():
|
||||||
@@ -4755,6 +4756,21 @@ def health_check():
|
|||||||
# does not bring secondary monitors back). Repair them without cooldown.
|
# does not bring secondary monitors back). Repair them without cooldown.
|
||||||
if _monitor_down('wlan1mon') or _monitor_down('wlan0mon'):
|
if _monitor_down('wlan1mon') or _monitor_down('wlan0mon'):
|
||||||
_bring_monitors_up(h)
|
_bring_monitors_up(h)
|
||||||
|
# The stock daemon re-enables its dummy STA during its own config
|
||||||
|
# reconvergence (e.g. after wifi reloads), silently pinning phy0 again.
|
||||||
|
# Re-park periodically — parking never runs wifi reload, so it is safe
|
||||||
|
# to repeat.
|
||||||
|
h['ticks'] = h.get('ticks', 0) + 1
|
||||||
|
if h['ticks'] % HEALTH_STA_PARK_INTERVAL == 0 and _sta_uplink_enabled():
|
||||||
|
try:
|
||||||
|
_park_dummy_sta()
|
||||||
|
h['last_action'] = 'dummy STA re-parked'
|
||||||
|
import mk8_events
|
||||||
|
mk8_events.log_event('guard_fix',
|
||||||
|
msg='re-parked dummy_radio0 STA '
|
||||||
|
'(stock reconvergence)')
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
h['mem_percent'] = _mem_percent()
|
h['mem_percent'] = _mem_percent()
|
||||||
if h['mem_percent'] >= MEM_WARN_PERCENT:
|
if h['mem_percent'] >= MEM_WARN_PERCENT:
|
||||||
h['mem_streak'] = h.get('mem_streak', 0) + 1
|
h['mem_streak'] = h.get('mem_streak', 0) + 1
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'payload', 'user', 'remote_access', 'pager-webui'))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'payload', 'user', 'remote_access', 'pager-webui'))
|
||||||
import server
|
import server
|
||||||
@@ -150,6 +151,25 @@ class SupervisorExtrasTest(unittest.TestCase):
|
|||||||
open(path, 'w').write(content)
|
open(path, 'w').write(content)
|
||||||
self.assertEqual(server._mem_percent(path), 60)
|
self.assertEqual(server._mem_percent(path), 60)
|
||||||
|
|
||||||
|
def test_health_reparks_resurrected_dummy_sta(self):
|
||||||
|
server._health['ticks'] = server.HEALTH_STA_PARK_INTERVAL - 1
|
||||||
|
with mock.patch.object(
|
||||||
|
server, '_sta_uplink_enabled', return_value=True), \
|
||||||
|
__import__('unittest').mock.patch.object(
|
||||||
|
server, '_park_dummy_sta') as park:
|
||||||
|
h = server.health_check()
|
||||||
|
park.assert_called_once()
|
||||||
|
self.assertEqual(server._health['ticks'],
|
||||||
|
server.HEALTH_STA_PARK_INTERVAL)
|
||||||
|
# not on interval ticks: no re-park
|
||||||
|
server._health['ticks'] = 1
|
||||||
|
with mock.patch.object(
|
||||||
|
server, '_sta_uplink_enabled', return_value=True), \
|
||||||
|
__import__('unittest').mock.patch.object(
|
||||||
|
server, '_park_dummy_sta') as park:
|
||||||
|
server.health_check()
|
||||||
|
park.assert_not_called()
|
||||||
|
|
||||||
def test_health_reports_events_and_counters(self):
|
def test_health_reports_events_and_counters(self):
|
||||||
import mk8_events
|
import mk8_events
|
||||||
mk8_events.log_event('restart', msg='x')
|
mk8_events.log_event('restart', msg='x')
|
||||||
|
|||||||
Reference in New Issue
Block a user