Skip to content

Commit e32b5ac

Browse files
authored
Add soft-reboot reboot type (#1453)
What I did Add a new reboot named as soft-reboot which can be performed by "kexec -e" How I did it Replace the platform reboot with "kexec -e" for the cold reboot case. How to verify it Verified the reboot on DUT and check the reboot-cause
1 parent 8b3bc18 commit e32b5ac

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed

scripts/soft-reboot

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#!/bin/bash
2+
DEVPATH="/usr/share/sonic/device"
3+
REBOOT_CAUSE_FILE="/host/reboot-cause/reboot-cause.txt"
4+
REBOOT_TIME=$(date)
5+
REBOOT_METHOD="/sbin/kexec -e"
6+
LOG_SSD_HEALTH="/usr/local/bin/log_ssd_health"
7+
WATCHDOG_UTIL="/usr/local/bin/watchdogutil"
8+
9+
EXIT_SUCCESS=0
10+
EXIT_FAILURE=1
11+
EXIT_NOT_SUPPORTED=2
12+
EXIT_FILE_SYSTEM_FULL=3
13+
EXIT_NEXT_IMAGE_NOT_EXISTS=4
14+
15+
# Reboot immediately if we run the kdump capture kernel
16+
VMCORE_FILE=/proc/vmcore
17+
if [ -e $VMCORE_FILE -a -s $VMCORE_FILE ]; then
18+
echo "We have a /proc/vmcore, then we just kdump'ed"
19+
echo "User issued 'kdump' command [User: kdump, Time: ${REBOOT_TIME}]" > ${REBOOT_CAUSE_FILE}
20+
sync
21+
PLATFORM=$(grep -oP 'sonic_platform=\K\S+' /proc/cmdline)
22+
if [ ! -z "${PLATFORM}" -a -x ${DEVPATH}/${PLATFORM}/${PLAT_REBOOT} ]; then
23+
exec ${DEVPATH}/${PLATFORM}/${PLAT_REBOOT}
24+
fi
25+
# If no platform-specific reboot tool, just run /sbin/reboot
26+
/sbin/reboot
27+
echo 1 > /proc/sys/kernel/sysrq
28+
echo b > /proc/sysrq-trigger
29+
fi
30+
31+
REBOOT_USER=$(logname)
32+
PLATFORM=$(sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
33+
ASIC_TYPE=$(sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type)
34+
VERBOSE=no
35+
EXIT_NEXT_IMAGE_NOT_EXISTS=4
36+
EXIT_SONIC_INSTALLER_VERIFY_REBOOT=21
37+
SSD_FW_UPDATE="ssd-fw-upgrade"
38+
REBOOT_SCRIPT_NAME=$(basename $0)
39+
REBOOT_TYPE="${REBOOT_SCRIPT_NAME}"
40+
PLATFORM_PLUGIN="${REBOOT_TYPE}_plugin"
41+
BOOT_TYPE_ARG="soft"
42+
TAG_LATEST=yes
43+
44+
function debug()
45+
{
46+
if [[ x"${VERBOSE}" == x"yes" ]]; then
47+
echo `date` $@
48+
fi
49+
logger "$@"
50+
}
51+
52+
function tag_images()
53+
{
54+
if test -f /usr/local/bin/ctrmgr_tools.py
55+
then
56+
if [[ x"${TAG_LATEST}" == x"yes" ]]; then
57+
/usr/local/bin/ctrmgr_tools.py tag-all
58+
fi
59+
fi
60+
}
61+
62+
function stop_sonic_services()
63+
{
64+
if [[ x"$ASIC_TYPE" != x"mellanox" ]]; then
65+
debug "Stopping syncd process..."
66+
docker exec -i syncd /usr/bin/syncd_request_shutdown --cold > /dev/null
67+
sleep 3
68+
fi
69+
}
70+
71+
function clear_lingering_reboot_config()
72+
{
73+
# Clear any outstanding warm-reboot config
74+
result=`timeout 10s config warm_restart disable; if [[ $? == 124 ]]; then echo timeout; else echo "code ($?)"; fi` || /bin/true
75+
debug "Cancel warm-reboot: ${result}"
76+
77+
WARM_DIR="/host/warmboot"
78+
REDIS_FILE=dump.rdb
79+
TIMESTAMP=`date +%Y%m%d-%H%M%S`
80+
if [[ -f ${WARM_DIR}/${REDIS_FILE} ]]; then
81+
mv -f ${WARM_DIR}/${REDIS_FILE} ${WARM_DIR}/${REDIS_FILE}.${TIMESTAMP} || /bin/true
82+
fi
83+
/sbin/kexec -u || /bin/true
84+
}
85+
86+
SCRIPT=$0
87+
88+
function show_help_and_exit()
89+
{
90+
echo "Usage ${SCRIPT} [options]"
91+
echo " Request rebooting the device. Invoke platform-specific tool when available."
92+
echo " This script will shutdown syncd before rebooting."
93+
echo " "
94+
echo " Available options:"
95+
echo " -h, -? : getting this help"
96+
97+
exit "${EXIT_SUCCESS}"
98+
}
99+
100+
function setup_reboot_variables()
101+
{
102+
# Kernel and initrd image
103+
NEXT_SONIC_IMAGE=$(sonic-installer list | grep "Next: " | cut -d ' ' -f 2)
104+
IMAGE_PATH="/host/image-${NEXT_SONIC_IMAGE#SONiC-OS-}"
105+
if grep -q aboot_platform= /host/machine.conf; then
106+
KERNEL_IMAGE="$(ls $IMAGE_PATH/boot/vmlinuz-*)"
107+
BOOT_OPTIONS="$(cat "$IMAGE_PATH/kernel-cmdline" | tr '\n' ' ') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}"
108+
elif grep -q onie_platform= /host/machine.conf; then
109+
KERNEL_OPTIONS=$(cat /host/grub/grub.cfg | sed "/$NEXT_SONIC_IMAGE'/,/}/"'!'"g" | grep linux)
110+
KERNEL_IMAGE="/host$(echo $KERNEL_OPTIONS | cut -d ' ' -f 2)"
111+
BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}"
112+
else
113+
error "Unknown bootloader. ${REBOOT_TYPE} is not supported."
114+
exit "${EXIT_NOT_SUPPORTED}"
115+
fi
116+
INITRD=$(echo $KERNEL_IMAGE | sed 's/vmlinuz/initrd.img/g')
117+
}
118+
119+
function load_kernel() {
120+
# Load kernel into the memory
121+
/sbin/kexec -l "$KERNEL_IMAGE" --initrd="$INITRD" --append="$BOOT_OPTIONS"
122+
}
123+
124+
function reboot_pre_check()
125+
{
126+
# Make sure that the file system is normal: read-write able
127+
filename="/host/test-`date +%Y%m%d-%H%M%S`"
128+
ERR=0
129+
touch ${filename} || ERR=$?
130+
if [[ ${ERR} -ne 0 ]]; then
131+
# Continue rebooting in this case, but log the error
132+
VERBOSE=yes debug "Filesystem might be read-only or full ..."
133+
fi
134+
rm ${filename}
135+
136+
# Verify the next image by sonic-installer
137+
local message=$(sonic-installer verify-next-image 2>&1)
138+
if [ $? -ne 0 ]; then
139+
VERBOSE=yes debug "Failed to verify next image: ${message}"
140+
exit ${EXIT_SONIC_INSTALLER_VERIFY_REBOOT}
141+
fi
142+
}
143+
144+
function parse_options()
145+
{
146+
while getopts "h?v" opt; do
147+
case ${opt} in
148+
h|\? )
149+
show_help_and_exit
150+
;;
151+
v )
152+
VERBOSE=yes
153+
;;
154+
t )
155+
TAG_LATEST=no
156+
;;
157+
esac
158+
done
159+
}
160+
161+
parse_options $@
162+
163+
# Exit if not superuser
164+
if [[ "$EUID" -ne 0 ]]; then
165+
echo "This command must be run as root" >&2
166+
exit "${EXIT_FAILURE}"
167+
fi
168+
169+
if [ -x ${LOG_SSD_HEALTH} ]; then
170+
debug "Collecting logs to check ssd health before ${REBOOT_TYPE}..."
171+
${LOG_SSD_HEALTH}
172+
fi
173+
174+
debug "User requested rebooting device ..."
175+
176+
setup_reboot_variables
177+
reboot_pre_check
178+
179+
# Tag remotely deployed images as local
180+
tag_images
181+
182+
# Stop SONiC services gracefully.
183+
stop_sonic_services
184+
185+
clear_lingering_reboot_config
186+
187+
load_kernel
188+
189+
# Update the reboot cause file to reflect that user issued 'reboot' command
190+
# Upon next boot, the contents of this file will be used to determine the
191+
# cause of the previous reboot
192+
echo "User issued '${REBOOT_SCRIPT_NAME}' command [User: ${REBOOT_USER}, Time: ${REBOOT_TIME}]" > ${REBOOT_CAUSE_FILE}
193+
194+
sync
195+
sleep 3
196+
sync
197+
198+
# sync the current system time to CMOS
199+
if [ -x /sbin/hwclock ]; then
200+
/sbin/hwclock -w || /bin/true
201+
fi
202+
203+
if [ -x ${DEVPATH}/${PLATFORM}/${SSD_FW_UPDATE} ]; then
204+
debug "updating ssd fw for${REBOOT_TYPE}"
205+
${DEVPATH}/${PLATFORM}/${SSD_FW_UPDATE} ${REBOOT_TYPE}
206+
fi
207+
208+
# Enable Watchdog Timer
209+
if [ -x ${WATCHDOG_UTIL} ]; then
210+
debug "Enabling Watchdog before ${REBOOT_TYPE}"
211+
${WATCHDOG_UTIL} arm
212+
fi
213+
214+
# Run platform specific reboot plugin
215+
if [ -x ${DEVPATH}/${PLATFORM}/${PLATFORM_PLUGIN} ]; then
216+
debug "Running ${PLATFORM} specific plugin..."
217+
${DEVPATH}/${PLATFORM}/${PLATFORM_PLUGIN}
218+
fi
219+
220+
# Reboot: explicitly call Linux "kexec -e"
221+
debug "Rebooting with ${REBOOT_METHOD} to ${NEXT_SONIC_IMAGE} ..."
222+
exec ${REBOOT_METHOD}
223+
224+
# Should never reach here
225+
error "${REBOOT_TYPE} failed!"
226+
exit "${EXIT_FAILURE}"
227+

0 commit comments

Comments
 (0)