Skip to content

Commit

Permalink
[reboot-cause]: Move reboot cause processing to its own service, 'pro…
Browse files Browse the repository at this point in the history
…cess-reboot-cause' (#3102)
  • Loading branch information
jleveque authored and lguohan committed Jul 3, 2019
1 parent 211c8cd commit e5a2beb
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 32 deletions.
5 changes: 5 additions & 0 deletions files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd.service $FILESYSTEM_ROOT/etc/systemd/s
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable caclmgrd.service
sudo cp $IMAGE_CONFIGS/caclmgrd/caclmgrd $FILESYSTEM_ROOT/usr/bin/

# Copy process-reboot-cause service files
sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.service
sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause $FILESYSTEM_ROOT/usr/bin/

## Install package without starting service
## ref: https://wiki.debian.org/chroot
sudo tee -a $FILESYSTEM_ROOT/usr/sbin/policy-rc.d > /dev/null <<EOF
Expand Down
32 changes: 0 additions & 32 deletions files/image_config/platform/rc.local
Original file line number Diff line number Diff line change
Expand Up @@ -106,35 +106,6 @@ value_extract() {
done
}

# Set up previous and next reboot cause files accordingly
process_reboot_cause() {
REBOOT_CAUSE_DIR="/host/reboot-cause"
REBOOT_CAUSE_FILE="${REBOOT_CAUSE_DIR}/reboot-cause.txt"
PREVIOUS_REBOOT_CAUSE_FILE="${REBOOT_CAUSE_DIR}/previous-reboot-cause.txt"

mkdir -p $REBOOT_CAUSE_DIR

# If this is the first boot after an image install, store that as the
# previous reboot cause.
if [ -f $FIRST_BOOT_FILE ]; then
echo "SONiC image installation" > $PREVIOUS_REBOOT_CAUSE_FILE
fi

# If there is an existing REBOOT_CAUSE_FILE, copy that file to
# PREVIOUS_REBOOT_CAUSE_FILE.
if [ -f $REBOOT_CAUSE_FILE ]; then
mv -f $REBOOT_CAUSE_FILE $PREVIOUS_REBOOT_CAUSE_FILE
else
echo "Unknown reboot cause" > $PREVIOUS_REBOOT_CAUSE_FILE
fi

# Log the previous reboot cause to the syslog
logger "Previous reboot cause: $(cat $PREVIOUS_REBOOT_CAUSE_FILE)"

# Set the default cause for the next reboot
echo "Unexpected reboot" > $REBOOT_CAUSE_FILE
}

program_console_speed()
{
speed=$(cat /proc/cmdline | grep -Eo 'console=ttyS[0-9]+,[0-9]+' | cut -d "," -f2)
Expand All @@ -150,9 +121,6 @@ program_console_speed()

#### Begin Main Body ####

# Set up previous and next reboot cause files
process_reboot_cause

# If the machine.conf is absent, it indicates that the unit booted
# into SONiC from another NOS. Extract the machine.conf from ONIE.
if [ ! -e /host/machine.conf ]; then
Expand Down
89 changes: 89 additions & 0 deletions files/image_config/process-reboot-cause/process-reboot-cause
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python
#
# process-reboot-cause
#
# Program designed to run once, soon after system boot which will
# determine the cause of the previous reboot and store it to the disk,
#

try:
import os
import pwd
import subprocess
import sys
import syslog
import sonic_platform
from sonic_daemon_base.daemon_base import Logger
except ImportError as err:
raise ImportError("%s - required module not found" % str(err))

VERSION = "1.0"

SYSLOG_IDENTIFIER = "process-reboot-cause"

# Global logger instance
logger = Logger(SYSLOG_IDENTIFIER)

REBOOT_CAUSE_DIR = "/host/reboot-cause/"
REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt"
PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt"

UNKNOWN_REBOOT_CAUSE = "Unknown"


def main():
logger.log_info("Starting up...")

if not os.geteuid() == 0:
logger.log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name))
sys.exit("This utility must be run as root")

# Create REBOOT_CAUSE_DIR if it doesn't exist
if not os.path.exists(REBOOT_CAUSE_DIR):
os.makedirs(REBOOT_CAUSE_DIR)

# Remove stale PREVIOUS_REBOOT_CAUSE_FILE if it exists
if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE):
os.remove(PREVIOUS_REBOOT_CAUSE_FILE)

# Check if the previous reboot was caused by hardware
platform = sonic_platform.platform.Platform()

chassis = platform.get_chassis()

hardware_reboot_cause, optional_details = chassis.get_reboot_cause()

# Set a default previous reboot cause
previous_reboot_cause = UNKNOWN_REBOOT_CAUSE

if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE:
# The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will
# contain any software-related reboot info. We will use it as the previous cause.
if os.path.isfile(REBOOT_CAUSE_FILE):
cause_file = open(REBOOT_CAUSE_FILE, "r")
previous_reboot_cause = cause_file.readline().rstrip('\n')
cause_file.close()
elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER:
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
else:
previous_reboot_cause = hardware_reboot_cause

# Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE
prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w")
prev_cause_file.write(previous_reboot_cause)
prev_cause_file.close()

# Also log the previous reboot cause to the syslog
logger.log_info("Previous reboot cause: {}".format(previous_reboot_cause))

# Remove the old REBOOT_CAUSE_FILE
os.remove(REBOOT_CAUSE_FILE)

# Write a new default reboot cause file for the next reboot
cause_file = open(REBOOT_CAUSE_FILE, "w")
cause_file.write(UNKNOWN_REBOOT_CAUSE)
cause_file.close()


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Reboot cause determination service
After=rc-local.service

[Service]
Type=simple
ExecStart=/usr/bin/process-reboot-cause

[Install]
WantedBy=multi-user.target

0 comments on commit e5a2beb

Please sign in to comment.