Skip to content
Closed
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
25 changes: 25 additions & 0 deletions platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from .utils import extract_RJ45_ports_index
from . import utils
from .device_data import DeviceDataManager
import re
except ImportError as e:
raise ImportError (str(e) + "- required module not found")

Expand Down Expand Up @@ -61,6 +62,10 @@

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()

Expand Down Expand Up @@ -736,6 +741,18 @@ def initialize_reboot_cause(self):
self.reboot_by_software = 'reset_sw_reset'
self.reboot_cause_initialized = True

def _parse_warmfast_reboot_from_proc_cmdline(self):
if os.path.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 get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
Expand All @@ -748,6 +765,14 @@ def get_reboot_cause(self):
to pass a description of the reboot cause.
"""
#read reboot causes files in the following order

# 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, ''

if not self.reboot_cause_initialized:
self.initialize_reboot_cause()

Expand Down
29 changes: 29 additions & 0 deletions platform/mellanox/mlnx-platform-api/tests/test_chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,35 @@ def read_int_from_file(file_path, *args, **kwargs):
assert minor == value
mock_file_content[file_path] = 0

utils.is_host = mock.MagicMock(return_value=True)
chassis._parse_warmfast_reboot_from_proc_cmdline = mock.MagicMock(return_value='warm-reboot')
for key, value in chassis.reboot_major_cause_dict.items():
file_path = os.path.join(REBOOT_CAUSE_ROOT, key)
mock_file_content[file_path] = 1
major, minor = chassis.get_reboot_cause()
assert major == chassis.REBOOT_CAUSE_NON_HARDWARE
assert minor == ''
mock_file_content[file_path] = 0

for key, value in chassis.reboot_minor_cause_dict.items():
file_path = os.path.join(REBOOT_CAUSE_ROOT, key)
mock_file_content[file_path] = 1
major, minor = chassis.get_reboot_cause()
assert major == chassis.REBOOT_CAUSE_NON_HARDWARE
assert minor == value
mock_file_content[file_path] = 0

def test_parse_warmfast_reboot_from_proc_cmdline(self):
chassis = Chassis()
with mock.patch("builtins.open", mock.mock_open(read_data="SONIC_BOOT_TYPE=warm")):
assert chassis._parse_warmfast_reboot_from_proc_cmdline() == "warm-reboot"

with mock.patch("builtins.open", mock.mock_open(read_data="SONIC_BOOT_TYPE=fast")):
assert chassis._parse_warmfast_reboot_from_proc_cmdline() == "fast-reboot"

with mock.patch("builtins.open", mock.mock_open(read_data="SONIC_BOOT_TYPE=None")):
assert chassis._parse_warmfast_reboot_from_proc_cmdline() == None

def test_module(self):
from sonic_platform.chassis import ModularChassis
# Test get_num_modules, it should not create any SFP objects
Expand Down