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

[pbh]: Fix show PBH counters when cache is partial #16

Closed
wants to merge 4 commits into from
Closed
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
225 changes: 119 additions & 106 deletions pfc/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3

import click
from swsscommon.swsscommon import ConfigDBConnector
from tabulate import tabulate
Expand All @@ -8,153 +7,167 @@
ALL_PRIORITIES = [str(x) for x in range(8)]
PRIORITY_STATUS = ['on', 'off']

def configPfcAsym(interface, pfc_asym):
"""
PFC handler to configure asymmentric PFC.
"""
configdb = ConfigDBConnector()
configdb.connect()

configdb.mod_entry("PORT", interface, {'pfc_asym': pfc_asym})
class Pfc(object):
def __init__(self, cfgdb=None):
self.cfgdb = cfgdb

def configPfcAsym(self, interface, pfc_asym):
"""
PFC handler to configure asymmetric PFC.
"""
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

def showPfcAsym(interface):
"""
PFC handler to display asymmetric PFC information.
"""
header = ('Interface', 'Asymmetric')
configdb.mod_entry("PORT", interface, {'pfc_asym': pfc_asym})

configdb = ConfigDBConnector()
configdb.connect()
def showPfcAsym(self, interface):
"""
PFC handler to display asymmetric PFC information.
"""
header = ('Interface', 'Asymmetric')

if interface:
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|{0}'.format(interface))
else:
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|*')
configdb = ConfigDBConnector() if self.cfgdb is None else self.cfgdb
configdb.connect()

table = []

for i in db_keys or [None]:
key = None
if i:
key = i.split('|')[-1]
if interface:
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|{0}'.format(interface))
else:
db_keys = configdb.keys(configdb.CONFIG_DB, 'PORT|*')

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

sorted_table = natsorted(table)
for i in db_keys or [None]:
key = None
if i:
key = i.split('|')[-1]

click.echo()
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
click.echo()
if key and key.startswith('Ethernet'):
entry = configdb.get_entry('PORT', key)
table.append([key, entry.get('pfc_asym', 'N/A')])

def configPfcPrio(status, interface, priority):
configdb = ConfigDBConnector()
configdb.connect()
sorted_table = natsorted(table)

if interface not in configdb.get_keys('PORT_QOS_MAP'):
click.echo('Cannot find interface {0}'.format(interface))
return
click.echo()
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
click.echo()

"""Current lossless priorities on the 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()]

if status == 'on' and priority in enable_prio:
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}'.format(priority, interface))
return

if status == 'on':
enable_prio.append(priority)

else:
enable_prio.remove(priority)

enable_prio.sort()
configdb.mod_entry("PORT_QOS_MAP", interface, {'pfc_enable': ','.join(enable_prio)})

"""Show the latest PFC configuration"""
showPfcPrio(interface)

def showPfcPrio(interface):
"""
PFC handler to display PFC enabled priority information.
"""
header = ('Interface', 'Lossless priorities')
table = []
def configPfcPrio(self, status, interface, priority):
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 = 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()]

if status == 'on' and priority in enable_prio:
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}'.format(priority, interface))
return

if status == 'on':
enable_prio.append(priority)

else:
enable_prio.remove(priority)

enable_prio.sort()
configdb.mod_entry("PORT_QOS_MAP", interface, {'pfc_enable': ','.join(enable_prio)})

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

configdb = ConfigDBConnector()
configdb.connect()

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

"""The user specifies an interface but we cannot find it"""
if interface and interface not in intfs:
click.echo('Cannot find interface {0}'.format(interface))
return

if interface:
intfs = [interface]

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

sorted_table = natsorted(table)
click.echo()
click.echo(tabulate(sorted_table, headers=header, tablefmt="simple", missingval=""))
click.echo()
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 = configdb.get_keys('PORT_QOS_MAP')

"""The user specifies an interface but we cannot find it"""
if interface and interface not in intfs:
click.echo('Cannot find interface {0}'.format(interface))
return

if interface:
intfs = [interface]

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

sorted_table = natsorted(table)
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"""
pass
# 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)
def configAsym(status, interface):
@click.pass_context
def configAsym(ctx, status, interface):
"""Configure asymmetric PFC on a given port."""
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))
def configPrio(status, interface, priority):
@click.pass_context
def configPrio(ctx, status, interface, priority):
"""Configure PFC on a given priority."""
configPfcPrio(status, interface, priority)
ctx.obj['pfc'].configPfcPrio(status, interface, priority)

@click.command()
@click.argument('interface', type=click.STRING, required=False)
def showAsym(interface):
@click.pass_context
def showAsym(ctx, interface):
"""Show asymmetric PFC information"""
showPfcAsym(interface)
ctx.obj['pfc'].showPfcAsym(interface)

