Skip to content

Commit

Permalink
Revert "Fix multi-asic support to PFC config/show (#3521)"
Browse files Browse the repository at this point in the history
This reverts commit 785d7bd.
  • Loading branch information
wenyiz2021 authored Sep 5, 2024
1 parent 785d7bd commit 533949f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 554 deletions.
18 changes: 4 additions & 14 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6511,9 +6511,8 @@ def pfc(ctx):
@pfc.command()
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('status', type=click.Choice(['on', 'off']))
@multi_asic_util.multi_asic_click_option_namespace
@click.pass_context
def asymmetric(ctx, interface_name, status, namespace):
def asymmetric(ctx, interface_name, status):
"""Set asymmetric PFC configuration."""
# Get the config_db connector
config_db = ctx.obj['config_db']
Expand All @@ -6523,11 +6522,7 @@ def asymmetric(ctx, interface_name, status, namespace):
if interface_name is None:
ctx.fail("'interface_name' is None!")

cmd = ['pfc', 'config', 'asymmetric', str(status), str(interface_name)]
if namespace is not None:
cmd += ['-n', str(namespace)]

clicommon.run_command(cmd)
clicommon.run_command(['pfc', 'config', 'asymmetric', str(status), str(interface_name)])

#
# 'pfc priority' command ('config interface pfc priority ...')
Expand All @@ -6537,9 +6532,8 @@ def asymmetric(ctx, interface_name, status, namespace):
@click.argument('interface_name', metavar='<interface_name>', required=True)
@click.argument('priority', type=click.Choice([str(x) for x in range(8)]))
@click.argument('status', type=click.Choice(['on', 'off']))
@multi_asic_util.multi_asic_click_option_namespace
@click.pass_context
def priority(ctx, interface_name, priority, status, namespace):
def priority(ctx, interface_name, priority, status):
"""Set PFC priority configuration."""
# Get the config_db connector
config_db = ctx.obj['config_db']
Expand All @@ -6549,11 +6543,7 @@ def priority(ctx, interface_name, priority, status, namespace):
if interface_name is None:
ctx.fail("'interface_name' is None!")

cmd = ['pfc', 'config', 'priority', str(status), str(interface_name), str(priority)]
if namespace is not None:
cmd += ['-n', str(namespace)]

clicommon.run_command(cmd)
clicommon.run_command(['pfc', 'config', 'priority', str(status), str(interface_name), str(priority)])

#
# 'buffer' group ('config buffer ...')
Expand Down
132 changes: 54 additions & 78 deletions pfc/main.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,39 @@
#!/usr/bin/env python3
import os
import click
import json
from sonic_py_common import multi_asic
from swsscommon.swsscommon import ConfigDBConnector
from tabulate import tabulate
from natsort import natsorted
from utilities_common import multi_asic as multi_asic_util

# Constants
ALL_PRIORITIES = [str(x) for x in range(8)]
PRIORITY_STATUS = ['on', 'off']
PORT_TABLE_NAME = "PORT"
PORT_QOS_MAP_TABLE_NAME = "PORT_QOS_MAP"


class Pfc(object):
def __init__(self, namespace=None):
self.multi_asic = multi_asic_util.MultiAsic(namespace_option=namespace)
self.config_db = None
def __init__(self, cfgdb=None):
self.cfgdb = cfgdb

# For unit testing
self.updated_port_tables = {}
self.test_filename = '/tmp/pfc_testdata.json'

def dump_config_to_json(self, table_name, namespace):
"""
This function dumps the current config in a JSON file for unit testing.
"""
# Only dump files in unit testing mode
if os.environ["UTILITIES_UNIT_TESTING"] != "2":
return

if namespace not in self.updated_port_tables.keys():
self.updated_port_tables[namespace] = {}

self.updated_port_tables[namespace][table_name] = self.config_db.get_table(table_name)
with open(self.test_filename, "w") as fd:
json.dump(self.updated_port_tables, fd)

