Skip to content

Commit 24fba04

Browse files
authored
[ycable] fix the logic to update cable_info values when ycable is not present; fix read side logic for ycable (sonic-net#249)
Description This PR fixes the MUX_CABLE_INFO table insertion logic which was not done before this PR. If the muxcable is plugged in, with this change if the config DB states that it is a muxcable then the logic populates the MUX_CABLE_INFO with 'N/A' or 'unknown' entries. This was not done before This PR also fixes the read_side logic, which if initialized with a -1 value would never be updated to the correct value, this PR makes sure that if the read_side is read correctly if cable not powered on/disconnected from server side, and the read_side is populated correctly in state DB. Before this change the read_side was not populated correctly if the cable was not powered from server side/disconnected. Motivation and Context Required for the logic of services looking for MUX_CABLE_INFO values which require this be populated without cable presence. read_side fix logic makes sure that if the cable is powered off/disconnected from server side then the cable driver works well in those cases How Has This Been Tested? Unit-Tests and tested in the lab Signed-off-by: vaibhav-dahiya <[email protected]>
1 parent f09bd31 commit 24fba04

File tree

2 files changed

+157
-32
lines changed

2 files changed

+157
-32
lines changed

sonic-ycabled/tests/test_y_cable_helper.py

+67-6
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ def test_update_tor_active_side_1_active(self):
413413

414414
rc = update_tor_active_side(read_side, state, logical_port_name)
415415

416-
assert(rc == 1)
416+
assert(rc == (1, 1))
417417

418418
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
419419
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
@@ -429,7 +429,7 @@ def test_update_tor_active_side_2_active(self):
429429

430430
rc = update_tor_active_side(read_side, state, logical_port_name)
431431

432-
assert(rc == 2)
432+
assert(rc == (2,2))
433433

434434
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
435435
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
@@ -445,7 +445,7 @@ def test_update_tor_active_side_1_standby(self):
445445

446446
rc = update_tor_active_side(read_side, state, logical_port_name)
447447

448-
assert(rc == 2)
448+
assert(rc == (2,1))
449449

450450
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
451451
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
@@ -461,7 +461,7 @@ def test_update_tor_active_side_2_standby(self):
461461

462462
rc = update_tor_active_side(read_side, state, logical_port_name)
463463

464-
assert(rc == 1)
464+
assert(rc == (1,2))
465465

466466
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
467467
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=False))
@@ -477,7 +477,7 @@ def test_update_tor_active_side_no_cable_presence(self):
477477

478478
rc = update_tor_active_side(read_side, state, logical_port_name)
479479

480-
assert(rc == -1)
480+
assert(rc == (-1,-1))
481481

482482
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0, 1, 2]))
483483
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=False))
@@ -493,7 +493,68 @@ def test_update_tor_active_side_multiple_mappings(self):
493493

494494
rc = update_tor_active_side(read_side, state, logical_port_name)
495495

496-
assert(rc == -1)
496+
assert(rc == (-1,-1))
497+
498+
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
499+
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
500+
def test_update_tor_active_side_with_read_update(self):
501+
read_side = -1
502+
state = "active"
503+
logical_port_name = "Ethernet0"
504+
with patch('ycable.ycable_utilities.y_cable_helper.y_cable_port_instances') as patched_util:
505+
506+
mock_toggle_object = MagicMock()
507+
mock_toggle_object.toggle_mux_to_tor_a.return_value = True
508+
mock_toggle_object.get_read_side.return_value = 1
509+
patched_util.get.return_value = mock_toggle_object
510+
511+
rc = update_tor_active_side(read_side, state, logical_port_name)
512+
513+
assert(rc == (1, 1))
514+
515+
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
516+
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
517+
def test_update_tor_active_side_with_read_update(self):
518+
read_side = -1
519+
state = "active"
520+
logical_port_name = "Ethernet0"
521+
with patch('ycable.ycable_utilities.y_cable_helper.y_cable_port_instances') as patched_util:
522+
523+
mock_toggle_object = MagicMock()
524+
mock_toggle_object.toggle_mux_to_tor_b.return_value = True
525+
mock_toggle_object.get_read_side.return_value = 2
526+
patched_util.get.return_value = mock_toggle_object
527+
528+
rc = update_tor_active_side(read_side, state, logical_port_name)
529+
530+
assert(rc == (2, 1))
531+
532+
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
533+
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))
534+
def test_update_tor_active_side_with_read_update(self):
535+
read_side = -1
536+
state = "active"
537+
logical_port_name = "Ethernet0"
538+
with patch('ycable.ycable_utilities.y_cable_helper.y_cable_port_instances') as patched_util:
539+
540+
mock_toggle_object = MagicMock()
541+
mock_toggle_object.toggle_mux_to_tor_b.return_value = True
542+
mock_toggle_object.get_read_side.return_value = -1
543+
patched_util.get.return_value = mock_toggle_object
544+
545+
rc = update_tor_active_side(read_side, state, logical_port_name)
546+
547+
assert(rc == (-1, -1))
548+
549+
def test_get_mux_cable_info_without_presence(self):
550+
551+
rc = get_muxcable_info_without_presence()
552+
553+
assert(rc['tor_active'] == 'unknown')
554+
assert(rc['mux_direction'] == 'unknown')
555+
assert(rc['manual_switch_count'] == 'N/A')
556+
assert(rc['auto_switch_count'] == 'N/A')
557+
497558