@click.command()
@click.argument('interface', type=click.STRING, required=False)
def showPrio(interface):
@click.pass_context
def showPrio(ctx, interface):
"""Show PFC priority information"""
showPfcPrio(interface)
ctx.obj['pfc'].showPfcPrio(interface)

config.add_command(configAsym, "asymmetric")
config.add_command(configPrio, "priority")
Expand Down
43 changes: 43 additions & 0 deletions scripts/fast-reboot
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ EXIT_NO_CONTROL_PLANE_ASSISTANT=20
EXIT_SONIC_INSTALLER_VERIFY_REBOOT=21
EXIT_PLATFORM_FW_AU_FAILURE=22
EXIT_TEAMD_RETRY_COUNT_FAILURE=23
EXIT_NO_MIRROR_SESSION_ACLS=24

function error()
{
Expand Down Expand Up @@ -283,13 +284,55 @@ function backup_database()
fi
}

function check_mirror_session_acls()
{
debug "Checking if mirror session ACLs (arp, nd) programmed to ASIC successfully"
ACL_ARP="missing"
ACL_ND="missing"
start_time=${SECONDS}
elapsed_time=$((${SECONDS} - ${start_time}))
while [[ ${elapsed_time} -lt 10 ]]; do
CHECK_ACL_ENTRIES=0
ACL_OUTPUT=$(sonic-db-cli ASIC_DB KEYS "*" | grep SAI_OBJECT_TYPE_ACL_ENTRY) || CHECK_ACL_ENTRIES=$?
if [[ ${CHECK_ACL_ENTRIES} -ne 0 ]]; then
error "Failed to retrieve SAI_OBJECT_TYPE_ACL_ENTRY from redis"
exit ${EXIT_NO_MIRROR_SESSION_ACLS}
fi
ACL_ENTRIES=( ${ACL_OUTPUT} )
if [[ ${#ACL_ENTRIES[@]} -eq 0 ]]; then
error "NO SAI_OBJECT_TYPE_ACL_ENTRY objects found"
exit ${EXIT_NO_MIRROR_SESSION_ACLS}
fi
for ACL_ENTRY in ${ACL_ENTRIES[@]}; do
ACL_PRIORITY=$(sonic-db-cli ASIC_DB HGET ${ACL_ENTRY} SAI_ACL_ENTRY_ATTR_PRIORITY)
if [[ ${ACL_PRIORITY} -eq 8888 ]]; then
ACL_ARP="found"
fi
if [[ ${ACL_PRIORITY} -eq 8887 ]]; then
ACL_ND="found"
fi
done
if [[ "${ACL_ARP}" = "found" && "${ACL_ND}" = "found" ]]; then
break
fi
sleep 0.1
elapsed_time=$((${SECONDS} - ${start_time}))
done
if [[ "${ACL_ARP}" != "found" || "${ACL_ND}" != "found" ]]; then
debug "Failed to program mirror session ACLs on ASIC. ACLs: ARP=${ACL_ARP} ND=${ACL_ND}"
exit ${EXIT_NO_MIRROR_SESSION_ACLS}
fi
debug "Mirror session ACLs (arp, nd) programmed to ASIC successfully"
}

function setup_control_plane_assistant()
{
if [[ -n "${ASSISTANT_IP_LIST}" && -x ${ASSISTANT_SCRIPT} ]]; then
# TH3 HW is not capable of VxLAN programming thus skipping TH3 platforms
if [[ "${HWSKU}" != "DellEMC-Z9332f-M-O16C64" && "${HWSKU}" != "DellEMC-Z9332f-M-O16C64-lab" ]]; then
debug "Setting up control plane assistant: ${ASSISTANT_IP_LIST} ..."
${ASSISTANT_SCRIPT} -s ${ASSISTANT_IP_LIST} -m set
check_mirror_session_acls
else
debug "${HWSKU} Not capable to support CPA. Skipping gracefully ..."
fi
Expand Down
2 changes: 1 addition & 1 deletion show/plugins/pbh.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def get_counter_value(pbh_counters, saved_pbh_counters, key, type):
if not pbh_counters[key]:
return '0'

if key in saved_pbh_counters:
if key in saved_pbh_counters and saved_pbh_counters[key]:
new_value = int(pbh_counters[key][type]) - int(saved_pbh_counters[key][type])
if new_value >= 0:
return str(new_value)
Expand Down
2 changes: 1 addition & 1 deletion ssdutil/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def import_ssd_api(diskdev):
except ImportError as e:
log.log_warning("Platform specific SsdUtil module not found. Falling down to the generic implementation")
try:
from sonic_platform_base.sonic_ssd.ssd_generic import SsdUtil
from sonic_platform_base.sonic_storage.ssd import SsdUtil
except ImportError as e:
log.log_error("Failed to import default SsdUtil. Error: {}".format(str(e)), True)
raise e
Expand Down
Loading
Loading