From 2b54fc8a512933f2c45f2e8260dc3413f348b389 Mon Sep 17 00:00:00 2001 From: junchao Date: Tue, 20 Jul 2021 13:52:13 +0800 Subject: [PATCH] [Mellanox] Add a trigger to set LED to blink --- .../mlnx-platform-api/sonic_platform/led.py | 206 ++++++++---------- 1 file changed, 88 insertions(+), 118 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py index d67cbb1d9557..d9f31aa1a352 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/led.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/led.py @@ -1,4 +1,6 @@ import os +import time +from . import utils class Led(object): @@ -10,7 +12,7 @@ class Led(object): STATUS_LED_COLOR_ORANGE_BLINK = 'orange_blink' STATUS_LED_COLOR_OFF = 'off' - LED_ON = '1' + LED_ON = '255' LED_OFF = '0' LED_BLINK = '50' @@ -26,12 +28,11 @@ def set_status(self, color): self._stop_blink(led_cap_list) blink_pos = color.find('blink') if blink_pos != -1: - return self._set_status_blink(color, blink_pos, led_cap_list) + return self._set_status_blink(color, led_cap_list) if color == Led.STATUS_LED_COLOR_GREEN: - with open(self.get_green_led_path(), 'w') as led: - led.write(Led.LED_ON) - status = True + utils.write_file(self.get_green_led_path(), Led.LED_ON) + status = True elif color == Led.STATUS_LED_COLOR_RED: # Some led don't support red led but support orange led, in this case we set led to orange if Led.STATUS_LED_COLOR_RED in led_cap_list: @@ -41,19 +42,15 @@ def set_status(self, color): else: return False - with open(led_path, 'w') as led: - led.write(Led.LED_ON) - status = True + utils.write_file(led_path, Led.LED_ON) + status = True elif color == Led.STATUS_LED_COLOR_OFF: if Led.STATUS_LED_COLOR_GREEN in led_cap_list: - with open(self.get_green_led_path(), 'w') as led: - led.write(Led.LED_OFF) + utils.write_file(self.get_green_led_path(), Led.LED_OFF) if Led.STATUS_LED_COLOR_RED in led_cap_list: - with open(self.get_red_led_path(), 'w') as led: - led.write(Led.LED_OFF) + utils.write_file(self.get_red_led_path(), Led.LED_OFF) if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(self.get_orange_led_path(), 'w') as led: - led.write(Led.LED_OFF) + utils.write_file(self.get_orange_led_path(), Led.LED_OFF) status = True else: @@ -63,7 +60,7 @@ def set_status(self, color): return status - def _set_status_blink(self, color, blink_pos, led_cap_list): + def _set_status_blink(self, color, led_cap_list): if color not in led_cap_list: if color == Led.STATUS_LED_COLOR_RED_BLINK and Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: color = Led.STATUS_LED_COLOR_ORANGE_BLINK @@ -73,32 +70,60 @@ def _set_status_blink(self, color, blink_pos, led_cap_list): return False if Led.STATUS_LED_COLOR_GREEN_BLINK == color: - self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_BLINK) + self._trigger_blink(self.get_green_led_trigger()) + return self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_BLINK) elif Led.STATUS_LED_COLOR_RED_BLINK == color: - self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_BLINK) + self._trigger_blink(self.get_red_led_trigger()) + return self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_BLINK) elif Led.STATUS_LED_COLOR_ORANGE_BLINK == color: - self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_BLINK) + self._trigger_blink(self.get_orange_led_trigger()) + return self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_BLINK) else: return False - return True - def _stop_blink(self, led_cap_list): try: if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: - self._set_led_blink_status(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path(), Led.LED_OFF) + self._untrigger_blink(self.get_green_led_trigger()) if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: - self._set_led_blink_status(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path(), Led.LED_OFF) + self._untrigger_blink(self.get_red_led_trigger()) if Led.STATUS_LED_COLOR_ORANGE_BLINK in led_cap_list: - self._set_led_blink_status(self.get_orange_led_delay_on_path(), self.get_orange_led_delay_off_path(), Led.LED_OFF) + self._untrigger_blink(self.get_orange_led_trigger()) except Exception as e: return + def _trigger_blink(self, blink_trigger_file): + utils.write_file(blink_trigger_file, 'timer') + + def _untrigger_blink(self, blink_trigger_file): + utils.write_file(blink_trigger_file, 'none') + def _set_led_blink_status(self, delay_on_file, delay_off_file, value): - with open(delay_on_file, 'w') as led: - led.write(value) - with open(delay_off_file, 'w') as led: - led.write(value) + if not self._wait_files_ready((delay_on_file, delay_off_file)): + return False + + utils.write_file(delay_on_file, value) + utils.write_file(delay_off_file, value) + return True + + def _wait_files_ready(self, file_list): + """delay_off and delay_on sysfs will be available only if _trigger_blink is called. And once + _trigger_blink is called, driver might need time to prepare delay_off and delay_on. So, + need wait a few seconds here to make sure the sysfs is ready + + Args: + file_list (list of str): files to be checked + """ + wait_time = 5.0 + initial_sleep = 0.01 + while wait_time > 0: + if all([os.path.exists(x) for x in file_list]): + return True + time.sleep(initial_sleep) + wait_time -= initial_sleep + initial_sleep = initial_sleep * 2 + + return False def get_status(self): led_cap_list = self.get_capability() @@ -110,18 +135,15 @@ def get_status(self): if blink_status is not None: return blink_status - with open(self.get_green_led_path(), 'r') as led: - if Led.LED_OFF != led.read().rstrip('\n'): - return Led.STATUS_LED_COLOR_GREEN + if utils.read_str_from_file(self.get_green_led_path()) != Led.LED_OFF: + return Led.STATUS_LED_COLOR_GREEN if Led.STATUS_LED_COLOR_RED in led_cap_list: - with open(self.get_red_led_path(), 'r') as led: - if Led.LED_OFF != led.read().rstrip('\n'): - return Led.STATUS_LED_COLOR_RED + if utils.read_str_from_file(self.get_red_led_path()) != Led.LED_OFF: + return Led.STATUS_LED_COLOR_RED if Led.STATUS_LED_COLOR_ORANGE in led_cap_list: - with open(self.get_orange_led_path(), 'r') as led: - if Led.LED_OFF != led.read().rstrip('\n'): - return Led.STATUS_LED_COLOR_RED + if utils.read_str_from_file(self.get_orange_led_path()) != Led.LED_OFF: + return Led.STATUS_LED_COLOR_RED except (ValueError, IOError) as e: raise RuntimeError("Failed to read led status due to {}".format(repr(e))) @@ -132,6 +154,7 @@ def _get_blink_status(self, led_cap_list): if Led.STATUS_LED_COLOR_GREEN_BLINK in led_cap_list: if self._is_led_blinking(self.get_green_led_delay_on_path(), self.get_green_led_delay_off_path()): return Led.STATUS_LED_COLOR_GREEN_BLINK + if Led.STATUS_LED_COLOR_RED_BLINK in led_cap_list: if self._is_led_blinking(self.get_red_led_delay_on_path(), self.get_red_led_delay_off_path()): return Led.STATUS_LED_COLOR_RED_BLINK @@ -144,126 +167,73 @@ def _get_blink_status(self, led_cap_list): return None def _is_led_blinking(self, delay_on_file, delay_off_file): - with open(delay_on_file, 'r') as led: - delay_on = led.read().rstrip('\n') - with open(delay_off_file, 'r') as led: - delay_off = led.read().rstrip('\n') + delay_on = utils.read_str_from_file(delay_on_file, default=Led.LED_OFF) + delay_off = utils.read_str_from_file(delay_off_file, default=Led.LED_OFF) return delay_on != Led.LED_OFF and delay_off != Led.LED_OFF def get_capability(self): - cap_list = None - try: - with open(self.get_led_cap_path(), 'r') as led_cap: - caps = led_cap.read() - cap_list = set(caps.split()) - except (ValueError, IOError): - pass - - return cap_list + caps = utils.read_str_from_file(self.get_led_cap_path()) + return set(caps.split()) def get_green_led_path(self): - pass + return os.path.join(Led.LED_PATH, 'led_{}_green'.format(self._led_id)) def get_green_led_delay_off_path(self): - return '{}_delay_off'.format(self.get_green_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_green_delay_off'.format(self._led_id)) def get_green_led_delay_on_path(self): - return '{}_delay_on'.format(self.get_green_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_green_delay_on'.format(self._led_id)) + + def get_green_led_trigger(self): + return os.path.join(Led.LED_PATH, 'led_{}_green_trigger'.format(self._led_id)) def get_red_led_path(self): - pass + return os.path.join(Led.LED_PATH, 'led_{}_red'.format(self._led_id)) def get_red_led_delay_off_path(self): - return '{}_delay_off'.format(self.get_red_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_red_delay_off'.format(self._led_id)) def get_red_led_delay_on_path(self): - return '{}_delay_on'.format(self.get_red_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_red_delay_on'.format(self._led_id)) + + def get_red_led_trigger(self): + return os.path.join(Led.LED_PATH, 'led_{}_red_trigger'.format(self._led_id)) def get_orange_led_path(self): - pass + return os.path.join(Led.LED_PATH, 'led_{}_orange'.format(self._led_id)) def get_orange_led_delay_off_path(self): - return '{}_delay_off'.format(self.get_orange_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_orange_delay_off'.format(self._led_id)) def get_orange_led_delay_on_path(self): - return '{}_delay_on'.format(self.get_orange_led_path()) + return os.path.join(Led.LED_PATH, 'led_{}_orange_delay_on'.format(self._led_id)) + + def get_orange_led_trigger(self): + return os.path.join(Led.LED_PATH, 'led_{}_orange_trigger'.format(self._led_id)) def get_led_cap_path(self): - pass + return os.path.join(Led.LED_PATH, 'led_{}_capability'.format(self._led_id)) - -class FanLed(Led): - LED_PATH = "/var/run/hw-management/led/" +class FanLed(Led): def __init__(self, index): if index is not None: - self._green_led_path = os.path.join(Led.LED_PATH, "led_fan{}_green".format(index)) - self._red_led_path = os.path.join(Led.LED_PATH, "led_fan{}_red".format(index)) - self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan{}_orange".format(index)) - self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan{}_capability".format(index)) + self._led_id = 'fan{}'.format(index) else: - self._green_led_path = os.path.join(Led.LED_PATH, "led_fan_green") - self._red_led_path = os.path.join(Led.LED_PATH, "led_fan_red") - self._orange_led_path = os.path.join(Led.LED_PATH, "led_fan_orange") - self._led_cap_path = os.path.join(Led.LED_PATH, "led_fan_capability") - - def get_green_led_path(self): - return self._green_led_path - - def get_red_led_path(self): - return self._red_led_path - - def get_orange_led_path(self): - return self._orange_led_path - - def get_led_cap_path(self): - return self._led_cap_path + self._led_id = 'fan' class PsuLed(Led): def __init__(self, index): if index is not None: - self._green_led_path = os.path.join(Led.LED_PATH, "led_psu{}_green".format(index)) - self._red_led_path = os.path.join(Led.LED_PATH, "led_psu{}_red".format(index)) - self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu{}_orange".format(index)) - self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu{}_capability".format(index)) + self._led_id = 'psu{}'.format(index) else: - self._green_led_path = os.path.join(Led.LED_PATH, "led_psu_green") - self._red_led_path = os.path.join(Led.LED_PATH, "led_psu_red") - self._orange_led_path = os.path.join(Led.LED_PATH, "led_psu_orange") - self._led_cap_path = os.path.join(Led.LED_PATH, "led_psu_capability") - - def get_green_led_path(self): - return self._green_led_path - - def get_red_led_path(self): - return self._red_led_path - - def get_orange_led_path(self): - return self._orange_led_path - - def get_led_cap_path(self): - return self._led_cap_path + self._led_id = 'psu' class SystemLed(Led): def __init__(self): - self._green_led_path = os.path.join(Led.LED_PATH, "led_status_green") - self._red_led_path = os.path.join(Led.LED_PATH, "led_status_red") - self._orange_led_path = os.path.join(Led.LED_PATH, "led_status_orange") - self._led_cap_path = os.path.join(Led.LED_PATH, "led_status_capability") - - def get_green_led_path(self): - return self._green_led_path - - def get_red_led_path(self): - return self._red_led_path - - def get_orange_led_path(self): - return self._orange_led_path - - def get_led_cap_path(self): - return self._led_cap_path + self._led_id = 'status' class SharedLed(object):