From a569bfc9ebeee4bc7df3df25c603684041b3a7c1 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 18 Jan 2023 05:21:31 +0800 Subject: [PATCH] skip hw reboot cause if warm/fast reboot found from the proc cmdline (#13378) #### Why I did it Backport https://github.com/sonic-net/sonic-buildimage/pull/13246 to 202012 branch. In case of warm/fast reboot, the hardware reboot cause will NOT be cleared because CPLD will not be touched in this flow. To not confuse the reboot cause determine logic, the leftover hardware reboot cause shall be skipped by the platform API, platform API will return the 'REBOOT_CAUSE_NON_HARDWARE' instead of the "hardware" reboot cause. #### How I did it Check the proc cmdline to see whether the last reboot is a warm or fast reboot, if yes skip checking the leftover hardware reboot cause. #### How to verify it a. Manual test: > 1. Perform a power loss > 2. Perform a warm/fast reboot > 3. check the reboot cause should be "warm-reboot" or "fast-reboot" instead of "power loss" b. Run reboot cause related regression test. --- .../sonic_platform/chassis.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 2d42673791..eb02b6359d 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -13,6 +13,7 @@ try: from sonic_py_common.logger import Logger from os import listdir from os.path import isfile, join + from . import utils import sys import io import re @@ -38,6 +39,10 @@ REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT REBOOT_CAUSE_FILE_LENGTH = 1 +REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" +REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*" +REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*" + # Global logger class instance logger = Logger() @@ -350,6 +355,17 @@ class Chassis(ChassisBase): ''' return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + def _parse_warmfast_reboot_from_proc_cmdline(self): + if isfile(REBOOT_TYPE_KEXEC_FILE): + with open(REBOOT_TYPE_KEXEC_FILE) as cause_file: + cause_file_kexec = cause_file.readline() + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) + if m and m.group(1): + return 'warm-reboot' + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) + if m and m.group(1): + return 'fast-reboot' + return None def initialize_reboot_cause(self): self.reboot_major_cause_dict = { @@ -388,6 +404,13 @@ class Chassis(ChassisBase): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ + # To avoid the leftover hardware reboot cause confusing the reboot cause determine service + # Skip the hardware reboot cause check if warm/fast reboot cause found from cmdline + if utils.is_host(): + reboot_cause = self._parse_warmfast_reboot_from_proc_cmdline() + if reboot_cause: + return self.REBOOT_CAUSE_NON_HARDWARE, '' + #read reboot causes files in the following order if not self.reboot_cause_initialized: self.initialize_reboot_cause()