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
98 changes: 97 additions & 1 deletion platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
"""

import os
import re
import fcntl
import array
import time
import subprocess

from sonic_platform_base.watchdog_base import WatchdogBase

Expand Down Expand Up @@ -233,6 +235,7 @@ def get_remaining_time(self):

return timeleft


class WatchdogType2(WatchdogImplBase):
"""
Watchdog type 2
Expand All @@ -241,6 +244,85 @@ class WatchdogType2(WatchdogImplBase):
pass


class WatchdogType3(WatchdogBase):
"""
Type 3 should support timeleft and maximum
timeout is 65535 sec.
This is temporary implementation, because
watchdog kernel driver haven't implemented support for
watchdog type 3 on recent CPLDs. Eventually this should be
removed and WatchdogImplBase which is based on linux
watchdog API should be sufficient.
"""

HW_MGMT_WD = "/usr/bin/hw-management-wd.sh"

def __init__(self):
""" initialize WatchdogType3 """

self._is_armed = False

def arm(self, timeout):
"""
Implements arm WatchdogBase API
"""

if timeout < 0:
return WD_COMMON_ERROR
proc = subprocess.Popen(
"{} start {}".format(self.HW_MGMT_WD, timeout).split(),
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if proc.returncode != 0:
return WD_COMMON_ERROR
self._is_armed = True
match = re.match(".* timeout ([0-9]+) .*", out)
if match is None:
raise Exception("unexpected output of {}".format(self.HW_MGMT_WD))
actual_timeout, = match.groups()
return int(actual_timeout)

def disarm(self):
"""
Implements disarm WatchdogBase API
"""

if not self._is_armed:
return False

proc = subprocess.Popen("{} stop".format(self.HW_MGMT_WD).split(),
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if proc.returncode != 0:
return WD_COMMON_ERROR
self._is_armed = False

return True

def is_armed(self):
""" Implements is_armed WatchdogBase API """

return self._is_armed

def get_remaining_time(self):
""" Implements get_remaining_time WatchdogBase API """

if not self._is_armed:
return WD_COMMON_ERROR

proc = subprocess.Popen("{} tleft".format(self.HW_MGMT_WD).split(),
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if proc.returncode != 0:
return WD_COMMON_ERROR
match = re.match(".* timeleft: ([0-9]+) .*", out)
if match is None:
raise Exception("unexpected {} output".format(self.HW_MGMT_WD))
tleft, = match.groups()

return int(tleft)


def is_mlnx_wd_main(dev):
"""
Checks if dev is Mellanox main watchdog
Expand All @@ -265,6 +347,17 @@ def is_wd_type2(dev):
return os.path.exists("{}/{}/timeleft".format(WD_SYSFS_PATH, dev))


def is_wd_type3(dev):
"""
Checks if dev is Mellanox type 3 watchdog
"""

proc = subprocess.Popen('{} help'.format(WatchdogType3.HW_MGMT_WD).split(),
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.communicate()
return proc.returncode == 0


def get_watchdog():
"""
Return WatchdogType1 or WatchdogType2 based on system
Expand All @@ -280,9 +373,12 @@ def get_watchdog():

watchdog = None

if is_wd_type2(watchdog_main_device_name):
if is_wd_type3(watchdog_main_device_name):
watchdog = WatchdogType3()
elif is_wd_type2(watchdog_main_device_name):
watchdog = WatchdogType2(watchdog_device_path)
else:
watchdog = WatchdogType1(watchdog_device_path)

return watchdog

8 changes: 8 additions & 0 deletions platform/mellanox/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,11 @@ $(SYNCD)_RDEPENDS += $(MLNX_SAI)

# Inject mlnx sdk libs to platform monitor
$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(APPLIBS) $(SX_COMPLIB) $(SXD_LIBS) $(SX_GEN_UTILS) $(PYTHON_SDK_API) $(APPLIBS_DEV) $(SX_COMPLIB_DEV) $(SXD_LIBS_DEV) $(SX_GEN_UTILS_DEV)

# W/A:
# Inject mlnx hw-management to platform monitor
# temporary change to include iorw utility and
# hw-managemnt-wd.sh for temporary WatchdogType3
# implementation. Please, refer to comment about
# WatchdogType3 in platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py
$(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(MLNX_HW_MANAGEMENT)