Skip to content

Commit 16baa1a

Browse files
stephenxsisabelmsft
authored andcommitted
Enhance the logic to wait for all buffer tables to be removed in _clear_qos (sonic-net#2720)
- What I did This is an enhancement of PR sonic-net#2503 - How I did it On top of waiting for BUFFER_POOL_TABLE to be cleared from APPL_DB, we need to wait for KEY_SET and DEL_SET as well. KEY_SET and DEL_SET are designed to accommodate the APPL_DB entries that were updated by manager daemons but have not yet been handled by the orchagent. In this case, even if the buffer tables are empty, entries in KEY_SET or DEL_SET will be in the buffer tables later on. So, we need to wait for key set tables as well. Do not delay for traditional buffer manager because it does not remove any buffer table. Provide a CLI option to print the detailed message if there is any table item which still exists - How to verify it Manually test and unit test - Previous command output (if the output of a command-line utility has changed) Running command: /usr/local/bin/sonic-cfggen -d --write-to-db -t /usr/share/sonic/device/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_dynamic.json.j2,config-db -t /usr/share/sonic/device/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json.j2,config-db -y /etc/sonic/sonic_version.yml - New command output (if the output of a command-line utility has changed) Only with option --verbose there are new output. Without the option, the output is the same as it is. admin@mtbc-sonic-01-2410:~$ sudo config qos reload --verbose Some entries matching BUFFER_*_TABLE:* still exist: BUFFER_QUEUE_TABLE:Ethernet108:0-2 Some entries matching BUFFER_*_SET still exist: BUFFER_PG_TABLE_KEY_SET Some entries matching BUFFER_*_TABLE:* still exist: BUFFER_QUEUE_TABLE:Ethernet108:0-2 Some entries matching BUFFER_*_SET still exist: BUFFER_PG_TABLE_KEY_SET Some entries matching BUFFER_*_TABLE:* still exist: BUFFER_QUEUE_TABLE:Ethernet108:0-2 Running command: /usr/local/bin/sonic-cfggen -d --write-to-db -t /usr/share/sonic/device/x86_64-mlnx_msn2410-r0/ACS-MSN2410/buffers_dynamic.json.j2,config-db -t /usr/share/sonic/device/x86_64-mlnx_msn2410-r0/ACS-MSN2410/qos.json.j2,config-db -y /etc/sonic/sonic_version.yml
1 parent 81b4fca commit 16baa1a

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

config/main.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -744,24 +744,28 @@ def storm_control_delete_entry(port_name, storm_type):
744744
return True
745745

746746

747-
def _wait_until_clear(table, interval=0.5, timeout=30):
747+
def _wait_until_clear(tables, interval=0.5, timeout=30, verbose=False):
748748
start = time.time()
749749
empty = False
750750
app_db = SonicV2Connector(host='127.0.0.1')
751751
app_db.connect(app_db.APPL_DB)
752752

753753
while not empty and time.time() - start < timeout:
754-
current_profiles = app_db.keys(app_db.APPL_DB, table)
755-
if not current_profiles:
756-
empty = True
757-
else:
758-
time.sleep(interval)
754+
non_empty_table_count = 0
755+
for table in tables:
756+
keys = app_db.keys(app_db.APPL_DB, table)
757+
if keys:
758+
non_empty_table_count += 1
759+
if verbose:
760+
click.echo("Some entries matching {} still exist: {}".format(table, keys[0]))
761+
time.sleep(interval)
762+
empty = (non_empty_table_count == 0)
759763
if not empty:
760764
click.echo("Operation not completed successfully, please save and reload configuration.")
761765
return empty
762766

763767

764-
def _clear_qos(delay = False):
768+
def _clear_qos(delay=False, verbose=False):
765769
QOS_TABLE_NAMES = [
766770
'PORT_QOS_MAP',
767771
'QUEUE',
@@ -798,7 +802,10 @@ def _clear_qos(delay = False):
798802
for qos_table in QOS_TABLE_NAMES:
799803
config_db.delete_table(qos_table)
800804
if delay:
801-
_wait_until_clear("BUFFER_POOL_TABLE:*",interval=0.5, timeout=30)
805+
device_metadata = config_db.get_entry('DEVICE_METADATA', 'localhost')
806+
# Traditional buffer manager do not remove buffer tables in any case, no need to wait.
807+
timeout = 120 if device_metadata and device_metadata.get('buffer_model') == 'dynamic' else 0
808+
_wait_until_clear(["BUFFER_*_TABLE:*", "BUFFER_*_SET"], interval=0.5, timeout=timeout, verbose=verbose)
802809

803810
def _get_sonic_generated_services(num_asic):
804811
if not os.path.isfile(SONIC_GENERATED_SERVICE_PATH):
@@ -2645,10 +2652,11 @@ def qos(ctx):
26452652
pass
26462653

26472654
@qos.command('clear')
2648-
def clear():
2655+
@click.option('--verbose', is_flag=True, help="Enable verbose output")
2656+
def clear(verbose):
26492657
"""Clear QoS configuration"""
26502658
log.log_info("'qos clear' executing...")
2651-
_clear_qos()
2659+
_clear_qos(verbose=verbose)
26522660

26532661
def _update_buffer_calculation_model(config_db, model):
26542662
"""Update the buffer calculation model into CONFIG_DB"""
@@ -2665,6 +2673,7 @@ def _update_buffer_calculation_model(config_db, model):
26652673
@click.option('--ports', is_flag=False, required=False, help="List of ports that needs to be updated")
26662674
@click.option('--no-dynamic-buffer', is_flag=True, help="Disable dynamic buffer calculation")
26672675
@click.option('--no-delay', is_flag=True, hidden=True)
2676+
@click.option('--verbose', is_flag=True, help="Enable verbose output")
26682677
@click.option(
26692678
'--json-data', type=click.STRING,
26702679
help="json string with additional data, valid with --dry-run option"
@@ -2673,7 +2682,7 @@ def _update_buffer_calculation_model(config_db, model):
26732682
'--dry_run', type=click.STRING,
26742683
help="Dry run, writes config to the given file"
26752684
)
2676-
def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports):
2685+
def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports, verbose):
26772686
"""Reload QoS configuration"""
26782687
if ports:
26792688
log.log_info("'qos reload --ports {}' executing...".format(ports))
@@ -2682,7 +2691,7 @@ def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports):
26822691

