From 44737100e6d16afba1fef66ddb6510c16861097f Mon Sep 17 00:00:00 2001 From: ngocdo Date: Mon, 26 Apr 2021 13:59:27 -0700 Subject: [PATCH 1/5] Collect asic info and store in database chassis' STATE_DB Signed-off-by: ngocdo --- sonic-chassisd/scripts/chassisd | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sonic-chassisd/scripts/chassisd b/sonic-chassisd/scripts/chassisd index 355382911..f064f652a 100644 --- a/sonic-chassisd/scripts/chassisd +++ b/sonic-chassisd/scripts/chassisd @@ -44,6 +44,13 @@ CHASSIS_MODULE_INFO_NAME_FIELD = 'name' CHASSIS_MODULE_INFO_DESC_FIELD = 'desc' CHASSIS_MODULE_INFO_SLOT_FIELD = 'slot' CHASSIS_MODULE_INFO_OPERSTATUS_FIELD = 'oper_status' +CHASSIS_MODULE_INFO_NUM_ASICS_FIELD = 'num_asics' +CHASSIS_MODULE_INFO_ASICS = 'asics' + +CHASSIS_ASIC_INFO_TABLE = 'CHASSIS_ASIC_TABLE' +CHASSIS_ASIC = 'asic' +CHASSIS_ASIC_PCI_ADDRESS_FIELD = 'asic_pci_address' +CHASSIS_ASIC_ID_IN_MODULE_FIELD = 'asic_id_in_module' CHASSIS_MIDPLANE_INFO_TABLE = 'CHASSIS_MIDPLANE_TABLE' CHASSIS_MIDPLANE_INFO_KEY_TEMPLATE = 'CHASSIS_MIDPLANE {}' @@ -157,6 +164,7 @@ class ModuleUpdater(logger.Logger): state_db = daemon_base.db_connect("STATE_DB") self.chassis_table = swsscommon.Table(state_db, CHASSIS_INFO_TABLE) self.module_table = swsscommon.Table(state_db, CHASSIS_MODULE_INFO_TABLE) + self.asic_table = swsscommon.Table(state_db, CHASSIS_ASIC_INFO_TABLE) self.midplane_table = swsscommon.Table(state_db, CHASSIS_MIDPLANE_INFO_TABLE) self.info_dict_keys = [CHASSIS_MODULE_INFO_NAME_FIELD, CHASSIS_MODULE_INFO_DESC_FIELD, @@ -211,9 +219,18 @@ class ModuleUpdater(logger.Logger): fvs = swsscommon.FieldValuePairs([(CHASSIS_MODULE_INFO_DESC_FIELD, module_info_dict[CHASSIS_MODULE_INFO_DESC_FIELD]), (CHASSIS_MODULE_INFO_SLOT_FIELD, module_info_dict[CHASSIS_MODULE_INFO_SLOT_FIELD]), - (CHASSIS_MODULE_INFO_OPERSTATUS_FIELD, module_info_dict[CHASSIS_MODULE_INFO_OPERSTATUS_FIELD])]) + (CHASSIS_MODULE_INFO_OPERSTATUS_FIELD, module_info_dict[CHASSIS_MODULE_INFO_OPERSTATUS_FIELD]), + (CHASSIS_MODULE_INFO_NUM_ASICS_FIELD, str(len(module_info_dict[CHASSIS_MODULE_INFO_ASICS])))]) self.module_table.set(key, fvs) + for asic_id, asic in enumerate(module_info_dict[CHASSIS_MODULE_INFO_ASICS]): + asic_global_id, asic_pci_addr = asic + asic_key = "%s%s" % (CHASSIS_ASIC, asic_global_id) + asic_fvs = swsscommon.FieldValuePairs([(CHASSIS_ASIC_PCI_ADDRESS_FIELD, asic_pci_addr), + (CHASSIS_MODULE_INFO_NAME_FIELD, key), + (CHASSIS_ASIC_ID_IN_MODULE_FIELD, str(asic_id))]) + self.asic_table.set(asic_key, asic_fvs) + def _get_module_info(self, module_index): """ Retrieves module info of this module @@ -225,11 +242,14 @@ class ModuleUpdater(logger.Logger): slot = try_get(self.chassis.get_module(module_index).get_slot, default=INVALID_SLOT) status = try_get(self.chassis.get_module(module_index).get_oper_status, default=ModuleBase.MODULE_STATUS_OFFLINE) + asics = try_get(self.chassis.get_module(module_index).get_all_asics, + default=[]) module_info_dict[CHASSIS_MODULE_INFO_NAME_FIELD] = name module_info_dict[CHASSIS_MODULE_INFO_DESC_FIELD] = str(desc) module_info_dict[CHASSIS_MODULE_INFO_SLOT_FIELD] = str(slot) module_info_dict[CHASSIS_MODULE_INFO_OPERSTATUS_FIELD] = str(status) + module_info_dict[CHASSIS_MODULE_INFO_ASICS] = asics return module_info_dict From 81f65ad18c920085a7db95d386e78cc64dbb09a5 Mon Sep 17 00:00:00 2001 From: ngocdo Date: Tue, 18 May 2021 21:19:31 -0700 Subject: [PATCH 2/5] Store asic PCI ID in CHASSIS_STATE_DB and delete table at deinit() Signed-off-by: ngocdo --- sonic-chassisd/scripts/chassisd | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sonic-chassisd/scripts/chassisd b/sonic-chassisd/scripts/chassisd index f064f652a..5fff02c4c 100644 --- a/sonic-chassisd/scripts/chassisd +++ b/sonic-chassisd/scripts/chassisd @@ -164,13 +164,15 @@ class ModuleUpdater(logger.Logger): state_db = daemon_base.db_connect("STATE_DB") self.chassis_table = swsscommon.Table(state_db, CHASSIS_INFO_TABLE) self.module_table = swsscommon.Table(state_db, CHASSIS_MODULE_INFO_TABLE) - self.asic_table = swsscommon.Table(state_db, CHASSIS_ASIC_INFO_TABLE) self.midplane_table = swsscommon.Table(state_db, CHASSIS_MIDPLANE_INFO_TABLE) self.info_dict_keys = [CHASSIS_MODULE_INFO_NAME_FIELD, CHASSIS_MODULE_INFO_DESC_FIELD, CHASSIS_MODULE_INFO_SLOT_FIELD, CHASSIS_MODULE_INFO_OPERSTATUS_FIELD] + chassis_state_db = daemon_base.db_connect("CHASSIS_STATE_DB") + self.asic_table = swsscommon.Table(chassis_state_db, CHASSIS_ASIC_INFO_TABLE) + self.midplane_initialized = try_get(chassis.init_midplane_switch, default=False) if not self.midplane_initialized: self.log_error("Chassisd midplane intialization failed") @@ -190,6 +192,10 @@ class ModuleUpdater(logger.Logger): if self.chassis_table is not None: self.chassis_table._del(CHASSIS_INFO_KEY_TEMPLATE.format(1)) + if self.asic_table is not None: + for key in self.asic_table.getKeys(): + self.asic_table.delete(key) + def modules_num_update(self): # Check if module list is populated num_modules = self.chassis.get_num_modules() From 5430bbcf2471a5220ef7f80065d59ce3826a7b32 Mon Sep 17 00:00:00 2001 From: ngocdo Date: Fri, 4 Jun 2021 13:15:55 -0700 Subject: [PATCH 3/5] Add test --- sonic-chassisd/scripts/chassisd | 18 +++++- sonic-chassisd/tests/mock_platform.py | 10 +++- sonic-chassisd/tests/mock_swsscommon.py | 3 + sonic-chassisd/tests/test_chassisd.py | 75 +++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/sonic-chassisd/scripts/chassisd b/sonic-chassisd/scripts/chassisd index 5fff02c4c..771b73f5a 100644 --- a/sonic-chassisd/scripts/chassisd +++ b/sonic-chassisd/scripts/chassisd @@ -193,8 +193,9 @@ class ModuleUpdater(logger.Logger): self.chassis_table._del(CHASSIS_INFO_KEY_TEMPLATE.format(1)) if self.asic_table is not None: - for key in self.asic_table.getKeys(): - self.asic_table.delete(key) + asics = list(self.asic_table.getKeys()) + for asic in asics: + self.asic_table._del(asic) def modules_num_update(self): # Check if module list is populated @@ -208,6 +209,8 @@ class ModuleUpdater(logger.Logger): self.chassis_table.set(CHASSIS_INFO_KEY_TEMPLATE.format(1), fvs) def module_db_update(self): + notOnlineModules = [] + for module_index in range(0, self.num_modules): module_info_dict = self._get_module_info(module_index) if module_info_dict is not None: @@ -229,6 +232,10 @@ class ModuleUpdater(logger.Logger): (CHASSIS_MODULE_INFO_NUM_ASICS_FIELD, str(len(module_info_dict[CHASSIS_MODULE_INFO_ASICS])))]) self.module_table.set(key, fvs) + if module_info_dict[CHASSIS_MODULE_INFO_OPERSTATUS_FIELD] != str(ModuleBase.MODULE_STATUS_ONLINE): + notOnlineModules.append(key) + continue + for asic_id, asic in enumerate(module_info_dict[CHASSIS_MODULE_INFO_ASICS]): asic_global_id, asic_pci_addr = asic asic_key = "%s%s" % (CHASSIS_ASIC, asic_global_id) @@ -237,6 +244,13 @@ class ModuleUpdater(logger.Logger): (CHASSIS_ASIC_ID_IN_MODULE_FIELD, str(asic_id))]) self.asic_table.set(asic_key, asic_fvs) + # Asics that are on the "not online" modules need to be cleaned up + asics = list(self.asic_table.getKeys()) + for asic in asics: + fvs = self.asic_table.get(asic) + if fvs[CHASSIS_MODULE_INFO_NAME_FIELD] in notOnlineModules: + self.asic_table._del(asic) + def _get_module_info(self, module_index): """ Retrieves module info of this module diff --git a/sonic-chassisd/tests/mock_platform.py b/sonic-chassisd/tests/mock_platform.py index f13356c52..da35d1466 100644 --- a/sonic-chassisd/tests/mock_platform.py +++ b/sonic-chassisd/tests/mock_platform.py @@ -19,8 +19,8 @@ def get_serial(self): class MockModule(MockDevice): - def __init__(self, module_index, module_name, module_desc, module_type, module_slot): - self.module_index = module_index + def __init__(self, module_index, module_name, module_desc, module_type, module_slot, + asic_list=[]): self.module_name = module_name self.module_desc = module_desc self.module_type = module_type @@ -29,7 +29,8 @@ def __init__(self, module_index, module_name, module_desc, module_type, module_s self.admin_state = 1 self.supervisor_slot = 16 self.midplane_access = False - + self.asic_list = asic_list + def get_name(self): return self.module_name @@ -69,6 +70,9 @@ def is_midplane_reachable(self): def set_midplane_reachable(self, up): self.midplane_access = up + def get_all_asics(self): + return self.asic_list + class MockChassis: def __init__(self): self.module_list = [] diff --git a/sonic-chassisd/tests/mock_swsscommon.py b/sonic-chassisd/tests/mock_swsscommon.py index 8e9c68761..589084225 100644 --- a/sonic-chassisd/tests/mock_swsscommon.py +++ b/sonic-chassisd/tests/mock_swsscommon.py @@ -19,6 +19,9 @@ def get(self, key): return self.mock_dict[key] return None + def getKeys(self): + return list(self.mock_dict) + def size(self): return len(self.mock_dict) diff --git a/sonic-chassisd/tests/test_chassisd.py b/sonic-chassisd/tests/test_chassisd.py index ef3d2fb67..a28d58a17 100644 --- a/sonic-chassisd/tests/test_chassisd.py +++ b/sonic-chassisd/tests/test_chassisd.py @@ -31,6 +31,8 @@ CHASSIS_INFO_KEY_TEMPLATE = 'CHASSIS {}' CHASSIS_INFO_CARD_NUM_FIELD = 'module_num' +CHASSIS_ASIC_PCI_ADDRESS_FIELD = 'asic_pci_address' +CHASSIS_ASIC_ID_IN_MODULE_FIELD = 'asic_id_in_module' def setup_function(): ModuleUpdater.log_notice = MagicMock() @@ -366,3 +368,76 @@ def test_midplane_presence_supervisor(): module_updater.deinit() fvs = midplane_table.get(name) assert fvs == None + +def test_asic_presence(): + chassis = MockChassis() + + #Supervisor + index = 0 + name = "SUPERVISOR0" + desc = "Supervisor card" + slot = 16 + module_type = ModuleBase.MODULE_TYPE_SUPERVISOR + supervisor = MockModule(index, name, desc, module_type, slot) + supervisor.set_midplane_ip() + chassis.module_list.append(supervisor) + + #Linecard + index = 1 + name = "LINE-CARD0" + desc = "36 port 400G card" + slot = 1 + module_type = ModuleBase.MODULE_TYPE_LINE + module = MockModule(index, name, desc, module_type, slot) + module.set_midplane_ip() + chassis.module_list.append(module) + + #Fabric-card with asics + index = 1 + name = "FABRIC-CARD0" + desc = "Switch fabric card" + slot = 17 + module_type = ModuleBase.MODULE_TYPE_FABRIC + fabric_asic_list = [("4", "0000:04:00.0"), ("5", "0000:05:00.0")] + fabric = MockModule(index, name, desc, module_type, slot, fabric_asic_list) + chassis.module_list.append(fabric) + + #Run on supervisor + module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis) + module_updater.supervisor_slot = supervisor.get_slot() + module_updater.my_slot = supervisor.get_slot() + module_updater.modules_num_update() + module_updater.module_db_update() + module_updater.check_midplane_reachability() + + #Asic presence on fabric module + fabric.set_oper_status(ModuleBase.MODULE_STATUS_ONLINE) + module_updater.module_db_update() + fabric_asic_table = module_updater.asic_table + assert len(fabric_asic_table.getKeys()) == 2 + + def test_fabric_asic(asic_name, asic_pci_address, module_name, asic_id_in_module): + fvs = fabric_asic_table.get(asic_name) + assert fvs[CHASSIS_ASIC_PCI_ADDRESS_FIELD] == asic_pci_address + assert fvs[CHASSIS_MODULE_INFO_NAME_FIELD] == module_name + assert fvs[CHASSIS_ASIC_ID_IN_MODULE_FIELD] == asic_id_in_module + + test_fabric_asic("asic4", "0000:04:00.0", name, "0") + test_fabric_asic("asic5", "0000:05:00.0", name, "1") + + #Card goes down and asics should be gone + fabric.set_oper_status(ModuleBase.MODULE_STATUS_OFFLINE) + module_updater.module_db_update() + assert len(fabric_asic_table.getKeys()) == 0 + + #Deinit + fabric.set_oper_status(ModuleBase.MODULE_STATUS_ONLINE) + module_updater.module_db_update() + module_updater.deinit() + midplane_table = module_updater.midplane_table + fvs = midplane_table.get(name) + assert fvs == None + fvs = fabric_asic_table.get("asic4") + assert fvs == None + fvs = fabric_asic_table.get("asic5") + assert fvs == None From 917c604c1c9de1372fa2b5800ff9843b05064834 Mon Sep 17 00:00:00 2001 From: ngocdo Date: Fri, 4 Jun 2021 13:26:34 -0700 Subject: [PATCH 4/5] Fix an accidentally removed line --- sonic-chassisd/tests/mock_platform.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sonic-chassisd/tests/mock_platform.py b/sonic-chassisd/tests/mock_platform.py index da35d1466..a1ab20530 100644 --- a/sonic-chassisd/tests/mock_platform.py +++ b/sonic-chassisd/tests/mock_platform.py @@ -21,6 +21,7 @@ def get_serial(self): class MockModule(MockDevice): def __init__(self, module_index, module_name, module_desc, module_type, module_slot, asic_list=[]): + self.module_index = module_index self.module_name = module_name self.module_desc = module_desc self.module_type = module_type From ccd0ad80b3997db0d6e55ba20f2fbddfd4f1e2b8 Mon Sep 17 00:00:00 2001 From: Ngoc Do Date: Tue, 22 Jun 2021 16:44:16 -0700 Subject: [PATCH 5/5] Change prefix test_ to verify_ --- sonic-chassisd/tests/test_chassisd.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonic-chassisd/tests/test_chassisd.py b/sonic-chassisd/tests/test_chassisd.py index a28d58a17..2950abd81 100644 --- a/sonic-chassisd/tests/test_chassisd.py +++ b/sonic-chassisd/tests/test_chassisd.py @@ -416,14 +416,14 @@ def test_asic_presence(): fabric_asic_table = module_updater.asic_table assert len(fabric_asic_table.getKeys()) == 2 - def test_fabric_asic(asic_name, asic_pci_address, module_name, asic_id_in_module): + def verify_fabric_asic(asic_name, asic_pci_address, module_name, asic_id_in_module): fvs = fabric_asic_table.get(asic_name) assert fvs[CHASSIS_ASIC_PCI_ADDRESS_FIELD] == asic_pci_address assert fvs[CHASSIS_MODULE_INFO_NAME_FIELD] == module_name assert fvs[CHASSIS_ASIC_ID_IN_MODULE_FIELD] == asic_id_in_module - test_fabric_asic("asic4", "0000:04:00.0", name, "0") - test_fabric_asic("asic5", "0000:05:00.0", name, "1") + verify_fabric_asic("asic4", "0000:04:00.0", name, "0") + verify_fabric_asic("asic5", "0000:05:00.0", name, "1") #Card goes down and asics should be gone fabric.set_oper_status(ModuleBase.MODULE_STATUS_OFFLINE)