@@ -100,6 +100,39 @@ def y_cable_wrapper_get_presence(physical_port):
100100 return y_cable_platform_sfputil .get_presence (physical_port )
101101
102102
103+
104+ def hook_y_cable_simulated (target ):
105+ """
106+ Decorator to add hook for using the simulated y_cable driver.
107+ This decorator checks existence of the configuration file required by the simulated y_cable driver. If the
108+ configuration file is found, then override the "manufacturer" and "model" fields with value "microsoft" and
109+ "simulated" in the collected transceiver info dict. Consequently, instance of the simulated y_cable driver
110+ class will be initialized.
111+ When the configuration file is not found on system, then just return the original transceiver info to initialize
112+ instance of y_cable driver class of whatever actually plugged physical y_cable.
113+ For test systems using simulated y_cable, we can just inject the simulated y_cable driver config file then
114+ restart the pmon service before testing starts.
115+
116+ Args:
117+ target (function): The function collecting transceiver info.
118+ """
119+
120+ MUX_SIMULATOR_CONFIG_FILE = "/etc/sonic/mux_simulator.json"
121+ VENDOR = "microsoft"
122+ MODEL = "simulated"
123+
124+ def wrapper (* args , ** kwargs ):
125+ res = target (* args , ** kwargs )
126+ if os .path .exists (MUX_SIMULATOR_CONFIG_FILE ):
127+ res ["manufacturer" ] = VENDOR
128+ res ["model" ] = MODEL
129+ return res
130+
131+ wrapper .__name__ = target .__name__
132+
133+ return wrapper
134+
135+ @hook_y_cable_simulated
103136def y_cable_wrapper_get_transceiver_info (physical_port ):
104137 if y_cable_platform_chassis is not None :
105138 try :
@@ -435,6 +468,23 @@ def read_y_cable_and_update_statedb_port_tbl(logical_port_name, mux_config_tbl):
435468 helper_logger .log_warning (
436469 "Error: Retreived multiple ports for a Y cable port {} to perform read_y_cable update state db" .format (logical_port_name ))
437470
471+ def create_tables_and_insert_mux_unknown_entries (state_db , y_cable_tbl , static_tbl , mux_tbl , asic_index , logical_port_name ):
472+
473+ namespaces = multi_asic .get_front_end_namespaces ()
474+ for namespace in namespaces :
475+ asic_id = multi_asic .get_asic_index_from_namespace (
476+ namespace )
477+ state_db [asic_id ] = daemon_base .db_connect (
478+ "STATE_DB" , namespace )
479+ y_cable_tbl [asic_id ] = swsscommon .Table (
480+ state_db [asic_id ], swsscommon .STATE_HW_MUX_CABLE_TABLE_NAME )
481+ static_tbl [asic_id ] = swsscommon .Table (
482+ state_db [asic_id ], MUX_CABLE_STATIC_INFO_TABLE )
483+ mux_tbl [asic_id ] = swsscommon .Table (
484+ state_db [asic_id ], MUX_CABLE_INFO_TABLE )
485+ # fill the newly found entry
486+ read_y_cable_and_update_statedb_port_tbl (
487+ logical_port_name , y_cable_tbl [asic_index ])
438488
439489def check_identifier_presence_and_update_mux_table_entry (state_db , port_tbl , y_cable_tbl , static_tbl , mux_tbl , asic_index , logical_port_name , y_cable_presence ):
440490
@@ -561,15 +611,22 @@ def check_identifier_presence_and_update_mux_table_entry(state_db, port_tbl, y_c
561611 else :
562612 helper_logger .log_warning (
563613 "Error: Could not get transceiver info dict Y cable port {} while inserting entries" .format (logical_port_name ))
614+ create_tables_and_insert_mux_unknown_entries (state_db , y_cable_tbl , static_tbl , mux_tbl , asic_index , logical_port_name )
615+
564616 else :
565617 helper_logger .log_warning (
566618 "Error: Could not establish transceiver presence for a Y cable port {} while inserting entries" .format (logical_port_name ))
619+ create_tables_and_insert_mux_unknown_entries (state_db , y_cable_tbl , static_tbl , mux_tbl , asic_index , logical_port_name )
620+
567621 else :
568622 helper_logger .log_warning (
569623 "Error: Retreived multiple ports for a Y cable port {} while inserting entries" .format (logical_port_name ))
624+ create_tables_and_insert_mux_unknown_entries (state_db , y_cable_tbl , static_tbl , mux_tbl , asic_index , logical_port_name )
625+
570626 else :
571627 helper_logger .log_warning (
572628 "Could not retreive active or auto value for state kvp for {}, inside MUX_CABLE table" .format (logical_port_name ))
629+
573630 else :
574631 helper_logger .log_warning (
575632 "Could not retreive state value inside mux_info_dict for {}, inside MUX_CABLE table" .format (logical_port_name ))
@@ -766,7 +823,7 @@ def delete_ports_status_for_y_cable():
766823 asic_index = y_cable_platform_sfputil .get_asic_id_for_logical_port (
767824 logical_port_name )
768825 if asic_index is None :
769- logger .log_warning (
826+ helper_logger .log_warning (
770827 "Got invalid asic index for {}, ignored" .format (logical_port_name ))
771828
772829 if logical_port_name in y_cable_tbl_keys [asic_index ]:
@@ -905,9 +962,9 @@ def get_muxcable_info(physical_port, logical_port_name):
905962
906963 if mux_dir_val is None or mux_dir_val == port_instance .EEPROM_ERROR or mux_dir_val < 0 :
907964 mux_direction = 'unknown'
908- elif read_side == mux_dir_val and ( active_side == 1 or active_side == 2 ) :
965+ elif read_side == mux_dir_val :
909966 mux_direction = 'self'
910- elif read_side != mux_dir_val and ( active_side == 1 or active_side == 2 ) :
967+ elif read_side != mux_dir_val :
911968 mux_direction = 'peer'
912969 else :
913970 mux_direction = 'unknown'
@@ -999,7 +1056,6 @@ def get_muxcable_info(physical_port, logical_port_name):
9991056 except Exception as e :
10001057 link_state_tor_b = False
10011058 helper_logger .log_warning ("Failed to execute the is_link_active TOR B side API for port {} due to {}" .format (physical_port ,repr (e )))
1002-
10031059 if link_state_tor_b :
10041060 mux_info_dict ["link_status_peer" ] = "up"
10051061 else :
@@ -1016,6 +1072,7 @@ def get_muxcable_info(physical_port, logical_port_name):
10161072 mux_info_dict ["link_status_self" ] = "up"
10171073 else :
10181074 mux_info_dict ["link_status_self" ] = "down"
1075+
10191076 with y_cable_port_locks [physical_port ]:
10201077 try :
10211078 link_state_tor_a = port_instance .is_link_active (port_instance .TARGET_TOR_A )
@@ -1342,7 +1399,7 @@ def post_mux_static_info_to_db(is_warm_start, stop_event=threading.Event()):
13421399 asic_index = y_cable_platform_sfputil .get_asic_id_for_logical_port (
13431400 logical_port_name )
13441401 if asic_index is None :
1345- logger .log_warning ("Got invalid asic index for {}, ignored" .format (logical_port_name ))
1402+ helper_logger .log_warning ("Got invalid asic index for {}, ignored" .format (logical_port_name ))
13461403 continue
13471404 post_port_mux_static_info_to_db (logical_port_name , mux_tbl [asic_index ])
13481405
@@ -1369,7 +1426,7 @@ def post_mux_info_to_db(is_warm_start, stop_event=threading.Event()):
13691426 asic_index = y_cable_platform_sfputil .get_asic_id_for_logical_port (
13701427 logical_port_name )
13711428 if asic_index is None :
1372- logger .log_warning (
1429+ helper_logger .log_warning (
13731430 "Got invalid asic index for {}, ignored" .format (logical_port_name ))
13741431 continue
13751432 post_port_mux_info_to_db (logical_port_name , mux_tbl [asic_index ])
@@ -1396,6 +1453,7 @@ def __init__(self):
13961453 self .task_thread = None
13971454 self .task_cli_thread = None
13981455 self .task_download_firmware_thread = {}
1456+ self .task_stopping_event = threading .Event ()
13991457
14001458 if multi_asic .is_multi_asic ():
14011459 # Load the namespace details first from the database_global.json file.
@@ -1438,6 +1496,9 @@ def task_worker(self):
14381496 # Use timeout to prevent ignoring the signals we want to handle
14391497 # in signal_handler() (e.g. SIGTERM for graceful shutdown)
14401498
1499+ if self .task_stopping_event .is_set ():
1500+ break
1501+
14411502 (state , selectableObj ) = sel .select (SELECT_TIMEOUT )
14421503
14431504 if state == swsscommon .Select .TIMEOUT :
@@ -1631,11 +1692,14 @@ def task_cli_worker(self):
16311692 sel .addSelectable (xcvrd_show_hwmode_swmode_cmd_tbl [asic_id ])
16321693 sel .addSelectable (xcvrd_config_hwmode_swmode_cmd_tbl [asic_id ])
16331694
1634- # Listen indefinitely for changes to the HW_MUX_CABLE_TABLE in the Application DB's
1695+ # Listen indefinitely for changes to the XCVRD_CMD_TABLE in the Application DB's
16351696 while True :
16361697 # Use timeout to prevent ignoring the signals we want to handle
16371698 # in signal_handler() (e.g. SIGTERM for graceful shutdown)
16381699
1700+ if self .task_stopping_event .is_set ():
1701+ break
1702+
16391703 (state , selectableObj ) = sel .select (SELECT_TIMEOUT )
16401704
16411705 if state == swsscommon .Select .TIMEOUT :
@@ -2207,10 +2271,12 @@ def task_run(self):
22072271 self .task_cli_thread .start ()
22082272
22092273 def task_stop (self ):
2274+
2275+ self .task_stopping_event .set ()
2276+ helper_logger .log_info ("stopping the cli and probing task threads xcvrd" )
22102277 self .task_thread .join ()
22112278 self .task_cli_thread .join ()
22122279
2213- helper_logger .log_warning ("stopping the task" )
22142280 for key , value in self .task_download_firmware_thread .items ():
22152281 self .task_download_firmware_thread [key ].join ()
2216- helper_logger .log_warning ("stopped" )
2282+ helper_logger .log_info ("stopped all thread " )
0 commit comments