26832692
log.log_info("'qos reload' executing...")
26842693
if not dry_run:
2685-
_clear_qos(delay = not no_delay)
2694+
_clear_qos(delay = not no_delay, verbose=verbose)
26862695

26872696
_, hwsku_path = device_info.get_paths_to_platform_and_hwsku_dirs()
26882697
sonic_version_file = device_info.get_sonic_version_file()

tests/config_test.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -694,17 +694,23 @@ def test_qos_wait_until_clear_empty(self):
694694

695695
with mock.patch('swsscommon.swsscommon.SonicV2Connector.keys', side_effect=TestConfigQos._keys):
696696
TestConfigQos._keys_counter = 1
697-
empty = _wait_until_clear("BUFFER_POOL_TABLE:*", 0.5,2)
697+
empty = _wait_until_clear(["BUFFER_POOL_TABLE:*"], 0.5,2)
698698
assert empty
699699

700700
def test_qos_wait_until_clear_not_empty(self):
701701
from config.main import _wait_until_clear
702702

703703
with mock.patch('swsscommon.swsscommon.SonicV2Connector.keys', side_effect=TestConfigQos._keys):
704704
TestConfigQos._keys_counter = 10
705-
empty = _wait_until_clear("BUFFER_POOL_TABLE:*", 0.5,2)
705+
empty = _wait_until_clear(["BUFFER_POOL_TABLE:*"], 0.5,2)
706706
assert not empty
707707

708+
@mock.patch('config.main._wait_until_clear')
709+
def test_qos_clear_no_wait(self, _wait_until_clear):
710+
from config.main import _clear_qos
711+
_clear_qos(True, False)
712+
_wait_until_clear.assert_called_with(['BUFFER_*_TABLE:*', 'BUFFER_*_SET'], interval=0.5, timeout=0, verbose=False)
713+
708714
def test_qos_reload_single(
709715
self, get_cmd_module, setup_qos_mock_apis,
710716
setup_single_broadcom_asic

0 commit comments

Comments
 (0)