Skip to content

Commit

Permalink
chassisd: Fix crash on exit on linecard
Browse files Browse the repository at this point in the history
Set the `config_manager` variable to `None` if we are running on a
linecard and thus don't need to set up the config manager.

During cleanup, the chassid service tries to clean up the
`config_manager`, but the `config_manager` variable is only ever
initialized if we are on the supervisor. Thus, checking if it is
`None` is insufficient because this results in an `UnboundLocalError`
that prevents the cleanup from succeeding on a linecard.
  • Loading branch information
patrickmacarthur committed Jul 12, 2023
1 parent 5f8f31c commit cb4ad62
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
2 changes: 2 additions & 0 deletions sonic-chassisd/scripts/chassisd
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ class ChassisdDaemon(daemon_base.DaemonBase):
if self.module_updater.supervisor_slot == self.module_updater.my_slot:
config_manager = ConfigManagerTask()
config_manager.task_run()
else:
config_manager = None

# Start main loop
self.log_info("Start daemon main loop")
Expand Down
15 changes: 15 additions & 0 deletions sonic-chassisd/tests/mock_swsscommon.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,18 @@ class FieldValuePairs:
def __init__(self, fvs):
self.fv_dict = dict(fvs)
pass

class Select:
TIMEOUT = 1

def addSelectable(self, selectable):
pass

def removeSelectable(self, selectable):
pass

def select(self, timeout=-1, interrupt_on_signal=False):
return self.TIMEOUT, None

class SubscriberStateTable(Table):
pass
13 changes: 12 additions & 1 deletion sonic-chassisd/tests/test_chassisd.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,20 @@ def test_signal_handler():
assert daemon_chassisd.stop.set.call_count == 0
assert exit_code == 0

def test_daemon_run():
def test_daemon_run_supervisor():
# Test the chassisd run
daemon_chassisd = ChassisdDaemon(SYSLOG_IDENTIFIER)
daemon_chassisd.stop = MagicMock()
daemon_chassisd.stop.wait.return_value = True
daemon_chassisd.run()

def test_daemon_run_linecard():
# Test the chassisd run
daemon_chassisd = ChassisdDaemon(SYSLOG_IDENTIFIER)
daemon_chassisd.stop = MagicMock()
daemon_chassisd.stop.wait.return_value = True

import sonic_platform.platform
with patch.object(sonic_platform.platform.Chassis, 'get_my_slot') as mock:
mock.return_value = sonic_platform.platform.Platform().get_chassis().get_supervisor_slot() + 1
daemon_chassisd.run()

0 comments on commit cb4ad62

Please sign in to comment.