Skip to content

Commit

Permalink
Merge branch 'master' into add_to_status_tbl
Browse files Browse the repository at this point in the history
  • Loading branch information
longhuan-cisco authored Dec 6, 2022
2 parents d1f4289 + adcd69b commit 4e30850
Show file tree
Hide file tree
Showing 13 changed files with 603 additions and 190 deletions.
4 changes: 4 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: "CodeQL config"
queries:
- uses: security-and-quality
- uses: security-extended
43 changes: 43 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# For more infomation, please visit: https://github.com/github/codeql-action

name: "CodeQL"

on:
push:
branches:
- 'master'
- '202[0-9][0-9][0-9]'
pull_request_target:
branches:
- 'master'
- '202[0-9][0-9][0-9]'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'python' ]

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
config-file: ./.github/codeql/codeql-config.yml
languages: ${{ matrix.language }}

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
59 changes: 36 additions & 23 deletions sonic-chassisd/scripts/chassisd
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ CHASSIS_MODULE_INFO_NUM_ASICS_FIELD = 'num_asics'
CHASSIS_MODULE_INFO_ASICS = 'asics'

CHASSIS_ASIC_INFO_TABLE = 'CHASSIS_ASIC_TABLE'
CHASSIS_FABRIC_ASIC_INFO_TABLE = 'CHASSIS_FABRIC_ASIC_TABLE'
CHASSIS_ASIC = 'asic'
CHASSIS_ASIC_PCI_ADDRESS_FIELD = 'asic_pci_address'
CHASSIS_ASIC_ID_IN_MODULE_FIELD = 'asic_id_in_module'
Expand Down Expand Up @@ -158,14 +159,16 @@ class ModuleConfigUpdater(logger.Logger):

class ModuleUpdater(logger.Logger):

def __init__(self, log_identifier, chassis):
def __init__(self, log_identifier, chassis, my_slot, supervisor_slot):
"""
Constructor for ModuleUpdater
:param chassis: Object representing a platform chassis
"""
super(ModuleUpdater, self).__init__(log_identifier)

self.chassis = chassis
self.my_slot = my_slot
self.supervisor_slot = supervisor_slot
self.num_modules = chassis.get_num_modules()
# Connect to STATE_DB and create chassis info tables
state_db = daemon_base.db_connect("STATE_DB")
Expand All @@ -177,9 +180,14 @@ class ModuleUpdater(logger.Logger):
CHASSIS_MODULE_INFO_SLOT_FIELD,
CHASSIS_MODULE_INFO_OPERSTATUS_FIELD]

chassis_state_db = daemon_base.db_connect("CHASSIS_STATE_DB")
self.asic_table = swsscommon.Table(chassis_state_db, CHASSIS_ASIC_INFO_TABLE)

self.chassis_state_db = daemon_base.db_connect("CHASSIS_STATE_DB")
if self._is_supervisor():
self.asic_table = swsscommon.Table(self.chassis_state_db,
CHASSIS_FABRIC_ASIC_INFO_TABLE)
else:
self.asic_table = swsscommon.Table(self.chassis_state_db,
CHASSIS_ASIC_INFO_TABLE)
#
self.midplane_initialized = try_get(chassis.init_midplane_switch, default=False)
if not self.midplane_initialized:
self.log_error("Chassisd midplane intialization failed")
Expand Down Expand Up @@ -240,25 +248,28 @@ class ModuleUpdater(logger.Logger):
self.module_table.set(key, fvs)

if module_info_dict[CHASSIS_MODULE_INFO_OPERSTATUS_FIELD] != str(ModuleBase.MODULE_STATUS_ONLINE):
notOnlineModules.append(key)
continue
notOnlineModules.append(key)
continue

for asic_id, asic in enumerate(module_info_dict[CHASSIS_MODULE_INFO_ASICS]):
asic_global_id, asic_pci_addr = asic
asic_key = "%s%s" % (CHASSIS_ASIC, asic_global_id)
asic_fvs = swsscommon.FieldValuePairs([(CHASSIS_ASIC_PCI_ADDRESS_FIELD, asic_pci_addr),
(CHASSIS_MODULE_INFO_NAME_FIELD, key),
(CHASSIS_ASIC_ID_IN_MODULE_FIELD, str(asic_id))])
self.asic_table.set(asic_key, asic_fvs)
asic_global_id, asic_pci_addr = asic
asic_key = "%s%s" % (CHASSIS_ASIC, asic_global_id)
if not self._is_supervisor():
asic_key = "%s|%s" % (key, asic_key)

asic_fvs = swsscommon.FieldValuePairs([(CHASSIS_ASIC_PCI_ADDRESS_FIELD, asic_pci_addr),
(CHASSIS_MODULE_INFO_NAME_FIELD, key),
(CHASSIS_ASIC_ID_IN_MODULE_FIELD, str(asic_id))])
self.asic_table.set(asic_key, asic_fvs)

