From 1115c8431dbae0755cc443b70529f6606ee78972 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 3 Jul 2019 10:38:20 -0700 Subject: [PATCH] [reboot-cause]: Move reboot cause processing to its own service, 'process-reboot-cause' (#3102) --- .../build_templates/sonic_debian_extension.j2 | 5 ++ files/image_config/platform/rc.local | 32 ------- .../process-reboot-cause/process-reboot-cause | 89 +++++++++++++++++++ .../process-reboot-cause.service | 10 +++ 4 files changed, 104 insertions(+), 32 deletions(-) create mode 100755 files/image_config/process-reboot-cause/process-reboot-cause create mode 100644 files/image_config/process-reboot-cause/process-reboot-cause.service diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 5127c5bf6a..9c6e8a5532 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -220,6 +220,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 < $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) @@ -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 diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause new file mode 100755 index 0000000000..d75924f298 --- /dev/null +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -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() diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service new file mode 100644 index 0000000000..a429339dbe --- /dev/null +++ b/files/image_config/process-reboot-cause/process-reboot-cause.service @@ -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