fix(reliability): converge runtime after profile restore (park dummy STA, re-raise monitors)
This commit is contained in:
@@ -4894,6 +4894,21 @@ def h_profile_save(ctx):
|
||||
return (200, {'ok': True}) if ok else (502, {'ok': False})
|
||||
|
||||
|
||||
def _post_restore_converge():
|
||||
"""After any profile restore: re-apply invariants the restored config may
|
||||
not carry. Factory-default configs enable dummy_radio0 (the phy0
|
||||
channel-pinner) and may drop monitors; park and re-raise best-effort.
|
||||
Uses ungated primitives — the restore is already inside its own gate."""
|
||||
try:
|
||||
_park_dummy_sta()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
_raise_monitors()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def h_profile_restore(ctx):
|
||||
import mk8_events
|
||||
import mk8_gate
|
||||
@@ -4911,6 +4926,7 @@ def h_profile_restore(ctx):
|
||||
ok = bool(result.get('ok'))
|
||||
if ok:
|
||||
device_run(['wifi', 'reload'], timeout=45)
|
||||
_post_restore_converge()
|
||||
try:
|
||||
mk8_events.log_event('profile_restore',
|
||||
sev='info' if ok else 'warn',
|
||||
@@ -5001,6 +5017,16 @@ def _sta_uplink_enabled():
|
||||
return cfg.get('mode') == 'sta' and cfg.get('disabled') != '1'
|
||||
|
||||
|
||||
def _park_dummy_sta():
|
||||
"""Ungated primitive: disable dummy_radio0 + take wlan0 down. Callers
|
||||
that already run inside a gate (post-restore convergence) use this to
|
||||
avoid spawning a nested watchdog."""
|
||||
device_run(['uci', 'set', 'wireless.dummy_radio0.disabled=1'])
|
||||
device_run(['uci', 'commit', 'wireless'])
|
||||
for iface in ('wlan0',):
|
||||
rc, out, err = device_run(['ip', 'link', 'set', iface, 'down'], timeout=10)
|
||||
|
||||
|
||||
def _disable_sta_uplink():
|
||||
"""Disable the dummy_radio0 STA without bouncing the radios. The UCI flag
|
||||
keeps it off across reboots/wifi reloads; taking wlan0 down immediately
|
||||
@@ -5008,10 +5034,7 @@ def _disable_sta_uplink():
|
||||
tears down live APs and drops the monitors mid-assessment."""
|
||||
import mk8_gate
|
||||
mk8_gate.enter('uplink_disable')
|
||||
device_run(['uci', 'set', 'wireless.dummy_radio0.disabled=1'])
|
||||
device_run(['uci', 'commit', 'wireless'])
|
||||
for iface in ('wlan0',):
|
||||
rc, out, err = device_run(['ip', 'link', 'set', iface, 'down'], timeout=10)
|
||||
_park_dummy_sta()
|
||||
|
||||
|
||||
def env_check():
|
||||
@@ -7402,6 +7425,7 @@ if __name__ == '__main__':
|
||||
import mk8_profiles
|
||||
result = mk8_profiles.restore(name)
|
||||
device_run(['wifi', 'reload'], timeout=90)
|
||||
_post_restore_converge()
|
||||
import mk8_events
|
||||
mk8_events.log_event('rollback', sev='warn',
|
||||
msg='watchdog restored %s' % name,
|
||||
|
||||
@@ -208,6 +208,17 @@ class ReliabilityApiTest(unittest.TestCase):
|
||||
self.assertEqual(calls['restored'], 'p1')
|
||||
reloads = [r for r in self.runs if r[0][:2] == ['wifi', 'reload']]
|
||||
self.assertEqual(len(reloads), 1)
|
||||
# post-restore convergence parks the factory-enabled dummy STA
|
||||
parked = [r for r in self.runs
|
||||
if r[0][:3] == ['uci', 'set',
|
||||
'wireless.dummy_radio0.disabled=1']]
|
||||
self.assertEqual(len(parked), 1)
|
||||
downs = [r for r in self.runs if r[0][:4] == ['ip', 'link',
|
||||
'set', 'wlan0']]
|
||||
self.assertTrue(downs)
|
||||
raises = [r for r in self.runs if r[0][:4] == ['ip', 'link',
|
||||
'set', 'wlan0mon']]
|
||||
self.assertTrue(raises)
|
||||
self.assertEqual(calls['events'][-1][0], 'profile_restore')
|
||||
|
||||
status, result = server.h_profile_restore(
|
||||
|
||||
Reference in New Issue
Block a user