Skip to content

[Mellanox] Modified Platform API to support all firmware updates in single boot #9608

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

Merged
merged 33 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
17011de
Split ONIE and SSD install from reboot
alexrallen Nov 15, 2021
dee7de3
Support separating install from update
alexrallen Nov 19, 2021
ebde9c9
Partial done
alexrallen Nov 22, 2021
fb8f442
Finish implementation
alexrallen Nov 22, 2021
4c987c3
Changes to get everything working
alexrallen Nov 23, 2021
d6c68c6
Fix permissions on pending fw script
alexrallen Nov 23, 2021
e80462c
Update unit testss
alexrallen Nov 24, 2021
2def48d
Review feedback and fix tests
alexrallen Nov 24, 2021
91a333b
More feedback
alexrallen Nov 24, 2021
fa2463b
Respond to feedback
alexrallen Nov 24, 2021
7dbbc41
Respond to review
alexrallen Nov 28, 2021
70b8be8
Fix some formatting and add missing mock
alexrallen Nov 28, 2021
e2e6155
More formatting
alexrallen Nov 28, 2021
1907e6f
Add copyright header to new script
alexrallen Nov 28, 2021
00e2da3
Fix some odds and ends
alexrallen Nov 29, 2021
1ac2938
Fix key parsing
alexrallen Nov 29, 2021
0eaea23
Add some SSD safety
alexrallen Dec 8, 2021
96e1590
Allow multiple updates through ONIE updater
alexrallen Dec 10, 2021
979a8cb
Fix some bugs
alexrallen Dec 13, 2021
f1e2216
Fix UNKOWN spelling in firmware unit tests
alexrallen Dec 13, 2021
d8ea208
Fix imports on firmware test
alexrallen Dec 14, 2021
5bd85f2
Fix typo
alexrallen Dec 14, 2021
12f9dda
Clean up other references to UKNOWN. Fix more imports.
alexrallen Dec 14, 2021
f649e98
Fix multiple CPLD logic to just skip multiple refresh operations
alexrallen Dec 14, 2021
77c2657
Correctly init the CPLD object
alexrallen Dec 14, 2021
3cd668e
Remove fw auto update test case for SSD failure since update flow doe…
alexrallen Dec 14, 2021
56e6f58
Fix typo
alexrallen Dec 14, 2021
631af30
Fix error handling for CPLD MPFA
alexrallen Dec 15, 2021
b116154
Add error handling to reboot plugin installer
alexrallen Dec 15, 2021
9fd75b5
Add prefix to images for ONIE installer to define explicit ordering
alexrallen Dec 17, 2021
07c6709
Add new reboot plugin to build template
alexrallen Jan 5, 2022
dc436e9
Merge branch 'master' into fwutil_split
alexrallen Jan 18, 2022
ccdf29a
Fix unused import
alexrallen Jan 18, 2022
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
3 changes: 3 additions & 0 deletions device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare -r EXIT_SUCCESS="0"
declare -r EXIT_ERROR="1"

declare -r PENDING_COMPONENT_FW="/usr/bin/install-pending-fw.py"
declare -r FW_UPGRADE_SCRIPT="/usr/bin/mlnx-fw-upgrade.sh"
declare -r SYSFS_PWR_CYCLE="/sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/pwr_cycle"

Expand Down Expand Up @@ -40,4 +41,6 @@ if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
fi
fi

${PENDING_COMPONENT_FW}

SafePwrCycle
1 change: 1 addition & 0 deletions files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version
sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh
sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE
sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE
sudo cp $files_path/$MLNX_INSTALL_PENDING_FW $FILESYSTEM_ROOT/usr/bin/$MLNX_INSTALL_PENDING_FW
j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh

Expand Down
10 changes: 10 additions & 0 deletions platform/mellanox/install-pending-fw.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# DPKG FRK