@multi_asic_util.run_on_multi_asic
def configPfcAsym(self, interface, pfc_asym):
"""
PFC handler to configure asymmetric PFC.
"""
self.config_db.mod_entry(PORT_TABLE_NAME, interface, {'pfc_asym': pfc_asym})
self.dump_config_to_json(PORT_TABLE_NAME, self.multi_asic.current_namespace)
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

configdb.mod_entry("PORT", interface, {'pfc_asym': pfc_asym})

@multi_asic_util.run_on_multi_asic
def showPfcAsym(self, interface):
"""
PFC handler to display asymmetric PFC information.
"""
namespace_str = f"Namespace {self.multi_asic.current_namespace}" if multi_asic.is_multi_asic() else ''
header = ('Interface', 'Asymmetric')

configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

if interface:
db_keys = self.config_db.keys(self.config_db.CONFIG_DB, 'PORT|{0}'.format(interface))
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|{0}'.format(interface))
else:
db_keys = self.config_db.keys(self.config_db.CONFIG_DB, 'PORT|*')
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|*')

table = []

Expand All @@ -67,35 +43,36 @@ def showPfcAsym(self, interface):
key = i.split('|')[-1]

if key and key.startswith('Ethernet'):
entry = self.config_db.get_entry(PORT_TABLE_NAME, key)
entry = configdb.get_entry('PORT', key)
table.append([key, entry.get('pfc_asym', 'N/A')])

sorted_table = natsorted(table)

click.echo(namespace_str)
click.echo()
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
click.echo()

@multi_asic_util.run_on_multi_asic
def configPfcPrio(self, status, interface, priority):
if interface not in self.config_db.get_keys(PORT_QOS_MAP_TABLE_NAME):
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

if interface not in configdb.get_keys('PORT_QOS_MAP'):
click.echo('Cannot find interface {0}'.format(interface))
return

"""Current lossless priorities on the interface"""
entry = self.config_db.get_entry('PORT_QOS_MAP', interface)
entry = configdb.get_entry('PORT_QOS_MAP', interface)
enable_prio = entry.get('pfc_enable').split(',')

"""Avoid '' in enable_prio"""
enable_prio = [x.strip() for x in enable_prio if x.strip()]

namespace_str = f" for namespace {self.multi_asic.current_namespace}" if multi_asic.is_multi_asic() else ''
if status == 'on' and priority in enable_prio:
click.echo('Priority {0} has already been enabled on {1}{2}'.format(priority, interface, namespace_str))
click.echo('Priority {0} has already been enabled on {1}'.format(priority, interface))
return

if status == 'off' and priority not in enable_prio:
click.echo('Priority {0} is not enabled on {1}{2}'.format(priority, interface, namespace_str))
click.echo('Priority {0} is not enabled on {1}'.format(priority, interface))
return

if status == 'on':
Expand All @@ -105,93 +82,92 @@ def configPfcPrio(self, status, interface, priority):
enable_prio.remove(priority)

enable_prio.sort()
self.config_db.mod_entry(PORT_QOS_MAP_TABLE_NAME, interface, {'pfc_enable': ','.join(enable_prio)})
self.dump_config_to_json(PORT_QOS_MAP_TABLE_NAME, self.multi_asic.current_namespace)
configdb.mod_entry("PORT_QOS_MAP", interface, {'pfc_enable': ','.join(enable_prio)})

@multi_asic_util.run_on_multi_asic
"""Show the latest PFC configuration"""
self.showPfcPrio(interface)

def showPfcPrio(self, interface):
"""
PFC handler to display PFC enabled priority information.
"""
header = ('Interface', 'Lossless priorities')
table = []

configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

"""Get all the interfaces with QoS map information"""
intfs = self.config_db.get_keys('PORT_QOS_MAP')
intfs = configdb.get_keys('PORT_QOS_MAP')

"""The user specifies an interface but we cannot find it"""
namespace_str = f"Namespace {self.multi_asic.current_namespace}" if multi_asic.is_multi_asic() else ''
if interface and interface not in intfs:
if multi_asic.is_multi_asic():
click.echo('Cannot find interface {0} for {1}'.format(interface, namespace_str))
else:
click.echo('Cannot find interface {0}'.format(interface))
click.echo('Cannot find interface {0}'.format(interface))
return

