Skip to content

Commit 8a07af9

Browse files
authored
[Mellanox] Modified Platform API to support all firmware updates in single boot (#9608)
Why I did it Requirements from Microsoft for fwutil update all state that all firmwares which support this upgrade flow must support upgrade within a single boot cycle. This conflicted with a number of Mellanox upgrade flows which have been revised to safely meet this requirement. How I did it Added --no-power-cycle flags to SSD and ONIE firmware scripts Modified Platform API to call firmware upgrade flows with this new flag during fwutil update all Added a script to our reboot plugin to handle installing firmwares in the correct order with prior to reboot How to verify it Populate platform_components.json with firmware for CPLD / BIOS / ONIE / SSD Execute fwutil update all fw --boot cold CPLD will burn / ONIE and BIOS images will stage / SSD will schedule for reboot Reboot the switch SSD will install / CPLD will refresh / switch will power cycle into ONIE ONIE installer will upgrade ONIE and BIOS / switch will reboot back into SONiC In SONiC run fwutil show status to check that all firmware upgrades were successful
1 parent f5cefb1 commit 8a07af9

File tree

11 files changed

+310
-93
lines changed

11 files changed

+310
-93
lines changed

device/mellanox/x86_64-mlnx_msn2700-r0/platform_reboot

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
declare -r EXIT_SUCCESS="0"
44
declare -r EXIT_ERROR="1"
55

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

@@ -40,4 +41,6 @@ if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
4041
fi
4142
fi
4243

44+
${PENDING_COMPONENT_FW}
45+
4346
SafePwrCycle

files/build_templates/sonic_debian_extension.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,7 @@ sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version
842842
sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh
843843
sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE
844844
sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE
845+
sudo cp $files_path/$MLNX_INSTALL_PENDING_FW $FILESYSTEM_ROOT/usr/bin/$MLNX_INSTALL_PENDING_FW
845846
j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
846847
sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh
847848

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# DPKG FRK
2+
3+
DPATH := $($(MLNX_INSTALL_PENDING_FW)_PATH)
4+
DEP_FILES := $(SONIC_COMMON_FILES_LIST) $(PLATFORM_PATH)/install-pending-fw.mk $(PLATFORM_PATH)/install-pending-fw.dep
5+
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
6+
DEP_FILES += $(addprefix $(DPATH),$(MLNX_INSTALL_PENDING_FW))
7+
8+
$(MLNX_INSTALL_PENDING_FW)_CACHE_MODE := GIT_CONTENT_SHA
9+
$(MLNX_INSTALL_PENDING_FW)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
10+
$(MLNX_INSTALL_PENDING_FW)_DEP_FILES := $(DEP_FILES)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES.
3+
# Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# Firmware pending update checker and installer
18+
19+
MLNX_INSTALL_PENDING_FW = install-pending-fw.py
20+
$(MLNX_INSTALL_PENDING_FW)_PATH = $(PLATFORM_PATH)/
21+
SONIC_COPY_FILES += $(MLNX_INSTALL_PENDING_FW)
22+
23+
MLNX_FILES += $(MLNX_INSTALL_PENDING_FW)
24+
25+
export MLNX_INSTALL_PENDING_FW
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES.
4+
# Apache-2.0
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
import os
20+
21+
from fwutil.lib import ComponentStatusProvider, PlatformComponentsParser
22+
from sonic_platform.component import ComponentCPLD, MPFAManager
23+
24+
# Globals
25+
FW_STATUS_SCHEDULED = "scheduled"
26+
CPLD_FLAG = False
27+
28+
# Init platform chassis helper classes
29+
csp = ComponentStatusProvider()
30+
pcp = PlatformComponentsParser(csp.is_modular_chassis())
31+
32+
# Parse update status file
33+
update_status = csp.read_au_status_file_if_exists()
34+
35+
if update_status is None:
36+
exit(0)
37+
38+
# Parse platform components file
39+
try:
40+
pcp.parse_platform_components()
41+
except Exception as e:
42+
print("Error parsing platform components. Firmware update failed: {}".format(str(e)))
43+
print("System will reboot in 10 seconds please fix issue and run update command again.")
44+
time.sleep(10)
45+
exit(-1)
46+
47+
# Iterate each component in the status file
48+
comp_install = []
49+
files = []
50+
51+
for boot_type, components in update_status.items():
52+
for comp in components:
53+
54+
# Skip if fw isn't scheduled for install at reboot
55+
if comp["info"] != FW_STATUS_SCHEDULED: continue
56+
57+
# Get component object and target firmware file
58+
key = comp["comp"]
59+
comp_path = key.split("/")
60+
61+
if len(comp_path) == 3:
62+
# Module component
63+
_, parent_name, comp_name = comp_path
64+
fw_file = pcp.module_component_map[parent_name][comp_name]["firmware"]
65+
component = csp.module_component_map[parent_name][comp_name]
66+
else:
67+
# Chassis component
68+
parent_name, comp_name = comp_path
69+
fw_file = pcp.chassis_component_map[parent_name][comp_name]["firmware"]
70+
component = csp.chassis_component_map[parent_name][comp_name]
71+
72+
# Install firmware. If CPLD flag to be installed last due to force reboot during refresh
73+
if type(component) == ComponentCPLD:
74+
if CPLD_FLAG:
75+
# Only need one refresh
76+
continue
77+
mpfa = MPFAManager(fw_file)
78+
mpfa.extract()
79+
if not mpfa.get_metadata().has_option('firmware', 'refresh'):
80+
print("Failed to get CPLD refresh firmware. Skipping.")
81+
continue
82+
CPLD_FLAG = True
83+
refresh_firmware = mpfa.get_metadata().get('firmware', 'refresh')
84+
comp_install = comp_install + [component]
85+
files = files + [os.path.join(mpfa.get_path(), refresh_firmware)]
86+
else:
87+
comp_install = [component] + comp_install
88+
files = [fw_file] + files
89+
90+
# Do install
91+
for i, c in enumerate(comp_install):
92+
try:
93+
if type(c) == ComponentCPLD:
94+
c.install_firmware(files[i])
95+
else:
96+
c.install_firmware(files[i], allow_reboot=False)
97+
except Exception as e:
98+
print("Firmware install for {} FAILED with: {}".format(c.get_name(),e))
99+

platform/mellanox/mlnx-onie-fw-update.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,12 @@ case "${cmd}" in
186186
rc=$?
187187
disable_onie_access
188188
if [[ ${rc} -eq 0 ]]; then
189-
system_reboot
189+
if [[ "${arg}" == "--no-reboot" ]]; then
190+
echo "INFO: ONIE firmware update successfully STAGED for install at NEXT reboot. Please reboot manually to complete installation."
191+
exit 0
192+
else
193+
system_reboot
194+
fi
190195
else
191196
echo "ERROR: failed to enable ONIE firmware update mode"
192197
exit ${rc}

0 commit comments

Comments
 (0)