sonic-buildimage/files/scripts/syncd_common.sh
Aryeh Feigin 41a9813018
Finalize fast-reboot in warmboot finalizer (#14238)
- Why I did it
To solve an issue with upgrade with fast-reboot including FW upgrade which has been introduced since moving to fast-reboot over warm-reboot infrastructure.
As well, this introduces fast-reboot finalizing logic to determine fast-reboot is done.

- How I did it
Added logic to finalize-warmboot script to handle fast-reboot as well, this makes sense as using fast-reboot over warm-reboot this script will be invoked. The script will clear fast-reboot entry from state-db instead of previous implementation that relied on timer. The timer could expire in some scenarios between fast-reboot finished causing fallback to cold-reboot and possible crashes.

As well this PR updates all services/scripts reading fast-reboot state-db entry to look for the updated value representing fast-reboot is active.

- How to verify it
Run fast-reboot and check that fast-reboot entry exists in state-db right after startup and being cleared as warm-reboot is finalized and not due to a timer.
2023-04-09 16:59:15 +03:00

175 lines
4.2 KiB
Bash
Executable File

#!/bin/bash
#
# common functions used by "syncd" scipts (syncd.sh, gbsyncd.sh, etc..)
# scripts using this must provide implementations of the following functions:
#
# startplatform
# waitplatform
# stopplatform1 and stopplatform2
#
# For examples of these, see gbsyncd.sh and syncd.sh.
#
. /usr/local/bin/asic_status.sh
function debug()
{
/usr/bin/logger $1
/bin/echo `date` "- $1" >> ${DEBUGLOG}
}
function lock_service_state_change()
{
debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service"
exec {LOCKFD}>${LOCKFILE}
/usr/bin/flock -x ${LOCKFD}
trap "/usr/bin/flock -u ${LOCKFD}" EXIT
debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service"
}
function unlock_service_state_change()
{
debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service"
/usr/bin/flock -u ${LOCKFD}
}
function check_warm_boot()
{
SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable`
SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable`
# SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful.
if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then
WARM_BOOT="true"
else
WARM_BOOT="false"
fi
}
function check_fast_boot()
{
SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB hget "FAST_RESTART_ENABLE_TABLE|system" enable`
if [[ x"${SYSTEM_FAST_REBOOT}" == x"true" ]]; then
FAST_BOOT="true"
else
FAST_BOOT="false"
fi
}
function wait_for_database_service()
{
# Wait for redis server start before database clean
until [[ $($SONIC_DB_CLI PING | grep -c PONG) -gt 0 ]]; do
sleep 1;
done
# Wait for configDB initialization
until [[ $($SONIC_DB_CLI CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]];
do sleep 1;
done
}
function getBootType()
{
# same code snippet in files/build_templates/docker_image_ctl.j2
case "$(cat /proc/cmdline)" in
*SONIC_BOOT_TYPE=warm*)
TYPE='warm'
;;
*SONIC_BOOT_TYPE=fastfast*)
TYPE='fastfast'
;;
*SONIC_BOOT_TYPE=fast*|*fast-reboot*)
# check that the key exists
SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB hget "FAST_RESTART_ENABLE_TABLE|system" enable`
if [[ x"${SYSTEM_FAST_REBOOT}" == x"true" ]]; then
TYPE='fast'
else
TYPE='cold'
fi
;;
*)
TYPE='cold'
esac
echo "${TYPE}"
}
start() {
debug "Starting ${SERVICE}$DEV service..."
lock_service_state_change
mkdir -p /host/warmboot
wait_for_database_service
check_warm_boot
debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}."
if [[ x"$WARM_BOOT" == x"true" ]]; then
# Leave a mark for syncd scripts running inside docker.
touch /host/warmboot/warm-starting
else
rm -f /host/warmboot/warm-starting
fi
startplatform
# On supervisor card, skip starting asic related services here. In wait(),
# wait until the asic is detected by pmon and published via database.
if ! is_chassis_supervisor; then
# start service docker
/usr/bin/${SERVICE}.sh start $DEV
debug "Started ${SERVICE}$DEV service..."
fi
unlock_service_state_change
}
wait() {
# On supervisor card, wait for asic to be online before starting the docker.
if is_chassis_supervisor; then
check_asic_status
ASIC_STATUS=$?
# start service docker
if [[ $ASIC_STATUS == 0 ]]; then
/usr/bin/${SERVICE}.sh start $DEV
debug "Started ${SERVICE}$DEV service..."
fi
fi
waitplatform
/usr/bin/${SERVICE}.sh wait $DEV
}
stop() {
debug "Stopping ${SERVICE}$DEV service..."
lock_service_state_change
check_warm_boot
check_fast_boot
debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}."
debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}."
if [[ x"$WARM_BOOT" == x"true" ]]; then
TYPE=warm
elif [[ x"$FAST_BOOT" == x"true" ]]; then
TYPE=fast
else
TYPE=cold
fi
stopplatform1
/usr/bin/${SERVICE}.sh stop $DEV
debug "Stopped ${SERVICE}$DEV service..."
stopplatform2
unlock_service_state_change
}