Skip to content

Commit 3d9cca6

Browse files
Fix issue: Exception occured at SfpStateUpdateTask thread due to KeyError('status') (#346)
* Fix issue: Exception occured at SfpStateUpdateTask thread due to KeyError('status') * Remove unused code * Update xcvrd.py
1 parent 11d438a commit 3d9cca6

File tree

2 files changed

+41
-90
lines changed

2 files changed

+41
-90
lines changed

sonic-xcvrd/tests/test_xcvrd.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,16 +1150,6 @@ class MockTable:
11501150
task.xcvr_table_helper.get_dom_threshold_tbl = mock_table_helper.get_dom_threshold_tbl
11511151
port_change_event = PortChangeEvent('Ethernet0', 1, 0, PortChangeEvent.PORT_ADD)
11521152
task.port_mapping.handle_port_change_event(port_change_event)
1153-
# SFP information is in the DB, copy the SFP information for the newly added logical port
1154-
task.on_add_logical_port(port_change_event)
1155-
status_tbl.get.assert_called_with('Ethernet0')
1156-
status_tbl.set.assert_called_with('Ethernet0', (('status', SFP_STATUS_INSERTED),))
1157-
int_tbl.get.assert_called_with('Ethernet0')
1158-
int_tbl.set.assert_called_with('Ethernet0', (('key2', 'value2'),))
1159-
dom_tbl.get.assert_called_with('Ethernet0')
1160-
dom_tbl.set.assert_called_with('Ethernet0', (('key3', 'value3'),))
1161-
dom_threshold_tbl.get.assert_called_with('Ethernet0')
1162-
dom_threshold_tbl.set.assert_called_with('Ethernet0', (('key4', 'value4'),))
11631153

11641154
status_tbl.get.return_value = (False, ())
11651155
mock_get_presence.return_value = True

sonic-xcvrd/xcvrd/xcvrd.py

Lines changed: 41 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,99 +2115,60 @@ def on_add_logical_port(self, port_change_event):
21152115
dict: key is logical port name, value is SFP status
21162116
"""
21172117
# A logical port is created. There could be 3 cases:
2118-
# 1. SFP information is already in DB, which means that a logical port with the same physical index is in DB before.
2119-
# Need copy the data from existing logical port and insert it into TRANSCEIVER_DOM_INFO, TRANSCEIVER_STATUS_INFO
2120-
# and TRANSCEIVER_INFO table.
2121-
# 2. SFP information is not in DB and SFP is present with no SFP error. Need query the SFP status by platform API and
2118+
# 1. SFP is present with no SFP error. Need query the SFP status by platform API and
21222119
# insert the data to DB.
2123-
# 3. SFP information is not in DB and SFP is present with SFP error. If the SFP error does not block EEPROM reading,
2120+
# 2. SFP is present with SFP error. If the SFP error does not block EEPROM reading,
21242121
# just query transceiver information and DOM sensor information via platform API and update the data to DB; otherwise,
21252122
# just update TRANSCEIVER_STATUS table with the error.
2126-
# 4. SFP information is not in DB and SFP is not present. Only update TRANSCEIVER_STATUS_INFO table.
2127-
logical_port_event_dict = {}
2128-
sfp_status = None
2129-
sibling_port = None
2123+
# 3. SFP is not present. Only update TRANSCEIVER_STATUS_INFO table.
21302124
status_tbl = self.xcvr_table_helper.get_status_tbl(port_change_event.asic_id)
21312125
int_tbl = self.xcvr_table_helper.get_intf_tbl(port_change_event.asic_id)
21322126
dom_tbl = self.xcvr_table_helper.get_dom_tbl(port_change_event.asic_id)
21332127
dom_threshold_tbl = self.xcvr_table_helper.get_dom_threshold_tbl(port_change_event.asic_id)
21342128
pm_tbl = self.xcvr_table_helper.get_pm_tbl(port_change_event.asic_id)
2135-
physical_port_list = self.port_mapping.logical_port_name_to_physical_port_list(port_change_event.port_name)
21362129

2137-
# Try to find a logical port with same physical index in DB
2138-
for physical_port in physical_port_list:
2139-
logical_port_list = self.port_mapping.get_physical_to_logical(physical_port)
2140-
if not logical_port_list:
2141-
continue
2130+
error_description = 'N/A'
2131+
status = None
2132+
read_eeprom = True
2133+
if port_change_event.port_index in self.sfp_error_dict:
2134+
value, error_dict = self.sfp_error_dict[port_change_event.port_index]
2135+
status = value
2136+
error_bits = int(value)
2137+
helper_logger.log_info("Got SFP error event {}".format(value))
21422138

2143-
for logical_port in logical_port_list:
2144-
found, sfp_status = status_tbl.get(logical_port)
2145-
if found:
2146-
sibling_port = logical_port
2147-
break
2148-
2149-
if sfp_status:
2150-
break
2139+
error_descriptions = sfp_status_helper.fetch_generic_error_description(error_bits)
21512140

2152-
if sfp_status:
2153-
# SFP information is in DB
2154-
status_tbl.set(port_change_event.port_name, sfp_status)
2155-
logical_port_event_dict[port_change_event.port_name] = dict(sfp_status)['status']
2156-
found, sfp_info = int_tbl.get(sibling_port)
2157-
if found:
2158-
int_tbl.set(port_change_event.port_name, sfp_info)
2159-
found, dom_info = dom_tbl.get(sibling_port)
2160-
if found:
2161-
dom_tbl.set(port_change_event.port_name, dom_info)
2162-
found, dom_threshold_info = dom_threshold_tbl.get(sibling_port)
2163-
if found:
2164-
dom_threshold_tbl.set(port_change_event.port_name, dom_threshold_info)
2165-
else:
2166-
error_description = 'N/A'
2167-
status = None
2168-
read_eeprom = True
2169-
if port_change_event.port_index in self.sfp_error_dict:
2170-
value, error_dict = self.sfp_error_dict[port_change_event.port_index]
2171-
status = value
2172-
error_bits = int(value)
2173-
helper_logger.log_info("Got SFP error event {}".format(value))
2174-
2175-
error_descriptions = sfp_status_helper.fetch_generic_error_description(error_bits)
2176-
2177-
if sfp_status_helper.has_vendor_specific_error(error_bits):
2178-
if error_dict:
2179-
vendor_specific_error_description = error_dict.get(port_change_event.port_index)
2180-
else:
2181-
vendor_specific_error_description = _wrapper_get_sfp_error_description(port_change_event.port_index)
2182-
error_descriptions.append(vendor_specific_error_description)
2183-
2184-
error_description = '|'.join(error_descriptions)
2185-
helper_logger.log_info("Receive error update port sfp status table.")
2186-
if sfp_status_helper.is_error_block_eeprom_reading(error_bits):
2187-
read_eeprom = False
2188-
2189-
# SFP information not in DB
2190-
if _wrapper_get_presence(port_change_event.port_index) and read_eeprom:
2191-
logical_port_event_dict[port_change_event.port_name] = sfp_status_helper.SFP_STATUS_INSERTED
2192-
transceiver_dict = {}
2193-
status = sfp_status_helper.SFP_STATUS_INSERTED if not status else status
2194-
rc = post_port_sfp_info_to_db(port_change_event.port_name, self.port_mapping, int_tbl, transceiver_dict)
2195-
if rc == SFP_EEPROM_NOT_READY:
2196-
# Failed to read EEPROM, put it to retry set
2197-
self.retry_eeprom_set.add(port_change_event.port_name)
2141+
if sfp_status_helper.has_vendor_specific_error(error_bits):
2142+
if error_dict:
2143+
vendor_specific_error_description = error_dict.get(port_change_event.port_index)
21982144
else:
2199-
post_port_dom_info_to_db(port_change_event.port_name, self.port_mapping, dom_tbl)
2200-
post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl)
2201-
update_port_transceiver_status_table_hw(port_change_event.port_name,
2202-
self.port_mapping,
2203-
status_tbl)
2204-
post_port_pm_info_to_db(port_change_event.port_name, self.port_mapping, pm_tbl)
2205-
notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.port_mapping)
2145+
vendor_specific_error_description = _wrapper_get_sfp_error_description(port_change_event.port_index)
2146+
error_descriptions.append(vendor_specific_error_description)
2147+
2148+
error_description = '|'.join(error_descriptions)
2149+
helper_logger.log_info("Receive error update port sfp status table.")
2150+
if sfp_status_helper.is_error_block_eeprom_reading(error_bits):
2151+
read_eeprom = False
2152+
2153+
# SFP information not in DB
2154+
if _wrapper_get_presence(port_change_event.port_index) and read_eeprom:
2155+
transceiver_dict = {}
2156+
status = sfp_status_helper.SFP_STATUS_INSERTED if not status else status
2157+
rc = post_port_sfp_info_to_db(port_change_event.port_name, self.port_mapping, int_tbl, transceiver_dict)
2158+
if rc == SFP_EEPROM_NOT_READY:
2159+
# Failed to read EEPROM, put it to retry set
2160+
self.retry_eeprom_set.add(port_change_event.port_name)
22062161
else:
2207-
status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status
2208-
logical_port_event_dict[port_change_event.port_name] = status
2209-
update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description)
2210-
return logical_port_event_dict
2162+
post_port_dom_info_to_db(port_change_event.port_name, self.port_mapping, dom_tbl)
2163+
post_port_dom_threshold_info_to_db(port_change_event.port_name, self.port_mapping, dom_threshold_tbl)
2164+
update_port_transceiver_status_table_hw(port_change_event.port_name,
2165+
self.port_mapping,
2166+
status_tbl)
2167+
post_port_pm_info_to_db(port_change_event.port_name, self.port_mapping, pm_tbl)
2168+
notify_media_setting(port_change_event.port_name, transceiver_dict, self.xcvr_table_helper.get_app_port_tbl(port_change_event.asic_id), self.port_mapping)
2169+
else:
2170+
status = sfp_status_helper.SFP_STATUS_REMOVED if not status else status
2171+
update_port_transceiver_status_table_sw(port_change_event.port_name, status_tbl, status, error_description)
22112172

22122173
def retry_eeprom_reading(self):
22132174
"""Retry EEPROM reading, if retry succeed, remove the logical port from the retry set

0 commit comments

Comments
 (0)