From 7c512f334679a489431482eb45c07ae3ed41be81 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Wed, 8 Jul 2020 11:24:47 -0700 Subject: [PATCH] Add watchdogutil to control the hw watchdog (#945) * Add watchdogutil to control the hw watchdog * fix LGTM * Fixed based on review comments * replace the is_armed() and get_remaining_time to status() subcommand * syntax error * Add more info to the output * re-format of output * remove spaces * change the version number of watchdogutil * Change the output parsing for the watchdog arm case * typo * fix more review comments --- setup.py | 2 + watchdogutil/__init__.py | 0 watchdogutil/main.py | 137 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 watchdogutil/__init__.py create mode 100644 watchdogutil/main.py diff --git a/setup.py b/setup.py index 8bccb843f1d0..38090071b073 100644 --- a/setup.py +++ b/setup.py @@ -53,6 +53,7 @@ 'sonic-utilities-tests', 'undebug', 'utilities_common', + 'watchdogutil', ], package_data={ 'show': ['aliases.ini'], @@ -136,6 +137,7 @@ 'sonic-clear = clear.main:cli', 'sonic_installer = sonic_installer.main:cli', 'undebug = undebug.main:cli', + 'watchdogutil = watchdogutil.main:watchdogutil', ] }, # NOTE: sonic-utilities also depends on other packages that are either only diff --git a/watchdogutil/__init__.py b/watchdogutil/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/watchdogutil/main.py b/watchdogutil/main.py new file mode 100644 index 000000000000..df0f72c78015 --- /dev/null +++ b/watchdogutil/main.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# +# main.py +# +# Command-line utility for interacting with HW Watchdog in SONiC +# + +try: + import sys + import os + import click + import syslog + import sonic_platform +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + +VERSION = "1.0" + +SYSLOG_IDENTIFIER = "watchdogutil" + +WATCHDOG_LOAD_ERROR = -1 +CHASSIS_LOAD_ERROR = -2 + +# Global platform-specific watchdog class instance +platform_watchdog = None + + +# ========================== Syslog wrappers ========================== + + +def log_info(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_INFO, msg) + syslog.closelog() + + if also_print_to_console: + click.echo(msg) + + +def log_warning(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_WARNING, msg) + syslog.closelog() + + if also_print_to_console: + click.echo(msg) + + +def log_error(msg, also_print_to_console=False): + syslog.openlog(SYSLOG_IDENTIFIER) + syslog.syslog(syslog.LOG_ERR, msg) + syslog.closelog() + + if also_print_to_console: + click.echo(msg) + + +# ==================== Methods for initialization ==================== + +# Loads platform specific watchdog module from source +def load_platform_watchdog(): + global platform_watchdog + + platform = sonic_platform.platform.Platform() + + chassis = platform.get_chassis() + if not chassis: + log_error("Failed to get chassis") + return CHASSIS_LOAD_ERROR + + platform_watchdog = chassis.get_watchdog() + if not platform_watchdog: + log_error("Failed to get watchdog module") + return WATCHDOG_LOAD_ERROR + + return 0 + + +# ==================== CLI commands and groups ==================== + + +# This is our main entrypoint - the main 'watchdogutil' command +@click.group() +def watchdogutil(): + """watchdogutil - Command line utility for providing HW watchdog interface""" + + if os.geteuid() != 0: + click.echo("Root privileges are required for this operation") + sys.exit(1) + + # Load platform-specific watchdog class + err = load_platform_watchdog() + if err != 0: + sys.exit(2) + +# 'version' subcommand +@watchdogutil.command() +def version(): + """Display version info""" + click.echo("watchdogutil version {0}".format(VERSION)) + +# 'status' subcommand +@watchdogutil.command() +def status(): + """Check the watchdog status with remaining_time if it's armed""" + status = platform_watchdog.is_armed() + remaining_time = platform_watchdog.get_remaining_time() + if status is True: + click.echo("Status: Armed") + click.echo("Time remaining: {} seconds".format(remaining_time)) + else: + click.echo("Status: Unarmed") + + +# 'disarm' subcommand +@watchdogutil.command() +def disarm(): + """Disarm HW watchdog""" + result = platform_watchdog.disarm() + if result is True: + click.echo("Watchdog disarmed successfully") + else: + click.echo("Failed to disarm Watchdog") + +# 'arm' subcommand +@watchdogutil.command() +@click.option('-s', '--seconds', default=180, type=int, help="the default timeout of HW watchdog") +def arm(seconds): + """Arm HW watchdog""" + result = int(platform_watchdog.arm(seconds)) + if result < 0: + click.echo("Failed to arm Watchdog for {} seconds".format(seconds)) + else: + click.echo("Watchdog armed for {} seconds".format(result)) + +if __name__ == '__main__': + watchdogutil()