498559
@patch('ycable.ycable_utilities.y_cable_helper.logical_port_name_to_physical_port_list', MagicMock(return_value=[0]))
499560
@patch('ycable.ycable_utilities.y_cable_helper.y_cable_wrapper_get_presence', MagicMock(return_value=True))

sonic-ycabled/ycable/ycable_utilities/y_cable_helper.py

+90-26
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,40 @@ def y_cable_toggle_mux_torB(physical_port):
302302
return -1
303303

304304

305+
def toggle_mux_direction(physical_port, read_side, state):
306+
307+
if int(read_side) == 1:
308+
if state == "active":
309+
return (y_cable_toggle_mux_torA(physical_port), read_side)
310+
elif state == "standby":
311+
return (y_cable_toggle_mux_torB(physical_port), read_side)
312+
elif int(read_side) == 2:
313+
if state == "active":
314+
return (y_cable_toggle_mux_torB(physical_port), read_side)
315+
elif state == "standby":
316+
return (y_cable_toggle_mux_torA(physical_port), read_side)
317+
318+
def toggle_mux_tor_direction_and_update_read_side(state, logical_port_name, physical_port):
319+
320+
port_instance = y_cable_port_instances.get(physical_port)
321+
if port_instance is None:
322+
helper_logger.log_error("Error: Could not get port instance for read side for while processing a toggle Y cable port {} {}".format(physical_port, threading.currentThread().getName()))
323+
return (-1, -1)
324+
325+
read_side = port_instance.get_read_side()
326+
327+
if read_side is None or read_side is port_instance.EEPROM_ERROR or read_side < 0:
328+
helper_logger.log_error(
329+
"Error: Could not get read side for toggle command from orchagent Y cable port {}".format(logical_port_name))
330+
return (-1, -1)
331+
if int(read_side) == 1 or int(read_side) == 2:
332+
(active_side, read_side) = toggle_mux_direction(physical_port, read_side, state)
333+
return (active_side, read_side)
334+
else:
335+
#should not happen
336+
return (-1,-1)
337+
338+
305339
def update_tor_active_side(read_side, state, logical_port_name):
306340
physical_port_list = logical_port_name_to_physical_port_list(
307341
logical_port_name)
@@ -310,34 +344,28 @@ def update_tor_active_side(read_side, state, logical_port_name):
310344

311345
physical_port = physical_port_list[0]
312346
if y_cable_wrapper_get_presence(physical_port):
313-
if int(read_side) == 1:
314-
if state == "active":
315-
return y_cable_toggle_mux_torA(physical_port)
316-
elif state == "standby":
317-
return y_cable_toggle_mux_torB(physical_port)
318-
elif int(read_side) == 2:
319-
if state == "active":
320-
return y_cable_toggle_mux_torB(physical_port)
321-
elif state == "standby":
322-
return y_cable_toggle_mux_torA(physical_port)
347+
if int(read_side) == 1 or int(read_side) == 2:
348+
(active_side, read_side) = toggle_mux_direction(physical_port, read_side, state)
349+
return (active_side, read_side)
323350
else:
324351
# not a valid read side
325-
return -1
352+
(active_side, read_side) = toggle_mux_tor_direction_and_update_read_side(state, logical_port_name, physical_port)
353+
return (active_side, read_side)
326354

327355
# TODO: Should we confirm that the mux was indeed toggled?
328356

329357
else:
330358
helper_logger.log_warning(
331359
"Error: Could not establish presence for Y cable port {} while trying to toggle the mux".format(logical_port_name))
332-
return -1
360+
return (-1, -1)
333361

