-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[process-reboot-cause]Address the issue: Incorrect reboot cause returned when warm reboot follows a hardware caused reboot #3880
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
Changes from 2 commits
66a9a25
757d82b
70a7df1
0ea7089
8fb11e3
f37d08d
00603a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ try: | |
| import pwd | ||
| import sys | ||
| import syslog | ||
| import re | ||
| except ImportError as err: | ||
| raise ImportError("%s - required module not found" % str(err)) | ||
|
|
||
|
|
@@ -22,6 +23,9 @@ 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" | ||
| FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" | ||
| REBOOT_CAUSE_KEXEC = "/proc/cmdline" | ||
| # The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities | ||
| REBOOT_CAUSE_KEXEC_PATTERN = ".*SONIC_BOOT_TYPE=(fast-reboot|warm|fastfast)$" | ||
|
||
|
|
||
| UNKNOWN_REBOOT_CAUSE = "Unknown" | ||
|
|
||
|
|
@@ -47,6 +51,16 @@ def log_error(msg): | |
|
|
||
|
|
||
| # ============================= Functions ============================= | ||
| def is_warmfast_reboot_from_proc_cmdline(): | ||
| if os.path.isfile(REBOOT_CAUSE_KEXEC): | ||
| cause_file = open(REBOOT_CAUSE_KEXEC, "r") | ||
|
||
| cause_file_kexec = cause_file.readline() | ||
| m = re.match(REBOOT_CAUSE_KEXEC_PATTERN, cause_file_kexec) | ||
| if m and m.group(1): | ||
| # the pattern matched so it's a fast/warm reboot | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def main(): | ||
| log_info("Starting up...") | ||
|
|
@@ -73,31 +87,49 @@ def main(): | |
| try: | ||
| import sonic_platform | ||
|
|
||
| # Check if the previous reboot was caused by hardware | ||
| platform = sonic_platform.platform.Platform() | ||
|
|
||
| chassis = platform.get_chassis() | ||
| proc_cmdline_reboot_cause = None | ||
|
|
||
| hardware_reboot_cause, optional_details = chassis.get_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. | ||
| # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline | ||
| # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause | ||
| if is_warmfast_reboot_from_proc_cmdline(): | ||
| if os.path.isfile(REBOOT_CAUSE_FILE): | ||
| cause_file = open(REBOOT_CAUSE_FILE, "r") | ||
| previous_reboot_cause = cause_file.readline().rstrip('\n') | ||
| proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n') | ||
| cause_file.close() | ||
| # If it is FirstTime Boot and previous_reboot_cause is unknown | ||
| # and hardware_reboot cause is non_hardware then | ||
| # Update the reboot cause as required | ||
| if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): | ||
| if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): | ||
| previous_reboot_cause = UNKNOWN_REBOOT_CAUSE | ||
| os.remove(FIRST_BOOT_PLATFORM_FILE) | ||
| elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: | ||
| previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) | ||
| else: | ||
| # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist. | ||
| # report an error. | ||
| log_error("/proc/cmdline indicates a fast/warm reboot but {} doesn't exist".format(REBOOT_CAUSE_DIR)) | ||
yxieca marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if proc_cmdline_reboot_cause is not None: | ||
| previous_reboot_cause = proc_cmdline_reboot_cause | ||
| else: | ||
| previous_reboot_cause = hardware_reboot_cause | ||
| # 2. Check if the previous reboot was caused by hardware | ||
| # If yes, the hardware reboot cause will be treated as teh reboot cause | ||
|
||
| platform = sonic_platform.platform.Platform() | ||
|
|
||
| chassis = platform.get_chassis() | ||
|
|
||
| hardware_reboot_cause, optional_details = chassis.get_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() | ||
| # If it is FirstTime Boot and previous_reboot_cause is unknown | ||
| # and hardware_reboot cause is non_hardware then | ||
| # Update the reboot cause as required | ||
| if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): | ||
| if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE): | ||
| previous_reboot_cause = UNKNOWN_REBOOT_CAUSE | ||
| os.remove(FIRST_BOOT_PLATFORM_FILE) | ||
|
||
| 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 | ||
| except ImportError as err: | ||
| log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.