Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multi-asic behaviour for pg-drop #3058

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 60 additions & 27 deletions scripts/pg-drop
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# pg-drop is a tool for show/clear ingress pg dropped packet stats.
#
#####################################################################
from importlib import reload
import json
import argparse
import os
Expand All @@ -13,6 +14,8 @@ from collections import OrderedDict

from natsort import natsorted
from tabulate import tabulate
from utilities_common.general import load_db_config
from sonic_py_common import multi_asic

# mock the redis for unit test purposes #
try:
Expand All @@ -22,7 +25,9 @@ try:
sys.path.insert(0, modules_path)
sys.path.insert(0, tests_path)
import mock_tables.dbconnector

if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic":
import mock_tables.mock_multi_asic
mock_tables.dbconnector.load_namespace_config()
except KeyError:
pass

Expand All @@ -43,28 +48,26 @@ def get_dropstat_dir():

class PgDropStat(object):

def __init__(self):
self.counters_db = SonicV2Connector(host='127.0.0.1')
self.counters_db.connect(self.counters_db.COUNTERS_DB)

self.configdb = ConfigDBConnector()
def __init__(self, namespace):
self.namespace = namespace
self.ns_list = multi_asic.get_namespace_list(namespace)
self.configdb = ConfigDBConnector(namespace=namespace)
self.configdb.connect()

dropstat_dir = get_dropstat_dir()
self.port_drop_stats_file = os.path.join(dropstat_dir, 'pg_drop_stats')

def get_port_id(oid):
"""
Get port ID using object ID
"""
port_id = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_PG_PORT_MAP, oid)
port_id = self.get_counters_mapdata(COUNTERS_PG_PORT_MAP, oid)
if not port_id:
print("Port is not available for oid '{}'".format(oid))
sys.exit(1)
return port_id

# Get all ports
self.counter_port_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP)
self.counter_port_name_map = self.get_counters_mapall(COUNTERS_PORT_NAME_MAP)
if not self.counter_port_name_map:
print("COUNTERS_PORT_NAME_MAP is empty!")
sys.exit(1)
Expand All @@ -77,7 +80,7 @@ class PgDropStat(object):
self.port_name_map[self.counter_port_name_map[port]] = port

# Get PGs for each port
counter_pg_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, COUNTERS_PG_NAME_MAP)
counter_pg_name_map = self.get_counters_mapall(COUNTERS_PG_NAME_MAP)
if not counter_pg_name_map:
print("COUNTERS_PG_NAME_MAP is empty!")
sys.exit(1)
Expand All @@ -94,13 +97,32 @@ class PgDropStat(object):
"header_prefix": "PG"},
}

def get_counters_mapdata(self, tablemap, index):
for ns in self.ns_list:
counters_db = SonicV2Connector(namespace=ns)
counters_db.connect(counters_db.COUNTERS_DB)
data = counters_db.get(counters_db.COUNTERS_DB, tablemap, index)
if data:
return data
return None

def get_counters_mapall(self, tablemap):
mapdata = {}
for ns in self.ns_list:
counters_db = SonicV2Connector(namespace=ns)
counters_db.connect(counters_db.COUNTERS_DB)
map_result = counters_db.get_all(counters_db.COUNTERS_DB, tablemap)
if map_result:
mapdata.update(map_result)
return mapdata

def get_pg_index(self, oid):
"""
return PG index (0-7)

oid - object ID for entry in redis
"""
pg_index = self.counters_db.get(self.counters_db.COUNTERS_DB, COUNTERS_PG_INDEX_MAP, oid)
pg_index = self.get_counters_mapdata(COUNTERS_PG_INDEX_MAP, oid)
if not pg_index:
print("Priority group index is not available for oid '{}'".format(oid))
sys.exit(1)
Expand Down Expand Up @@ -154,7 +176,7 @@ class PgDropStat(object):
old_collected_data = port_drop_ckpt.get(name,{})[full_table_id] if len(port_drop_ckpt) > 0 else 0
idx = int(idx_func(obj_id))
pos = self.header_idx_to_pos[idx]
counter_data = self.counters_db.get(self.counters_db.COUNTERS_DB, full_table_id, counter_name)
counter_data = self.get_counters_mapdata(full_table_id, counter_name)
if counter_data is None:
fields[pos] = STATUS_NA
elif fields[pos] != STATUS_NA:
Expand All @@ -180,29 +202,29 @@ class PgDropStat(object):
print(tabulate(table, self.header_list, tablefmt='simple', stralign='right'))