334362
else:
335363
# Y cable ports should always have
336364
# one to one mapping of physical-to-logical
337365
# This should not happen
338366
helper_logger.log_warning(
339367
"Error: Retreived multiple ports for a Y cable table port {} while trying to toggle the mux".format(logical_port_name))
340-
return -1
368+
return (-1, -1)
341369

342370

343371
def update_appdb_port_mux_cable_response_table(logical_port_name, asic_index, appl_db, read_side):
@@ -460,11 +488,11 @@ def read_y_cable_and_update_statedb_port_tbl(logical_port_name, mux_config_tbl):
460488
helper_logger.log_warning("Failed to execute the get_mux_direction for port {} due to {}".format(physical_port,repr(e)))
461489

462490
if active_side is None or active_side not in y_cable_switch_state_values:
463-
read_side = active_side = -1
491+
active_side = -1
464492
update_table_mux_status_for_statedb_port_tbl(
465493
mux_config_tbl, "unknown", read_side, active_side, logical_port_name)
466494
helper_logger.log_error(
467-
"Error: Could not establish the active side for Y cable port {} to perform read_y_cable update state db".format(logical_port_name))
495+
"Error: Could not establish the active side for Y cable port {} to perform read_y_cable update state db".format(logical_port_name))
468496
return
469497

