@@ -896,12 +896,44 @@ def on_port_update_event(self, port_change_event):
896
896
897
897
self .force_cmis_reinit (lport , 0 )
898
898
899
- # PORT_DEL event for the same lport happens 3 times because
900
- # we are subscribing to CONFIG_DB, STATE_DB|TRANSCEIVER_INFO, and STATE_DB|PORT_TABLE.
901
- # To only handle the first one, check if the lport exists in the port_dict.
902
- elif lport in self .port_dict :
903
- self .update_port_transceiver_status_table_sw_cmis_state (lport , CMIS_STATE_REMOVED )
904
- self .port_dict .pop (lport )
899
+ elif port_change_event .event_type == port_change_event .PORT_DEL :
900
+ # In handling the DEL event, the following two scenarios must be considered:
901
+ # 1. PORT_DEL event due to transceiver plug-out
902
+ # 2. PORT_DEL event due to Dynamic Port Breakout (DPB)
903
+ #
904
+ # Scenario 1 is simple, as only a STATE_DB|TRANSCEIVER_INFO PORT_DEL event occurs,
905
+ # so we just need to set SW_CMIS_STATE to CMIS_STATE_REMOVED.
906
+ #
907
+ # Scenario 2 is a bit more complex. First, for the port(s) before DPB, a CONFIG_DB|PORT PORT_DEL
908
+ # and a STATE_DB|PORT_TABLE PORT_DEL event occur. Next, for the port(s) after DPB,
909
+ # a CONFIG_DB|PORT PORT_SET and a STATE_DB|PORT_TABLE PORT_SET event occur.
910
+ # After that (after a short delay), a STATE_DB|TRANSCEIVER_INFO PORT_DEL event
911
+ # occurs for the port(s) before DPB, and finally, a STATE_DB|TRANSCEIVER_INFO
912
+ # PORT_SET event occurs for the port(s) after DPB.
913
+ #
914
+ # Below is the event sequence when configuring Ethernet0 from "2x200G" to "1x400G"
915
+ # (based on actual logs).
916
+ #
917
+ # 1. SET Ethernet0 CONFIG_DB|PORT
918
+ # 2. DEL Ethernet2 CONFIG_DB|PORT
919
+ # 3. DEL Ethernet0 CONFIG_DB|PORT
920
+ # 4. DEL Ethernet0 STATE_DB|PORT_TABLE
921
+ # 5. DEL Ethernet2 STATE_DB|PORT_TABLE
922
+ # 6. SET Ethernet0 CONFIG_DB|PORT
923
+ # 7. SET Ethernet0 STATE_DB|PORT_TABLE
924
+ # 8. SET Ethernet0 STATE_DB|PORT_TABLE
925
+ # 9. DEL Ethernet2 STATE_DB|TRANSCEIVER_INFO
926
+ # 10. DEL Ethernet0 STATE_DB|TRANSCEIVER_INFO
927
+ # 11. SET Ethernet0 STATE_DB|TRANSCEIVER_INFO
928
+ #
929
+ # To handle both scenarios, if the lport exists in port_dict for any DEL EVENT,
930
+ # set SW_CMIS_STATE to REMOVED. Additionally, for DEL EVENTS from CONFIG_DB due to DPB,
931
+ # remove the lport from port_dict.
932
+ if lport in self .port_dict :
933
+ self .update_port_transceiver_status_table_sw_cmis_state (lport , CMIS_STATE_REMOVED )
934
+
935
+ if port_change_event .db_name == 'CONFIG_DB' and port_change_event .table_name == 'PORT' :
936
+ self .port_dict .pop (lport )
905
937
906
938
def get_cmis_dp_init_duration_secs (self , api ):
907
939
return api .get_datapath_init_duration ()/ 1000
0 commit comments