Skip to content

Commit f5687d7

Browse files
oleksandrivantsivvvolam
authored andcommitted
[SmartSwitch] Extend implementation of the DPU chassis daemon. (sonic-net#563)
1 parent 3ca17b0 commit f5687d7

3 files changed

Lines changed: 107 additions & 2 deletions

File tree

sonic-chassisd/scripts/chassisd

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,21 +791,74 @@ class ChassisdDaemon(daemon_base.DaemonBase):
791791
self.log_info("Shutting down...")
792792

793793

794+
class DpuStateManagerTask(ProcessTaskBase):
795+
796+
def __init__(self, log_identifier, dpu_state_updater):
797+
super(DpuStateManagerTask, self).__init__()
798+
799+
self.logger = logger.Logger(log_identifier)
800+
self.dpu_state_updater = dpu_state_updater
801+
self.state_db = daemon_base.db_connect('STATE_DB')
802+
self.app_db = daemon_base.db_connect('APPL_DB')
803+
804+
def task_worker(self):
805+
sel = swsscommon.Select()
806+
selectable = [
807+
swsscommon.SubscriberStateTable(self.app_db, 'PORT_TABLE'),
808+
swsscommon.SubscriberStateTable(self.state_db, 'SYSTEM_READY')
809+
]
810+
811+
for s in selectable:
812+
sel.addSelectable(s)
813+
814+
try:
815+
while True:
816+
(state, c) = sel.select(SELECT_TIMEOUT)
817+
818+
if state == swsscommon.Select.TIMEOUT:
819+
continue
820+
821+
if state != swsscommon.Select.OBJECT:
822+
continue
823+
824+
for s in selectable:
825+
s.pops()
826+
827+
self.dpu_state_updater.update_state()
828+
829+
except KeyboardInterrupt:
830+
pass
831+
832+
794833
class DpuChassisdDaemon(ChassisdDaemon):
795834

796835
def run(self):
797836
self.log_info("Starting up...")
798837

838+
poll_dpu_state = True
839+
if not try_get(self.platform_chassis.get_dataplane_state, default=None) and not \
840+
try_get(self.platform_chassis.get_controlplane_state, default=None):
841+
poll_dpu_state = False
842+
799843
dpu_updater = DpuStateUpdater(SYSLOG_IDENTIFIER, self.platform_chassis)
844+
dpu_state_mng = None
845+
846+
if not poll_dpu_state:
847+
dpu_state_mng = DpuStateManagerTask(SYSLOG_IDENTIFIER, dpu_updater)
848+
dpu_state_mng.task_run()
800849

801850
# Start main loop
802851
self.log_info("Start daemon main loop")
803852

804853
while not self.stop.wait(CHASSIS_INFO_UPDATE_PERIOD_SECS):
805-
dpu_updater.update_state()
854+
if poll_dpu_state:
855+
dpu_updater.update_state()
806856

807857
self.log_info("Stop daemon main loop")
808858

859+
if dpu_state_mng:
860+
dpu_state_mng.task_stop()
861+
809862
dpu_updater.deinit()
810863

811864
self.log_info("Shutting down...")

sonic-chassisd/tests/mock_swsscommon.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def __init__(self, fvs):
5454
pass
5555

5656
class Select:
57+
OBJECT = 0
5758
TIMEOUT = 1
5859

5960
def addSelectable(self, selectable):
@@ -66,7 +67,12 @@ def select(self, timeout=-1, interrupt_on_signal=False):
6667
return self.TIMEOUT, None
6768

6869
class SubscriberStateTable(Table):
69-
pass
70+
71+
def pop(self):
72+
return None
73+
74+
def pops(self):
75+
return None
7076

7177
class RedisPipeline:
7278
def __init__(self, db):

sonic-chassisd/tests/test_dpu_chassisd.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,52 @@ def hset(key, field, value):
116116
'dpu_control_plane_state': 'down', 'dpu_control_plane_time': '2000-01-01 00:00:00'}}
117117

118118

119+
@pytest.mark.parametrize('dpu_id, dp_state, cp_state, expected_state', [
120+
(0, False, False, {'DPU0':
121+
{'dpu_data_plane_state': 'down', 'dpu_data_plane_time': '2000-01-01 00:00:00',
122+
'dpu_control_plane_state': 'down', 'dpu_control_plane_time': '2000-01-01 00:00:00'}}),
123+
(0, False, True, {'DPU0':
124+
{'dpu_data_plane_state': 'down', 'dpu_data_plane_time': '2000-01-01 00:00:00',
125+
'dpu_control_plane_state': 'up', 'dpu_control_plane_time': '2000-01-01 00:00:00'}}),
126+
(0, True, True, {'DPU0':
127+
{'dpu_data_plane_state': 'up', 'dpu_data_plane_time': '2000-01-01 00:00:00',
128+
'dpu_control_plane_state': 'up', 'dpu_control_plane_time': '2000-01-01 00:00:00'}}),
129+
])
130+
def test_dpu_state_manager(dpu_id, dp_state, cp_state, expected_state):
131+
chassis = MockDpuChassis()
132+
133+
chassis.get_dpu_id = MagicMock(return_value=dpu_id)
134+
chassis.get_dataplane_state = MagicMock(return_value=dp_state)
135+
chassis.get_controlplane_state = MagicMock(return_value=cp_state)
136+
137+
chassis_state_db = {}
138+
139+
def hset(key, field, value):
140+
print(key, field, value)
141+
if key not in chassis_state_db:
142+
chassis_state_db[key] = {}
143+
144+
chassis_state_db[key][field] = value
145+
146+
with mock.patch.object(swsscommon.Table, 'hset', side_effect=hset):
147+
with mock.patch.object(swsscommon.Select, 'select', side_effect=((swsscommon.Select.OBJECT, None), (swsscommon.Select.OBJECT, None), KeyboardInterrupt)):
148+
dpu_updater = DpuStateUpdater(SYSLOG_IDENTIFIER, chassis)
149+
dpu_updater._time_now = MagicMock(return_value='2000-01-01 00:00:00')
150+
151+
dpu_state_mng = DpuStateManagerTask(SYSLOG_IDENTIFIER, dpu_updater)
152+
153+
dpu_state_mng.task_worker()
154+
155+
assert chassis_state_db == expected_state
156+
157+
dpu_updater.deinit()
158+
159+
# After the deinit we assume that the DPU state is down.
160+
assert chassis_state_db == {'DPU0':
161+
{'dpu_data_plane_state': 'down', 'dpu_data_plane_time': '2000-01-01 00:00:00',
162+
'dpu_control_plane_state': 'down', 'dpu_control_plane_time': '2000-01-01 00:00:00'}}
163+
164+
119165
def test_dpu_chassis_daemon():
120166
# Test the chassisd run
121167
chassis = MockDpuChassis()

0 commit comments

Comments
 (0)