Skip to content

Commit

Permalink
[201911] Add soft-reboot reboot type (#1449)
Browse files Browse the repository at this point in the history
What I did
Introduce a new reboot named as soft-reboot to perform a kernel reboot instead of platform reboot

How I did it
Replace the platform reboot with kernel reboot from cold reboot.

How to verify it
Perform soft-reboot on DUT and verify all dockers and ports are up and running as expected as cold reboot
And verify the reboot-cause as soft-reboot
  • Loading branch information
sujinmkang authored Mar 8, 2021
1 parent 9e74075 commit d86af49
Showing 1 changed file with 184 additions and 0 deletions.
184 changes: 184 additions & 0 deletions scripts/soft-reboot
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/bin/bash

REBOOT_USER=$(logname)
REBOOT_TIME=$(date)
PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type)
DEVPATH="/usr/share/sonic/device"
REBOOT_SCRIPT_NAME=$(basename $0)
REBOOT_TYPE="${REBOOT_SCRIPT_NAME}"
REBOOT_METHOD="/sbin/kexec -e"
PLATFORM_PLUGIN="${REBOOT_TYPE}_plugin"
REBOOT_CAUSE_FILE="/host/reboot-cause/reboot-cause.txt"
WATCHDOG_UTIL="/usr/bin/watchdogutil"
VERBOSE=no
EXIT_SUCCESS=0
EXIT_FAILURE=1
EXIT_NOT_SUPPORTED=2
EXIT_FILE_SYSTEM_FULL=3
EXIT_NEXT_IMAGE_NOT_EXISTS=4
BOOT_TYPE_ARG="soft"

function debug()
{
if [[ x"${VERBOSE}" == x"yes" ]]; then
echo `date` $@
fi
logger "$@"
}

function stop_sonic_services()
{
if [[ x"$ASIC_TYPE" != x"mellanox" ]]; then
debug "Stopping syncd process..."
docker exec -i syncd /usr/bin/syncd_request_shutdown --cold > /dev/null
sleep 3
fi
}

function clear_lingering_reboot_config()
{
# Make sure the outstanding warm-boot is cleared
result=`timeout 10s config warm_restart disable; if [[ $? == 124 ]]; then echo timeout; else echo "code ($?)"; fi` || /bin/true
debug "Cancel warm-reboot: ${result}"
WARM_DIR="/host/warmboot"
REDIS_FILE=dump.rdb
TIMESTAMP=`date +%Y%m%d-%H%M%S`
if [[ -f ${WARM_DIR}/${REDIS_FILE} ]]; then
mv -f ${WARM_DIR}/${REDIS_FILE} ${WARM_DIR}/${REDIS_FILE}.${TIMESTAMP} || /bin/true
fi
/sbin/kexec -u || /bin/true
}
SCRIPT=$0
function show_help_and_exit()
{
echo "Usage ${SCRIPT} [options]"
echo " Request rebooting the device. Invoke platform-specific tool when available."
echo " This script will shutdown syncd before rebooting."
echo " "
echo " Available options:"
echo " -h, -? : getting this help"
exit 0
}
function setup_reboot_variables()
{
NEXT_SONIC_IMAGE=$(sonic_installer list | grep "Next: " | cut -d ' ' -f 2)
IMAGE_PATH="/host/image-${NEXT_SONIC_IMAGE#SONiC-OS-}"
if grep -q aboot_platform= /host/machine.conf; then
KERNEL_IMAGE="$(ls $IMAGE_PATH/boot/vmlinuz-*)"
BOOT_OPTIONS="$(cat "$IMAGE_PATH/kernel-cmdline" | tr '\n' ' ') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}"
elif grep -q onie_platform= /host/machine.conf; then
KERNEL_OPTIONS=$(cat /host/grub/grub.cfg | sed "/$NEXT_SONIC_IMAGE'/,/}/"'!'"g" | grep linux)
KERNEL_IMAGE="/host$(echo $KERNEL_OPTIONS | cut -d ' ' -f 2)"
BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}"
else
error "Unknown bootloader. ${REBOOT_TYPE} is not supported."
exit "${EXIT_NOT_SUPPORTED}"
fi
INITRD=$(echo $KERNEL_IMAGE | sed 's/vmlinuz/initrd.img/g')
}
function load_aboot_secureboot_kernel() {
local next_image="$IMAGE_PATH/sonic.swi"
echo "Loading next image from $next_image"
unzip -qp "$next_image" boot0 | \
swipath=$next_image kexec=true loadonly=true ENV_EXTRA_CMDLINE="$BOOT_OPTIONS" bash -
}
function load_kernel() {
# Load kernel into the memory
/sbin/kexec -l "$KERNEL_IMAGE" --initrd="$INITRD" --append="$BOOT_OPTIONS"
}
function reboot_pre_check()
{
# Make sure that the file system is normal: read-write able
filename="/host/test-`date +%Y%m%d-%H%M%S`"
ERR=0
touch ${filename} || ERR=$?
if [[ ${ERR} -ne 0 ]]; then
# Continue rebooting in this case, but log the error
VERBOSE=yes debug "Filesystem might be read-only or full ..."
fi
rm ${filename}
# Make sure that the next image exists
if [[ ! -d ${IMAGE_PATH} ]]; then
VERBOSE=yes debug "Next image ${NEXT_SONIC_IMAGE} doesn't exist ..."
exit ${EXIT_NEXT_IMAGE_NOT_EXISTS}
fi
}
function parse_options()
{
while getopts "h?v" opt; do
case ${opt} in
h|\? )
show_help_and_exit
;;
v )
VERBOSE=yes
;;
esac
done
}
parse_options $@
# Exit if not superuser
if [[ "$EUID" -ne 0 ]]; then
echo "This command must be run as root" >&2
exit 1
fi
debug "User requested rebooting device ..."
setup_reboot_variables
reboot_pre_check
# Stop SONiC services gracefully.
stop_sonic_services
clear_lingering_reboot_config
load_kernel
# Update the reboot cause file to reflect that user issued 'soft-reboot' command
# Upon next boot, the contents of this file will be used to determine the
# cause of the previous reboot
echo "User issued 'soft-reboot' command [User: ${REBOOT_USER}, Time: ${REBOOT_TIME}]" > ${REBOOT_CAUSE_FILE}
sync
sleep 1
sync
# sync the current system time to CMOS
if [ -x /sbin/hwclock ]; then
/sbin/hwclock -w || /bin/true
fi
# Enable Watchdog Timer
if [ -x ${WATCHDOG_UTIL} ]; then
debug "Enabling Watchdog before ${REBOOT_TYPE}"
${WATCHDOG_UTIL} arm
fi
# Run platform specific reboot plugin
if [ -x ${DEVPATH}/${PLATFORM}/${PLATFORM_PLUGIN} ]; then
debug "Running ${PLATFORM} specific plugin..."
${DEVPATH}/${PLATFORM}/${PLATFORM_PLUGIN}
fi
# Reboot: explicitly call Linux native reboot under sbin
debug "Rebooting with ${REBOOT_METHOD} to ${NEXT_SONIC_IMAGE} ..."
exec ${REBOOT_METHOD}
# Should never reach here
error "${REBOOT_TYPE} failed!"
exit "${EXIT_FAILURE}"

0 comments on commit d86af49

Please sign in to comment.