DPATH := $($(MLNX_INSTALL_PENDING_FW)_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/install-pending-fw.mk $(PLATFORM_PATH)/install-pending-fw.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(addprefix $(DPATH),$(MLNX_INSTALL_PENDING_FW))

$(MLNX_INSTALL_PENDING_FW)_CACHE_MODE := GIT_CONTENT_SHA
$(MLNX_INSTALL_PENDING_FW)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(MLNX_INSTALL_PENDING_FW)_DEP_FILES := $(DEP_FILES)
25 changes: 25 additions & 0 deletions platform/mellanox/install-pending-fw.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES.
# Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Firmware pending update checker and installer

MLNX_INSTALL_PENDING_FW = install-pending-fw.py
$(MLNX_INSTALL_PENDING_FW)_PATH = $(PLATFORM_PATH)/
SONIC_COPY_FILES += $(MLNX_INSTALL_PENDING_FW)

MLNX_FILES += $(MLNX_INSTALL_PENDING_FW)

export MLNX_INSTALL_PENDING_FW
99 changes: 99 additions & 0 deletions platform/mellanox/install-pending-fw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
#
# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES.
# Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os

from fwutil.lib import ComponentStatusProvider, PlatformComponentsParser
from sonic_platform.component import ComponentCPLD, MPFAManager

# Globals
FW_STATUS_SCHEDULED = "scheduled"
CPLD_FLAG = False

# Init platform chassis helper classes
csp = ComponentStatusProvider()
pcp = PlatformComponentsParser(csp.is_modular_chassis())

# Parse update status file
update_status = csp.read_au_status_file_if_exists()

if update_status is None:
exit(0)

# Parse platform components file
try:
pcp.parse_platform_components()
except Exception as e:
print("Error parsing platform components. Firmware update failed: {}".format(str(e)))
print("System will reboot in 10 seconds please fix issue and run update command again.")
time.sleep(10)
exit(-1)

# Iterate each component in the status file
comp_install = []
files = []

for boot_type, components in update_status.items():
for comp in components:

# Skip if fw isn't scheduled for install at reboot
if comp["info"] != FW_STATUS_SCHEDULED: continue

# Get component object and target firmware file
key = comp["comp"]
comp_path = key.split("/")

if len(comp_path) == 3:
# Module component
_, parent_name, comp_name = comp_path
fw_file = pcp.module_component_map[parent_name][comp_name]["firmware"]
component = csp.module_component_map[parent_name][comp_name]
else:
# Chassis component
parent_name, comp_name = comp_path
fw_file = pcp.chassis_component_map[parent_name][comp_name]["firmware"]
component = csp.chassis_component_map[parent_name][comp_name]

# Install firmware. If CPLD flag to be installed last due to force reboot during refresh
if type(component) == ComponentCPLD:
if CPLD_FLAG:
# Only need one refresh
continue
mpfa = MPFAManager(fw_file)
mpfa.extract()
if not mpfa.get_metadata().has_option('firmware', 'refresh'):
print("Failed to get CPLD refresh firmware. Skipping.")
continue
CPLD_FLAG = True
refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh')
comp_install = comp_install + [component]
files = files + [os.path.join(mpfa.get_path(), refresh_firmware)]
else:
comp_install = [component] + comp_install
files = [fw_file] + files

# Do install
for i, c in enumerate(comp_install):
try:
if type(c) == ComponentCPLD:
c.install_firmware(files[i])
else:
c.install_firmware(files[i], allow_reboot=False)
except Exception as e:
print("Firmware install for {} FAILED with: {}".format(c.get_name(),e))

7 changes: 6 additions & 1 deletion platform/mellanox/mlnx-onie-fw-update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,12 @@ case "${cmd}" in
rc=$?
disable_onie_access
if [[ ${rc} -eq 0 ]]; then
system_reboot
if [[ "${arg}" == "--no-reboot" ]]; then
echo "INFO: ONIE firmware update successfully STAGED for install at NEXT reboot. Please reboot manually to complete installation."
exit 0
else
system_reboot
fi
else
echo "ERROR: failed to enable ONIE firmware update mode"
exit ${rc}
Expand Down
Loading