def get_counts(self, counters, oid):
"""
Get the PG drop counts for an individual counter.
"""
counts = {}
table_id = COUNTER_TABLE_PREFIX + oid
for counter in counters:
counter_data = self.counters_db.get(self.counters_db.COUNTERS_DB, table_id, counter)
if counter_data is None:
counts[table_id] = 0
else:
counts[table_id] = int(counter_data)
return counts
"""
Get the PG drop counts for an individual counter.
"""
counts = {}
table_id = COUNTER_TABLE_PREFIX + oid
for counter in counters:
counter_data = self.get_counters_mapdata(table_id, counter)
if counter_data is None:
counts[table_id] = 0
else:
counts[table_id] = int(counter_data)
return counts

def get_counts_table(self, counters, object_table):
"""
Returns a dictionary containing a mapping from an object (like a port)
to its PG drop counts. Counts are contained in a dictionary that maps
counter oid to its counts.
"""
counter_object_name_map = self.counters_db.get_all(self.counters_db.COUNTERS_DB, object_table)
counter_object_name_map = self.get_counters_mapall(object_table)
current_stat_dict = OrderedDict()

if counter_object_name_map is None:
if not counter_object_name_map:
return current_stat_dict

for obj in natsorted(counter_object_name_map):
Expand Down Expand Up @@ -239,10 +261,12 @@ def main():
epilog="""
Examples:
pg-drop -c show
pg-drop -c show --namespace asic0
pg-drop -c clear
""")

parser.add_argument('-c', '--command', type=str, help='Desired action to perform')
parser.add_argument('-n', '--namespace', type=str, help='Namespace name or skip for all', default=None)

args = parser.parse_args()
command = args.command
Expand All @@ -256,7 +280,16 @@ pg-drop -c clear
print(e)
sys.exit(e.errno)

pgdropstat = PgDropStat()
# Load database config files
load_db_config()
namespaces = multi_asic.get_namespace_list()
if args.namespace and args.namespace not in namespaces:
namespacelist = ', '.join(namespaces)
print(f"Input value for '--namespace' / '-n'. Choose from one of ({namespacelist})")
sys.exit(1)

# For 'clear' command force applying to all namespaces
pgdropstat = PgDropStat(args.namespace if command != 'clear' else None)

if command == 'clear':
pgdropstat.clear_drop_counts()
Expand Down
5 changes: 4 additions & 1 deletion show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,9 +857,12 @@ def drop():
pass

@drop.command('counters')
def pg_drop_counters():
@multi_asic_util.multi_asic_click_option_namespace
def pg_drop_counters(namespace):
"""Show dropped packets for priority-group"""
command = ['pg-drop', '-c', 'show']
if namespace is not None:
command += ['-n', str(namespace)]
run_command(command)