if interface:
intfs = [interface]

for intf in intfs:
entry = self.config_db.get_entry('PORT_QOS_MAP', intf)
entry = configdb.get_entry('PORT_QOS_MAP', intf)
table.append([intf, entry.get('pfc_enable', 'N/A')])

sorted_table = natsorted(table)
click.echo(namespace_str)
click.echo()
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
click.echo()



@click.group()
def cli():
@click.pass_context
def cli(ctx):
"""PFC Command Line"""
# Use the cfgdb object if given as input.
cfgdb = None if ctx.obj is None else ctx.obj.cfgdb

ctx.obj = {'pfc': Pfc(cfgdb)}

@cli.group()
def config():
@click.pass_context
def config(ctx):
"""Config PFC"""
pass


@cli.group()
def show():
@click.pass_context
def show(ctx):
"""Show PFC information"""
pass


@click.command()
@click.argument('status', type=click.Choice(PRIORITY_STATUS))
@click.argument('interface', type=click.STRING)
@multi_asic_util.multi_asic_click_option_namespace
def configAsym(status, interface, namespace):
@click.pass_context
def configAsym(ctx, status, interface):
"""Configure asymmetric PFC on a given port."""
Pfc(namespace).configPfcAsym(interface, status)

ctx.obj['pfc'].configPfcAsym(interface, status)

@click.command()
@click.argument('status', type=click.Choice(PRIORITY_STATUS))
@click.argument('interface', type=click.STRING)
@click.argument('priority', type=click.Choice(ALL_PRIORITIES))
@multi_asic_util.multi_asic_click_option_namespace
def configPrio(status, interface, priority, namespace):
@click.pass_context
def configPrio(ctx, status, interface, priority):
"""Configure PFC on a given priority."""
Pfc(namespace).configPfcPrio(status, interface, priority)

ctx.obj['pfc'].configPfcPrio(status, interface, priority)

@click.command()
@click.argument('interface', type=click.STRING, required=False)
@multi_asic_util.multi_asic_click_option_namespace
def showAsym(interface, namespace):
@click.pass_context
def showAsym(ctx, interface):
"""Show asymmetric PFC information"""
Pfc(namespace).showPfcAsym(interface)

ctx.obj['pfc'].showPfcAsym(interface)

@click.command()
@click.argument('interface', type=click.STRING, required=False)
@multi_asic_util.multi_asic_click_option_namespace
def showPrio(interface, namespace):
@click.pass_context
def showPrio(ctx, interface):
"""Show PFC priority information"""
Pfc(namespace).showPfcPrio(interface)

ctx.obj['pfc'].showPfcPrio(interface)

config.add_command(configAsym, "asymmetric")
config.add_command(configPrio, "priority")
Expand Down
10 changes: 2 additions & 8 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,33 +647,27 @@ def counters(namespace, display, verbose):

@pfc.command()
@click.argument('interface', type=click.STRING, required=False)
@multi_asic_util.multi_asic_click_option_namespace
def priority(interface, namespace):
def priority(interface):
"""Show pfc priority"""
cmd = ['pfc', 'show', 'priority']
if interface is not None and clicommon.get_interface_naming_mode() == "alias":
interface = iface_alias_converter.alias_to_name(interface)

if interface is not None:
cmd += [str(interface)]
if namespace is not None:
cmd += ['-n', str(namespace)]

run_command(cmd)

@pfc.command()
@click.argument('interface', type=click.STRING, required=False)
@multi_asic_util.multi_asic_click_option_namespace
def asymmetric(interface, namespace):
def asymmetric(interface):
"""Show asymmetric pfc"""
cmd = ['pfc', 'show', 'asymmetric']
if interface is not None and clicommon.get_interface_naming_mode() == "alias":
interface = iface_alias_converter.alias_to_name(interface)

if interface is not None:
cmd += [str(interface)]
if namespace is not None:
cmd += ['-n', str(namespace)]

run_command(cmd)

Expand Down
Loading

0 comments on commit 533949f

Please sign in to comment.