Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move reboot cause processing to its own service, 'process-reboot-cause' #3102

Merged
merged 1 commit into from
Jul 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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