-
Notifications
You must be signed in to change notification settings - Fork 678
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[201911] Add soft-reboot reboot type (#1449)
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
1 parent
9e74075
commit d86af49
Showing
1 changed file
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}" | ||