1313 import copy
1414 import sys
1515 import re
16+ import time
1617
1718 from natsort import natsorted
1819 from sonic_py_common import syslogger
3334
3435SYSLOG_IDENTIFIER_DOMINFOUPDATETASK = "DomInfoUpdateTask"
3536
36- class DomInfoUpdateTask (threading .Thread ):
37- DOM_INFO_UPDATE_PERIOD_SECS = 60
38- DIAG_DB_UPDATE_TIME_AFTER_LINK_CHANGE = 1
39- DOM_PORT_CHG_OBSERVER_TBL_MAP = [
40- {'APPL_DB' : 'PORT_TABLE' , 'FILTER' : ['flap_count' ]},
41- ]
37+ class DomInfoUpdateBase (threading .Thread ):
4238
43- def __init__ (self , namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event , skip_cmis_mgr ):
39+ name = ''
40+
41+ def __init__ (self , namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event ):
4442 threading .Thread .__init__ (self )
45- self .name = "DomInfoUpdateTask"
4643 self .exc = None
4744 self .task_stopping_event = threading .Event ()
4845 self .main_thread_stop_event = main_thread_stop_event
4946 self .helper_logger = syslogger .SysLogger (SYSLOG_IDENTIFIER_DOMINFOUPDATETASK , enable_runtime_config = True )
5047 self .port_mapping = copy .deepcopy (port_mapping )
5148 self .namespaces = namespaces
52- self .skip_cmis_mgr = skip_cmis_mgr
5349 self .sfp_obj_dict = sfp_obj_dict
54- self .link_change_affected_ports = {}
55- self .xcvr_table_helper = XcvrTableHelper (self .namespaces )
56- self .xcvrd_utils = XCVRDUtils (self .sfp_obj_dict , helper_logger )
57- self .dom_db_utils = DOMDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
58- self .db_utils = self .dom_db_utils
59- self .vdm_utils = VDMUtils (self .sfp_obj_dict , self .helper_logger )
60- self .vdm_db_utils = VDMDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
61- self .status_db_utils = StatusDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
6250
6351 def log_debug (self , message ):
6452 self .helper_logger .log_debug ("{}" .format (message ))
@@ -75,6 +63,14 @@ def log_warning(self, message):
7563 def log_error (self , message ):
7664 self .helper_logger .log_error ("{}" .format (message ))
7765
66+ def on_port_config_change (self , port_change_event ):
67+ if port_change_event .event_type == port_event_helper .PortChangeEvent .PORT_REMOVE :
68+ self .on_remove_logical_port (port_change_event )
69+ self .port_mapping .handle_port_change_event (port_change_event )
70+
71+ def on_remove_logical_port (self , port_change_event ):
72+ pass
73+
7874 def get_dom_polling_from_config_db (self , lport ):
7975 """
8076 Returns the value of dom_polling field from PORT table in CONFIG_DB
@@ -110,6 +106,51 @@ def get_dom_polling_from_config_db(self, lport):
110106
111107 return dom_polling
112108
109+
110+ def is_port_dom_monitoring_disabled (self , logical_port_name ):
111+ return self .get_dom_polling_from_config_db (logical_port_name ) == 'disabled'
112+
113+ def task_worker (self ):
114+ pass
115+
116+ def run (self ):
117+ if self .task_stopping_event .is_set ():
118+ return
119+ try :
120+ self .task_worker ()
121+ except Exception as e :
122+ self .log_error ("Exception occured at {} thread due to {}" .format (threading .current_thread ().getName (), repr (e )))
123+ xcvrd .log_exception_traceback ()
124+ self .exc = e
125+ self .main_thread_stop_event .set ()
126+
127+ def join (self ):
128+ self .task_stopping_event .set ()
129+ threading .Thread .join (self )
130+ if self .exc :
131+ raise self .exc
132+
133+ class DomInfoUpdateTask (DomInfoUpdateBase ):
134+ name = "DomInfoUpdateTask"
135+
136+ DOM_INFO_UPDATE_PERIOD_SECS = 60
137+ DIAG_DB_UPDATE_TIME_AFTER_LINK_CHANGE = 1
138+ DOM_PORT_CHG_OBSERVER_TBL_MAP = [
139+ {'APPL_DB' : 'PORT_TABLE' , 'FILTER' : ['flap_count' ]},
140+ ]
141+
142+ def __init__ (self , namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event , skip_cmis_mgr ):
143+ super ().__init__ (namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event )
144+ self .skip_cmis_mgr = skip_cmis_mgr
145+ self .link_change_affected_ports = {}
146+ self .xcvr_table_helper = XcvrTableHelper (self .namespaces )
147+ self .xcvrd_utils = XCVRDUtils (self .sfp_obj_dict , helper_logger )
148+ self .dom_db_utils = DOMDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
149+ self .db_utils = self .dom_db_utils
150+ self .vdm_utils = VDMUtils (self .sfp_obj_dict , self .helper_logger )
151+ self .vdm_db_utils = VDMDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
152+ self .status_db_utils = StatusDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
153+
113154 """
114155 Checks if the port is going through CMIS initialization process
115156 This API assumes CMIS_STATE_UNKNOWN as a transitional state since it is the
@@ -339,23 +380,6 @@ def task_worker(self):
339380
340381 self .log_notice ("Stop DOM monitoring loop" )
341382
342- def run (self ):
343- if self .task_stopping_event .is_set ():
344- return
345- try :
346- self .task_worker ()
347- except Exception as e :
348- self .log_error ("Exception occured at {} thread due to {}" .format (threading .current_thread ().getName (), repr (e )))
349- common .log_exception_traceback ()
350- self .exc = e
351- self .main_thread_stop_event .set ()
352-
353- def join (self ):
354- self .task_stopping_event .set ()
355- threading .Thread .join (self )
356- if self .exc :
357- raise self .exc
358-
359383 def on_port_update_event (self , port_change_event ):
360384 """Called when a port change event is received
361385
@@ -427,11 +451,6 @@ def update_port_db_diagnostics_on_link_change(self, physical_port):
427451 self .log_warning (f"Update DB diagnostics during link change: Got exception { repr (e )} while processing vdm flags for port { first_logical_port } , ignored" )
428452 return
429453
430- def on_port_config_change (self , port_change_event ):
431- if port_change_event .event_type == port_event_helper .PortChangeEvent .PORT_REMOVE :
432- self .on_remove_logical_port (port_change_event )
433- self .port_mapping .handle_port_change_event (port_change_event )
434-
435454 def on_remove_logical_port (self , port_change_event ):
436455 """Called when a logical port is removed from CONFIG_DB
437456
@@ -444,6 +463,7 @@ def on_remove_logical_port(self, port_change_event):
444463 common .del_port_sfp_dom_info_from_db (port_change_event .port_name ,
445464 self .port_mapping ,
446465 [self .xcvr_table_helper .get_dom_tbl (port_change_event .asic_id ),
466+ self .xcvr_table_helper .get_dom_temperature_tbl (port_change_event .asic_id ),
447467 self .xcvr_table_helper .get_dom_flag_tbl (port_change_event .asic_id ),
448468 self .xcvr_table_helper .get_dom_flag_change_count_tbl (port_change_event .asic_id ),
449469 self .xcvr_table_helper .get_dom_flag_set_time_tbl (port_change_event .asic_id ),
@@ -461,3 +481,60 @@ def on_remove_logical_port(self, port_change_event):
461481 self .xcvr_table_helper .get_pm_tbl (port_change_event .asic_id ),
462482 self .xcvr_table_helper .get_firmware_info_tbl (port_change_event .asic_id )
463483 ])
484+
485+ class DomThermalInfoUpdateTask (DomInfoUpdateBase ):
486+ name = 'DomThermalInfoUpdateTask'
487+
488+ DOM_INFO_UPDATE_PERIOD_SECS = 5
489+
490+ def __init__ (self , namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event ):
491+ super ().__init__ (namespaces , port_mapping , sfp_obj_dict , main_thread_stop_event )
492+ self .xcvr_table_helper = XcvrTableHelper (self .namespaces )
493+ self .dom_db_utils = DOMDBUtils (self .sfp_obj_dict , self .port_mapping , self .xcvr_table_helper , self .task_stopping_event , self .helper_logger )
494+
495+ def task_worker (self ):
496+ self .log_notice ("Start DOM thermal monitoring loop" )
497+
498+ # Set the periodic db update time
499+ dom_info_update_periodic_secs = self .DOM_INFO_UPDATE_PERIOD_SECS
500+
501+ # Poll transceiver temperature as soon as possible
502+ next_periodic_db_update_time = datetime .datetime .now ()
503+
504+ # Start loop to update dom info in DB periodically and handle port change events
505+ while not self .task_stopping_event .is_set ():
506+ # Check if periodic db update is needed
507+ now = datetime .datetime .now ()
508+ if next_periodic_db_update_time > now :
509+ # Sleep for 1 second or less depending on the remaining time
510+ time .sleep (min (1 , (next_periodic_db_update_time - now ).total_seconds ()))
511+ continue
512+
513+ for physical_port , logical_ports in self .port_mapping .physical_to_logical .items ():
514+ # Get the first logical port name since it corresponds to the first subport
515+ # of the breakout group
516+ logical_port_name = logical_ports [0 ]
517+
518+ if self .is_port_dom_monitoring_disabled (logical_port_name ):
519+ continue
520+
521+ # Get the asic to which this port belongs
522+ asic_index = self .port_mapping .get_asic_id_for_logical_port (logical_port_name )
523+ if asic_index is None :
524+ self .log_warning ("Got invalid asic index for {}, ignored" .format (logical_port_name ))
525+ continue
526+
527+ if not sfp_status_helper .detect_port_in_error_status (logical_port_name , self .xcvr_table_helper .get_status_sw_tbl (asic_index )):
528+ if not xcvrd ._wrapper_get_presence (physical_port ):
529+ continue
530+
531+ try :
532+ self .dom_db_utils .post_port_dom_temperature_info_to_db (logical_port_name )
533+ except (KeyError , TypeError ) as e :
534+ #continue to process next port since exception could be raised due to port reset, transceiver removal
535+ self .log_warning ("Got exception {} while processing dom info for port {}, ignored" .format (repr (e ), logical_port_name ))
536+
537+ # Set the periodic db update time after all the ports are processed
538+ next_periodic_db_update_time = now + datetime .timedelta (seconds = dom_info_update_periodic_secs )
539+
540+ self .log_notice ("Stop DOM thermal monitoring loop" )
0 commit comments