Skip to content

Commit f7f783b

Browse files
authored
Enhance the logic to wait for all buffer tables to be removed in _clear_qos (#2720)
- What I did This is an enhancement of PR #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 e6179af commit f7f783b

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
@@ -743,24 +743,28 @@ def storm_control_delete_entry(port_name, storm_type):
743743
return True
744744

745745

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

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

762766

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

802809
def _get_sonic_generated_services(num_asic):
803810
if not os.path.isfile(SONIC_GENERATED_SERVICE_PATH):
@@ -2644,10 +2651,11 @@ def qos(ctx):
26442651
pass
26452652

26462653
@qos.command('clear')
2647-
def clear():
2654+
@click.option('--verbose', is_flag=True, help="Enable verbose output")
2655+
def clear(verbose):
26482656
"""Clear QoS configuration"""
26492657
log.log_info("'qos clear' executing...")
2650-
_clear_qos()
2658+
_clear_qos(verbose=verbose)
26512659

26522660
def _update_buffer_calculation_model(config_db, model):
26532661
"""Update the buffer calculation model into CONFIG_DB"""
@@ -2664,6 +2672,7 @@ def _update_buffer_calculation_model(config_db, model):
26642672
@click.option('--ports', is_flag=False, required=False, help="List of ports that needs to be updated")
26652673
@click.option('--no-dynamic-buffer', is_flag=True, help="Disable dynamic buffer calculation")
26662674
@click.option('--no-delay', is_flag=True, hidden=True)
2675+
@click.option('--verbose', is_flag=True, help="Enable verbose output")
26672676
@click.option(
26682677
'--json-data', type=click.STRING,
26692678
help="json string with additional data, valid with --dry-run option"
@@ -2672,7 +2681,7 @@ def _update_buffer_calculation_model(config_db, model):
26722681
'--dry_run', type=click.STRING,
26732682
help="Dry run, writes config to the given file"
26742683
)
2675-
def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports):
2684+
def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports, verbose):
26762685
"""Reload QoS configuration"""
26772686
if ports:
26782687
log.log_info("'qos reload --ports {}' executing...".format(ports))
@@ -2681,7 +2690,7 @@ def reload(ctx, no_dynamic_buffer, no_delay, dry_run, json_data, ports):
26812690

26822691
log.log_info("'qos reload' executing...")
26832692
if not dry_run:
2684-
_clear_qos(delay = not no_delay)
2693+
_clear_qos(delay = not no_delay, verbose=verbose)
26852694

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

tests/config_test.py

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

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

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

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

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

0 commit comments

Comments
 (0)