diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 2889b2469960..6a8dd2dbb3bd 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -1029,6 +1029,7 @@ sudo cp $files_path/$COMPONENT_VERSIONS_FILE $FILESYSTEM_ROOT/etc/mlnx/component 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_SONIC_BFB_INSTALL $FILESYSTEM_ROOT/usr/bin/$MLNX_SONIC_BFB_INSTALL sudo cp $files_path/$MLNX_INSTALL_PENDING_FW $FILESYSTEM_ROOT/usr/bin/$MLNX_INSTALL_PENDING_FW sudo mkdir -p $FILESYSTEM_ROOT/etc/mlnx/cpld/ for MLNX_CPLD_ARCHIVE in $MLNX_CPLD_ARCHIVES; do diff --git a/platform/mellanox/mlnx-sonic-bfb-installer.mk b/platform/mellanox/mlnx-sonic-bfb-installer.mk new file mode 100644 index 000000000000..2f9f177460a3 --- /dev/null +++ b/platform/mellanox/mlnx-sonic-bfb-installer.mk @@ -0,0 +1,25 @@ +# +# Copyright (c) 2020-2024 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. +# +# Mellanox specific Tool for installing bfb image on all DPUs attached to SmartSwitch + +MLNX_SONIC_BFB_INSTALL = sonic-bfb-installer.sh +$(MLNX_SONIC_BFB_INSTALL)_PATH = $(PLATFORM_PATH)/ +MLNX_BFB_FILES = $(MLNX_SONIC_BFB_INSTALL) +SONIC_COPY_FILES += $(MLNX_BFB_FILES) +MLNX_FILES += $(MLNX_BFB_FILES) + +export MLNX_SONIC_BFB_INSTALL diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index f7a10bc82b61..19e83b7c30c0 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -36,6 +36,7 @@ include $(PLATFORM_PATH)/install-pending-fw.mk include $(PLATFORM_PATH)/integration-scripts.mk include $(PLATFORM_PATH)/component-versions.mk include $(PLATFORM_PATH)/rshim.mk +include $(PLATFORM_PATH)/mlnx-sonic-bfb-installer.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) diff --git a/platform/mellanox/sonic-bfb-installer.sh b/platform/mellanox/sonic-bfb-installer.sh new file mode 100755 index 000000000000..4959a72a052a --- /dev/null +++ b/platform/mellanox/sonic-bfb-installer.sh @@ -0,0 +1,162 @@ +#!/bin/bash +# +# Copyright (c) 2024 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. +# + +command_name="sonic-bfb-installer.sh" +usage(){ + echo "Syntax: $command_name -b|--bfb --rshim|-r --verbose|-v --config|-c --help|h" + echo "Arguments:" + echo "-b Provide custom path for bfb image" + echo "-r Install only on DPUs connected to rshim interfaces provided, mention all if installation is requried on all connected DPUs" + echo "-v Verbose installation result output" + echo "-c Config file" + echo "-h Help" +} + +bfb_install_call(){ + #Example:sudo bfb-install -b -r rshim + local result_file=$(mktemp "/tmp/result_file.XXXXX") + trap "rm -f $result_file" EXIT + local cmd="timeout 300s bfb-install -b $2 -r $1 $appendix" + echo "Installing bfb image on DPU connected to $1 using $cmd" + local indicator="$1:" + eval "$cmd" > "$result_file" 2>&1 > >(while IFS= read -r line; do echo "$indicator $line"; done > "$result_file") + local exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "$1: Error: Installation failed on connected DPU!" + else + echo "$1: Installation Successful" + fi + if [ $exit_status -ne 0 ] ||[ $verbose = true ]; then + cat "$result_file" + fi + rm -f $result_file +} + +validate_rshim(){ + local provided_list=("$@") + for item1 in "${provided_list[@]}"; do + local found=0 + for item2 in "${dev_names_det[@]}"; do + if [[ "$item1" = "$item2" ]]; then + found=1 + break + fi + done + if [[ $found -eq 0 ]]; then + echo "$item1 is not detected! Please provide proper rshim interface list!" + exit 1 + fi + done +} + +check_for_root(){ + if [ "$EUID" -ne 0 ] + then echo "Please run the script in sudo mode" + exit + fi +} + + + +main(){ + check_for_root + local config= + while [ "$1" != "--" ] && [ -n "$1" ]; do + case $1 in + --help|-h) + usage; + exit 0 + ;; + --bfb|-b) + shift; + bfb=$1 + ;; + --rshim|-r) + shift; + rshim_dev=$1 + ;; + --config|-c) + shift; + config=$1 + ;; + --verbose|-v) + verbose=true + ;; + esac + shift + done + if [ -z "$bfb" ]; then + echo "Error : bfb image is not provided." + usage + exit 1 + fi + if [[ -f ${config} ]]; then + echo "Using ${config} file" + appendix="-c ${config}" + fi + IFS=$'\n' + dev_names_det+=($(ls /dev/rshim* | awk -F'/' '/^\/dev\/rshim/ {gsub(/:/,"",$NF); print $NF}')) + if [ "${#dev_names_det[@]}" -eq 0 ]; then + echo "No rshim interfaces detected! Make sure to run the $command_name script from the host device/ switch!" + exit 1 + fi + if [ -z "$rshim_dev" ]; then + echo "No rshim interfaces provided!" + usage + exit 1 + else + if [ "$rshim_dev" = "all" ]; then + dev_names=("${dev_names_det[@]}") + echo "${#dev_names_det[@]} rshim interfaces detected:" + echo "${dev_names_det[@]}" + else + IFS=',' read -ra dev_names <<< "$rshim_dev" + validate_rshim $dev_names + fi + fi + trap 'kill_ch_procs' SIGINT SIGTERM SIGHUP + for i in "${dev_names[@]}" + do + : + bfb_install_call $i $bfb & + done + wait +} + +kill_all_descendant_procs() { + local pid="$1" + local self_kill="${2:-false}" + if children="$(pgrep -P "$pid")"; then + for child in $children; do + kill_all_descendant_procs "$child" true + done + fi + if [[ "$self_kill" == true ]]; then + kill -15 "$pid" > /dev/null 2>&1 + fi +} + + +kill_ch_procs(){ + echo "" + echo "Installation Interrupted.. killing All child procs" + kill_all_descendant_procs $$ +} +appendix= +verbose=false +main "$@"