# Asics that are on the "not online" modules need to be cleaned up
asics = list(self.asic_table.getKeys())
for asic in asics:
fvs = self.asic_table.get(asic)
if isinstance(fvs, list):
fvs = dict(fvs[-1])
if fvs[CHASSIS_MODULE_INFO_NAME_FIELD] in notOnlineModules:
self.asic_table._del(asic)
fvs = self.asic_table.get(asic)
if isinstance(fvs, list):
fvs = dict(fvs[-1])
if fvs[CHASSIS_MODULE_INFO_NAME_FIELD] in notOnlineModules:
self.asic_table._del(asic)

def _get_module_info(self, module_index):
"""
Expand Down Expand Up @@ -403,15 +414,17 @@ class ChassisdDaemon(daemon_base.DaemonBase):
self.log_error("Failed to load chassis due to {}".format(repr(e)))
sys.exit(CHASSIS_LOAD_ERROR)

# Check if module list is populated
self.module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, platform_chassis)
self.module_updater.modules_num_update()

# Check for valid slot numbers
self.module_updater.my_slot = try_get(platform_chassis.get_my_slot,
my_slot = try_get(platform_chassis.get_my_slot,
default=INVALID_SLOT)
self.module_updater.supervisor_slot = try_get(platform_chassis.get_supervisor_slot,
supervisor_slot = try_get(platform_chassis.get_supervisor_slot,
default=INVALID_SLOT)

# Check if module list is populated
self.module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, platform_chassis, my_slot, supervisor_slot)
self.module_updater.modules_num_update()


if ((self.module_updater.my_slot == INVALID_SLOT) or
(self.module_updater.supervisor_slot == INVALID_SLOT)):
self.log_error("Chassisd not supported for this platform")
Expand Down
27 changes: 17 additions & 10 deletions sonic-chassisd/tests/test_chassisd.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ def test_moduleupdater_check_valid_fields():

chassis.module_list.append(module)

module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.module_db_update()
fvs = module_updater.module_table.get(name)
assert desc == fvs[CHASSIS_MODULE_INFO_DESC_FIELD]
Expand All @@ -82,7 +83,8 @@ def test_moduleupdater_check_invalid_name():

chassis.module_list.append(module)

module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.module_db_update()
fvs = module_updater.module_table.get(name)
assert fvs == None
Expand All @@ -102,7 +104,8 @@ def test_moduleupdater_check_status_update():
module.set_oper_status(status)
chassis.module_list.append(module)

module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.module_db_update()
fvs = module_updater.module_table.get(name)
print('Initial DB-entry {}'.format(fvs))
Expand Down Expand Up @@ -136,7 +139,8 @@ def test_moduleupdater_check_deinit():
module.set_oper_status(status)
chassis.module_list.append(module)

module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.modules_num_update()
module_updater.module_db_update()
fvs = module_updater.module_table.get(name)
Expand Down Expand Up @@ -226,7 +230,8 @@ def test_configupdater_check_num_modules():
module = MockModule(index, name, desc, module_type, slot)

# No modules
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.modules_num_update()
fvs = module_updater.chassis_table.get(CHASSIS_INFO_KEY_TEMPLATE.format(1))
assert fvs == None
Expand Down Expand Up @@ -274,7 +279,8 @@ def test_midplane_presence_modules():
chassis.module_list.append(fabric)

#Run on supervisor
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.supervisor_slot = supervisor.get_slot()
module_updater.my_slot = supervisor.get_slot()
module_updater.modules_num_update()
Expand Down Expand Up @@ -338,7 +344,8 @@ def test_midplane_presence_supervisor():
chassis.module_list.append(fabric)

#Run on supervisor
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis, slot,
module.supervisor_slot)
module_updater.supervisor_slot = supervisor.get_slot()
module_updater.my_slot = module.get_slot()
module_updater.modules_num_update()
Expand Down Expand Up @@ -403,9 +410,9 @@ def test_asic_presence():
chassis.module_list.append(fabric)

#Run on supervisor
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis)
module_updater.supervisor_slot = supervisor.get_slot()
module_updater.my_slot = supervisor.get_slot()
module_updater = ModuleUpdater(SYSLOG_IDENTIFIER, chassis,
module.supervisor_slot,
module.supervisor_slot)
module_updater.modules_num_update()
module_updater.module_db_update()
module_updater.check_midplane_reachability()
Expand Down
52 changes: 51 additions & 1 deletion sonic-psud/scripts/psud
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ PSU_INFO_VOLTAGE_MAX_TH_FIELD = 'voltage_max_threshold'
PSU_INFO_VOLTAGE_MIN_TH_FIELD = 'voltage_min_threshold'
PSU_INFO_CURRENT_FIELD = 'current'
PSU_INFO_POWER_FIELD = 'power'
PSU_INFO_POWER_OVERLOAD = 'power_overload'
PSU_INFO_POWER_WARNING_SUPPRESS_THRESHOLD = 'power_warning_suppress_threshold'
PSU_INFO_POWER_CRITICAL_THRESHOLD = 'power_critical_threshold'
PSU_INFO_FRU_FIELD = 'is_replaceable'
PSU_INFO_IN_VOLTAGE_FIELD = 'input_voltage'
PSU_INFO_IN_CURRENT_FIELD = 'input_current'
Expand Down Expand Up @@ -283,6 +286,8 @@ class PsuStatus(object):
self.power_good = True
self.voltage_good = True
self.temperature_good = True
self.check_psu_power_threshold = False
self.power_exceeded_threshold = False
self.logger = logger

def set_presence(self, presence):
Expand Down Expand Up @@ -339,6 +344,13 @@ class PsuStatus(object):
self.temperature_good = temperature_good
return True

def set_power_exceed_threshold(self, power_exceeded_threshold):
if power_exceeded_threshold == self.power_exceeded_threshold:
return False

self.power_exceeded_threshold = power_exceeded_threshold
return True

def is_ok(self):
return self.presence and self.power_good and self.voltage_good and self.temperature_good

Expand Down Expand Up @@ -486,6 +498,8 @@ class DaemonPsud(daemon_base.DaemonBase):
'PSU absence warning cleared: {} is inserted back.'.format(name),
'PSU absence warning: {} is not present.'.format(name)
)
if not psu_status.presence:
psu_status.check_psu_power_threshold = False

if presence_changed or self.first_run:
# Have to update PSU fan data here because PSU presence status changed. If we don't
Expand All @@ -495,13 +509,46 @@ class DaemonPsud(daemon_base.DaemonBase):
# every 60 seconds, it may still treat PSU state to "OK" and PSU LED to "red".
self._update_psu_fan_data(psu, index)

if presence and psu_status.set_power_good(power_good):
power_good_changed = psu_status.set_power_good(power_good)
if presence and power_good_changed:
set_led = True
log_on_status_changed(self, psu_status.power_good,
'Power absence warning cleared: {} power is back to normal.'.format(name),
'Power absence warning: {} is out of power.'.format(name)
)

if presence and power_good_changed or self.first_run:
psu_status.check_psu_power_threshold = False
if psu_status.power_good:
# power_good has been updated and it is True, which means it was False
# Initialize power exceeding threshold state in this case
if (try_get(psu.get_psu_power_critical_threshold) and try_get(psu.get_psu_power_warning_suppress_threshold) and power != NOT_AVAILABLE):
psu_status.check_psu_power_threshold = True

power_exceeded_threshold = psu_status.power_exceeded_threshold
power_warning_suppress_threshold = try_get(psu.get_psu_power_warning_suppress_threshold, NOT_AVAILABLE)
power_critical_threshold = try_get(psu.get_psu_power_critical_threshold, NOT_AVAILABLE)
if psu_status.check_psu_power_threshold:
if power_warning_suppress_threshold == NOT_AVAILABLE or power_critical_threshold == NOT_AVAILABLE:
self.log_error("PSU power thresholds become invalid: threshold {} critical threshold {}".format(power_warning_suppress_threshold, power_critical_threshold))
psu_status.check_psu_power_threshold = False
psu_status.power_exceeded_threshold = False
elif psu_status.power_exceeded_threshold:
# The failing threshold is the warning threshold
if power < power_warning_suppress_threshold:
# Clear alarm
power_exceeded_threshold = False
else:
# The rising threshold is the critical threshold
if power >= power_critical_threshold:
# Raise alarm
power_exceeded_threshold = True

if psu_status.set_power_exceed_threshold(power_exceeded_threshold):
log_on_status_changed(self, not psu_status.power_exceeded_threshold,
'PSU power warning cleared: {} power {} is back to normal.'.format(name, power),
'PSU power warning: {} power {} exceeds critical threshold {}.'.format(name, power, power_critical_threshold))

if presence and psu_status.set_voltage(voltage, voltage_high_threshold, voltage_low_threshold):
set_led = True
log_on_status_changed(self, psu_status.voltage_good,
Expand Down Expand Up @@ -532,6 +579,9 @@ class DaemonPsud(daemon_base.DaemonBase):
(PSU_INFO_VOLTAGE_MAX_TH_FIELD, str(voltage_high_threshold)),
(PSU_INFO_CURRENT_FIELD, str(current)),
(PSU_INFO_POWER_FIELD, str(power)),
(PSU_INFO_POWER_WARNING_SUPPRESS_THRESHOLD, str(power_warning_suppress_threshold)),
(PSU_INFO_POWER_CRITICAL_THRESHOLD, str(power_critical_threshold)),
(PSU_INFO_POWER_OVERLOAD, str(power_exceeded_threshold)),
(PSU_INFO_FRU_FIELD, str(is_replaceable)),
(PSU_INFO_IN_CURRENT_FIELD, str(in_current)),
(PSU_INFO_IN_VOLTAGE_FIELD, str(in_voltage)),
Expand Down
6 changes: 6 additions & 0 deletions sonic-psud/tests/mock_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,12 @@ def set_status_led(self, color):
self._status_led_color = color
return True

def get_psu_power_critical_threshold(self):
raise NotImplementedError

def get_psu_power_warning_suppress_threshold(self):
raise NotImplementedError

# Methods inherited from DeviceBase class and related setters
def get_name(self):
return self._name
Expand Down
Loading

0 comments on commit 4e30850

Please sign in to comment.