470498
if read_side == active_side and (active_side == 1 or active_side == 2):
@@ -693,13 +721,18 @@ def check_identifier_presence_and_delete_mux_table_entry(state_db, port_tbl, asi
693721
static_tbl[asic_id] = swsscommon.Table(state_db[asic_id], MUX_CABLE_STATIC_INFO_TABLE)
694722
mux_tbl[asic_id] = swsscommon.Table(state_db[asic_id], MUX_CABLE_INFO_TABLE)
695723
# fill the newly found entry
696-
#delete_port_from_y_cable_table(logical_port_name, y_cable_tbl[asic_index])
697724
#We dont delete the values here, rather just update the values in state DB
698-
read_side = active_side = -1
725+
(status, fvs) = y_cable_tbl[asic_index].get(logical_port_name)
726+
if status is False:
727+
helper_logger.log_warning("Could not retreive fieldvalue pairs for {}, inside state_db table {} while deleting mux entry".format(
728+
logical_port_name, y_cable_tbl[asic_index].getTableName()))
729+
mux_port_dict = dict(fvs)
730+
read_side = mux_port_dict.get("read_side", None)
731+
active_side = -1
699732
update_table_mux_status_for_statedb_port_tbl(
700733
y_cable_tbl[asic_index], "unknown", read_side, active_side, logical_port_name)
701-
delete_port_from_y_cable_table(logical_port_name, static_tbl[asic_index])
702-
delete_port_from_y_cable_table(logical_port_name, mux_tbl[asic_index])
734+
#delete_port_from_y_cable_table(logical_port_name, static_tbl[asic_index])
735+
#delete_port_from_y_cable_table(logical_port_name, mux_tbl[asic_index])
703736
delete_change_event[:] = [True]
704737
# delete the y_cable instance
705738
physical_port_list = logical_port_name_to_physical_port_list(logical_port_name)
@@ -981,6 +1014,37 @@ def get_firmware_dict(physical_port, port_instance, target, side, mux_info_dict,
9811014
mux_info_dict[("version_{}_next".format(side))] = "N/A"
9821015

9831016

1017+
def get_muxcable_info_without_presence():
1018+
mux_info_dict = {}
1019+
mux_info_dict['tor_active'] = 'unknown'
1020+
mux_info_dict['mux_direction'] = 'unknown'
1021+
mux_info_dict['manual_switch_count'] = 'N/A'
1022+
mux_info_dict['auto_switch_count'] = 'N/A'
1023+
mux_info_dict['link_status_self'] = 'unknown'
1024+
mux_info_dict['link_status_peer'] = 'unknown'
1025+
mux_info_dict['link_status_nic'] = 'unknown'
1026+
mux_info_dict['self_eye_height_lane1'] = 'N/A'
1027+
mux_info_dict['self_eye_height_lane2'] = 'N/A'
1028+
mux_info_dict['peer_eye_height_lane1'] = 'N/A'
1029+
mux_info_dict['peer_eye_height_lane2'] = 'N/A'
1030+
mux_info_dict['nic_eye_height_lane1'] = 'N/A'
1031+
mux_info_dict['nic_eye_height_lane2'] = 'N/A'
1032+
mux_info_dict['internal_temperature'] = 'N/A'
1033+
mux_info_dict['internal_voltage'] = 'N/A'
1034+
mux_info_dict['nic_temperature'] = 'N/A'
1035+
mux_info_dict['nic_voltage'] = 'N/A'
1036+
mux_info_dict['version_self_active'] = 'N/A'
1037+
mux_info_dict['version_self_inactive'] = 'N/A'
1038+
mux_info_dict['version_self_next'] = 'N/A'
1039+
mux_info_dict['version_peer_active'] = 'N/A'
1040+
mux_info_dict['version_peer_inactive'] = 'N/A'
1041+
mux_info_dict['version_peer_next'] = 'N/A'
1042+
mux_info_dict['version_nic_active'] = 'N/A'
1043+
mux_info_dict['version_nic_inactive'] = 'N/A'
1044+
mux_info_dict['version_nic_next'] = 'N/A'
1045+
1046+
return mux_info_dict
1047+
9841048
def get_muxcable_info(physical_port, logical_port_name):
9851049

9861050
mux_info_dict = {}
@@ -1358,9 +1422,10 @@ def post_port_mux_info_to_db(logical_port_name, table):
13581422

13591423
if not y_cable_wrapper_get_presence(physical_port):
13601424
helper_logger.log_warning("Error: trying to post mux info without presence of port {}".format(logical_port_name))
1361-
continue
1425+
mux_info_dict = get_muxcable_info_without_presence()
1426+
else:
1427+
mux_info_dict = get_muxcable_info(physical_port, logical_port_name)
13621428

1363-
mux_info_dict = get_muxcable_info(physical_port, logical_port_name)
13641429
if mux_info_dict is not None and mux_info_dict is not -1:
13651430
#transceiver_dict[physical_port] = port_info_dict
13661431
fvs = swsscommon.FieldValuePairs(
@@ -2456,22 +2521,22 @@ def task_worker(self):
24562521
old_status = mux_port_dict.get("state", None)
24572522
read_side = mux_port_dict.get("read_side", None)
24582523
# Now whatever is the state requested, toggle the mux appropriately
2459-
helper_logger.log_debug("Y_CABLE_DEBUG: xcvrd trying to transition port {} from {} to {}".format(port, old_status, new_status))
2460-
active_side = update_tor_active_side(read_side, new_status, port)
2524+
helper_logger.log_debug("Y_CABLE_DEBUG: xcvrd trying to transition port {} from {} to {} read side {}".format(port, old_status, new_status, read_side))
2525+
(active_side, read_side) = update_tor_active_side(read_side, new_status, port)
24612526
if active_side == -1:
24622527
helper_logger.log_warning("ERR: Got a change event for toggle but could not toggle the mux-direction for port {} state from {} to {}, writing unknown".format(
24632528
port, old_status, new_status))
24642529
new_status = 'unknown'
24652530

24662531
helper_logger.log_debug("Y_CABLE_DEBUG: xcvrd successful to transition port {} from {} to {} and write back to the DB {}".format(port, old_status, new_status, threading.currentThread().getName()))
2467-
helper_logger.log_notice("Got a change event for toggle the mux-direction active side for port {} state requested {} from old {} to {} {}".format(port, requested_status, old_status, new_status, threading.currentThread().getName()))
2532+
helper_logger.log_notice("Got a change event for toggle the mux-direction active side for port {} state requested {} from old state {} to new state {} read_side {} thread id {}".format(port, requested_status, old_status, new_status, read_side, threading.currentThread().getName()))
24682533
time_end = datetime.datetime.utcnow().strftime("%Y-%b-%d %H:%M:%S.%f")
24692534
fvs_metrics = swsscommon.FieldValuePairs([('xcvrd_switch_{}_start'.format(new_status), str(time_start)),
24702535
('xcvrd_switch_{}_end'.format(new_status), str(time_end))])
24712536
mux_metrics_tbl[asic_index].set(port, fvs_metrics)
24722537

24732538
fvs_updated = swsscommon.FieldValuePairs([('state', new_status),
2474-
('read_side', read_side),
2539+
('read_side', str(read_side)),
24752540
('active_side', str(active_side))])
24762541
y_cable_tbl[asic_index].set(port, fvs_updated)
24772542
else:
@@ -2530,7 +2595,6 @@ def task_cli_worker(self):
25302595

25312596
sel = swsscommon.Select()
25322597

2533-
helper_logger.log_error("executing the cli for prbs thread {}".format(threading.currentThread().getName()))
25342598

25352599
# Get the namespaces in the platform
25362600
namespaces = multi_asic.get_front_end_namespaces()

0 commit comments

Comments
 (0)