@priority_group.group(name='persistent-watermark')
Expand Down
102 changes: 102 additions & 0 deletions tests/mock_tables/asic1/counters_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,108 @@
"Ethernet-BP256": "oid:0x1000000000b06",
"Ethernet-BP260": "oid:0x1000000000b08"
},
"COUNTERS_PG_NAME_MAP": {
"Ethernet-BP256:0": "oid:100000000b0f0",
"Ethernet-BP256:1": "oid:100000000b0f1",
"Ethernet-BP256:2": "oid:100000000b0f2",
"Ethernet-BP256:3": "oid:100000000b0f3",
"Ethernet-BP256:4": "oid:100000000b0f4",
"Ethernet-BP256:5": "oid:100000000b0f5",
"Ethernet-BP256:6": "oid:100000000b0f6",
"Ethernet-BP256:7": "oid:100000000b0f7",
"Ethernet-BP256:8": "oid:100000000b0f8",
"Ethernet-BP256:9": "oid:100000000b0f9",
"Ethernet-BP256:10": "oid:100000000b0fa",
"Ethernet-BP256:11": "oid:100000000b0fb",
"Ethernet-BP256:12": "oid:100000000b0fc",
"Ethernet-BP256:13": "oid:100000000b0fd",
"Ethernet-BP256:14": "oid:100000000b0fe",
"Ethernet-BP256:15": "oid:100000000b0ff",
"Ethernet-BP260:0": "oid:0x100000000b1f0",
"Ethernet-BP260:1": "oid:0x100000000b1f1",
"Ethernet-BP260:2": "oid:0x100000000b1f2",
"Ethernet-BP260:3": "oid:0x100000000b1f3",
"Ethernet-BP260:4": "oid:0x100000000b1f4",
"Ethernet-BP260:5": "oid:0x100000000b1f5",
"Ethernet-BP260:6": "oid:0x100000000b1f6",
"Ethernet-BP260:7": "oid:0x100000000b1f7",
"Ethernet-BP260:8": "oid:0x100000000b1f8",
"Ethernet-BP260:9": "oid:0x100000000b1f9",
"Ethernet-BP260:10": "oid:0x100000000b1fa",
"Ethernet-BP260:11": "oid:0x100000000b1fb",
"Ethernet-BP260:12": "oid:0x100000000b1fc",
"Ethernet-BP260:13": "oid:0x100000000b1fd",
"Ethernet-BP260:14": "oid:0x100000000b1fe",
"Ethernet-BP260:15": "oid:0x100000000b1ff"
},
"COUNTERS_PG_PORT_MAP": {
"oid:100000000b0f0": "oid:0x1000000000b06",
"oid:100000000b0f1": "oid:0x1000000000b06",
"oid:100000000b0f2": "oid:0x1000000000b06",
"oid:100000000b0f3": "oid:0x1000000000b06",
"oid:100000000b0f4": "oid:0x1000000000b06",
"oid:100000000b0f5": "oid:0x1000000000b06",
"oid:100000000b0f6": "oid:0x1000000000b06",
"oid:100000000b0f7": "oid:0x1000000000b06",
"oid:100000000b0f8": "oid:0x1000000000b06",
"oid:100000000b0f9": "oid:0x1000000000b06",
"oid:100000000b0fa": "oid:0x1000000000b06",
"oid:100000000b0fb": "oid:0x1000000000b06",
"oid:100000000b0fc": "oid:0x1000000000b06",
"oid:100000000b0fd": "oid:0x1000000000b06",
"oid:100000000b0fe": "oid:0x1000000000b06",
"oid:100000000b0ff": "oid:0x1000000000b06",
"oid:0x100000000b1f0": "oid:0x1000000000b08",
"oid:0x100000000b1f1": "oid:0x1000000000b08",
"oid:0x100000000b1f2": "oid:0x1000000000b08",
"oid:0x100000000b1f3": "oid:0x1000000000b08",
"oid:0x100000000b1f4": "oid:0x1000000000b08",
"oid:0x100000000b1f5": "oid:0x1000000000b08",
"oid:0x100000000b1f6": "oid:0x1000000000b08",
"oid:0x100000000b1f7": "oid:0x1000000000b08",
"oid:0x100000000b1f8": "oid:0x1000000000b08",
"oid:0x100000000b1f9": "oid:0x1000000000b08",
"oid:0x100000000b1fa": "oid:0x1000000000b08",
"oid:0x100000000b1fb": "oid:0x1000000000b08",
"oid:0x100000000b1fc": "oid:0x1000000000b08",
"oid:0x100000000b1fd": "oid:0x1000000000b08",
"oid:0x100000000b1fe": "oid:0x1000000000b08",
"oid:0x100000000b1ff" : "oid:0x1000000000b08"
},
"COUNTERS_PG_INDEX_MAP": {
"oid:100000000b0f0": "0",
"oid:100000000b0f1": "1",
"oid:100000000b0f2": "2",
"oid:100000000b0f3": "3",
"oid:100000000b0f4": "4",
"oid:100000000b0f5": "5",
"oid:100000000b0f6": "6",
"oid:100000000b0f7": "7",
"oid:100000000b0f8": "8",
"oid:100000000b0f9": "9",
"oid:100000000b0fa": "10",
"oid:100000000b0fb": "11",
"oid:100000000b0fc": "12",
"oid:100000000b0fd": "13",
"oid:100000000b0fe": "14",
"oid:100000000b0ff": "15",
"oid:0x100000000b1f0": "0",
"oid:0x100000000b1f1": "1",
"oid:0x100000000b1f2": "2",
"oid:0x100000000b1f3": "3",
"oid:0x100000000b1f4": "4",
"oid:0x100000000b1f5": "5",
"oid:0x100000000b1f6": "6",
"oid:0x100000000b1f7": "7",
"oid:0x100000000b1f8": "8",
"oid:0x100000000b1f9": "9",
"oid:0x100000000b1fa": "10",
"oid:0x100000000b1fb": "11",
"oid:0x100000000b1fc": "12",
"oid:0x100000000b1fd": "13",
"oid:0x100000000b1fe": "14",
"oid:0x100000000b1ff" : "15"
},
"COUNTERS_LAG_NAME_MAP": {
"PortChannel0001": "oid:0x60000000005a1",
"PortChannel0002": "oid:0x60000000005a2",
Expand Down
Loading
Loading