From 627a2f5990f363e626c59ae396fcf75bcb1f5228 Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 16 Jul 2023 11:08:50 -0700 Subject: [PATCH 1/3] [Techsupport] Update the message seen during the lock acquisition failure (#2897) #### What I did When a second techsupport instance starts while one is running, the message thrown before exiting is not very user friendly. Thus updating the message for it to make more sense. --- scripts/generate_dump | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_dump b/scripts/generate_dump index 8af9e8533..6f64e90ec 100755 --- a/scripts/generate_dump +++ b/scripts/generate_dump @@ -1917,7 +1917,7 @@ else rm_lock_and_exit else # Lock is valid and the other instance is active. Exit Now - echo "Accquiring lock failed, PID ${PID_PROG} is active" >&2 + echo "Another instance of techsupport running with PID: ${PID_PROG}, please retry after some time..." >&2 exit $EXT_LOCKFAIL fi fi From 03292ffe5725ee7f63e20545f8aee70e30adef26 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan <55814491+arlakshm@users.noreply.github.com> Date: Thu, 17 Aug 2023 21:08:45 -0700 Subject: [PATCH 2/3] Fix show acl table for masic (#2937) What I did Fixes sonic-net/sonic-buildimage#16012 The show acl table command currently get the ports from host config_db on multi asic platforms. This host config_db will not the phyiscal ports in the binding ports because the host doesnt have any front panel ports on the host. This causes the show acl table not to display the phyiscal ports in the output on multi asic devices/linecards. The test iface_namingmode/test_iface_namingmode.py::test_show_acl_table fails because of this issue. --- acl_loader/main.py | 26 +++++++++++++++++++++++++- tests/mock_tables/asic2/config_db.json | 2 +- tests/show_acl_test.py | 10 ++++++---- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/acl_loader/main.py b/acl_loader/main.py index fab46eb90..6a28cb0f8 100644 --- a/acl_loader/main.py +++ b/acl_loader/main.py @@ -173,7 +173,31 @@ def read_tables_info(self): Read ACL_TABLE table from configuration database :return: """ - self.tables_db_info = self.configdb.get_table(self.ACL_TABLE) + # get the acl table info from host config_db + host_acl_table = self.configdb.get_table(self.ACL_TABLE) + # For multi asic get only the control plane acls from the host config_db + if self.per_npu_configdb: + for table, entry in host_acl_table.items(): + if entry.get('type', None) != self.ACL_TABLE_TYPE_CTRLPLANE: + continue + + self.tables_db_info[table] = entry + else: + self.tables_db_info.update(host_acl_table) + + # for DATAACL, EVERFLOW acls. + # update the ports from all the namespaces + if self.per_npu_configdb: + for ns, config_db in self.per_npu_configdb.items(): + acl_table = config_db.get_table(self.ACL_TABLE) + for table, entry in acl_table.items(): + if entry.get('type', None) == self.ACL_TABLE_TYPE_CTRLPLANE: + continue + if table not in self.tables_db_info: + self.tables_db_info[table] = entry + else: + self.tables_db_info[table]['ports'] += entry.get( + 'ports', []) def get_tables_db_info(self): return self.tables_db_info diff --git a/tests/mock_tables/asic2/config_db.json b/tests/mock_tables/asic2/config_db.json index bfda10a0d..32a524365 100644 --- a/tests/mock_tables/asic2/config_db.json +++ b/tests/mock_tables/asic2/config_db.json @@ -132,7 +132,7 @@ }, "ACL_TABLE|DATAACL_5": { "policy_desc": "DATAACL_5", - "ports@": "Ethernet124", + "ports@": "Ethernet20", "type": "L3", "stage": "ingress" } diff --git a/tests/show_acl_test.py b/tests/show_acl_test.py index 1b2cdc60a..64db81fb9 100644 --- a/tests/show_acl_test.py +++ b/tests/show_acl_test.py @@ -11,6 +11,11 @@ modules_path = os.path.dirname(root_path) scripts_path = os.path.join(modules_path, "scripts") +MASIC_SHOW_ACL_OUTPUT = """Name Type Binding Description Stage Status +--------- ------ ----------- ------------- ------- -------------------------------------- +DATAACL_5 L3 Ethernet20 DATAACL_5 ingress {'asic0': 'Active', 'asic2': 'Active'} + Ethernet124 +""" @pytest.fixture() def setup_teardown_single_asic(): @@ -74,10 +79,7 @@ def test_show_acl_table(self, setup_teardown_multi_asic): } result = runner.invoke(acl_loader_show.cli.commands['show'].commands['table'], ['DATAACL_5'], obj=context) assert result.exit_code == 0 - # We only care about the third line, which contains the 'Active' - result_top = result.output.split('\n')[2] - expected_output = "DATAACL_5 L3 Ethernet124 DATAACL_5 ingress {'asic0': 'Active', 'asic2': 'Active'}" - assert result_top == expected_output + assert result.output == MASIC_SHOW_ACL_OUTPUT def test_show_acl_rule(self, setup_teardown_multi_asic): runner = CliRunner() From 787b4a32471c780ee99340c0fa22475b24b2227e Mon Sep 17 00:00:00 2001 From: Prince George <45705344+prgeor@users.noreply.github.com> Date: Wed, 6 Sep 2023 13:41:51 -0700 Subject: [PATCH 3/3] Remove SFP index usage in generating list of SFP hw error (#2961) * Remove SFP index usage in generating list of SFP hw error * Consider case with multiple logical port map to same physical port * Added test case --- sfputil/main.py | 29 +++++++++++++---------------- tests/sfputil_test.py | 6 +++--- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/sfputil/main.py b/sfputil/main.py index d53cf8e3e..753634be7 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -901,9 +901,9 @@ def fetch_error_status_from_platform_api(port): # Code to fetch the error status get_error_status_code = \ "try:\n"\ - " errors=['{}:{}'.format(sfp.index, sfp.get_error_description()) for sfp in sfp_list]\n" \ + " errors=['{}'.format(sfp.get_error_description()) for sfp in sfp_list]\n" \ "except NotImplementedError as e:\n"\ - " errors=['{}:{}'.format(sfp.index, 'OK (Not implemented)') for sfp in sfp_list]\n" \ + " errors=['{}'.format('OK (Not implemented)') for sfp in sfp_list]\n" \ "print(errors)\n" get_error_status_command = "docker exec pmon python3 -c \"{}{}{}\"".format( @@ -917,28 +917,25 @@ def fetch_error_status_from_platform_api(port): output_list = output.split('\n') for output_str in output_list: - # The output of all SFP error status are a list consisting of element with convention of ':' + # The output of all SFP error status are a list consisting of sorted physical port indices # Besides, there can be some logs captured during the platform API executing # So, first of all, we need to skip all the logs until find the output list of SFP error status if output_str[0] == '[' and output_str[-1] == ']': output_list = ast.literal_eval(output_str) break - output_dict = {} - for output in output_list: - sfp_index, error_status = output.split(':') - output_dict[int(sfp_index)] = error_status + physical_port_set = set() + for port in logical_port_list: + physical_port_set.add(logical_port_to_physical_port_index(port)) - output = [] - for logical_port_name in logical_port_list: - physical_port_list = logical_port_name_to_physical_port_list(logical_port_name) - port_name = get_physical_port_name(logical_port_name, 1, False) - - if is_port_type_rj45(logical_port_name): - output.append([port_name, "N/A"]) - else: - output.append([port_name, output_dict.get(physical_port_list[0])]) + physical_port_list = list(physical_port_set) + # Map of + error_map = {physical_port_list[i] : output_list[i] for i in range(len(physical_port_list))} + output = [] + for i in range(len(logical_port_list)): + physical_port = logical_port_to_physical_port_index(logical_port_list[i]) + output.append([logical_port_list[i], error_map[physical_port] if not is_port_type_rj45(logical_port_list[i]) else 'N/A']) return output def fetch_error_status_from_state_db(port, state_db): diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index c57a5dc61..7b1e99d0b 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -319,14 +319,14 @@ def test_error_status_from_db_RJ45(self): @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1])) @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) - @patch('subprocess.check_output', MagicMock(return_value="['0:OK']")) + @patch('subprocess.check_output', MagicMock(return_value="['OK']")) def test_fetch_error_status_from_platform_api(self): output = sfputil.fetch_error_status_from_platform_api('Ethernet0') - assert output == [['Ethernet0', None]] + assert output == [['Ethernet0', 'OK']] @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1])) @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) - @patch('subprocess.check_output', MagicMock(return_value="['0:OK']")) + @patch('subprocess.check_output', MagicMock(return_value="['OK']")) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) def test_fetch_error_status_from_platform_api_RJ45(self): output = sfputil.fetch_error_status_from_platform_api('Ethernet0')