From c183ce8c6fef0179cb4c1ae4ff2baa62ebf24822 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Sun, 14 Jul 2019 10:04:51 +0300 Subject: [PATCH 1/8] install new platform api on host --- files/build_templates/sonic_debian_extension.j2 | 6 ++++++ platform/mellanox/mlnx-platform-api.mk | 1 + 2 files changed, 7 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 7dfd6dadb673..98f0d0c5bbe3 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -343,6 +343,12 @@ sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh + +# Install mlnx-sonic-platform-common Python 2 package +MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME=$(basename {{mlnx_platform_api_py2_wheel_path}}) +sudo cp {{mlnx_platform_api_py2_wheel_path}} $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$MLNX_PLATFORM_COMMON_PY2_WHEEL_NAME {% endif %} {%- if SONIC_ROUTING_STACK == "frr" %} diff --git a/platform/mellanox/mlnx-platform-api.mk b/platform/mellanox/mlnx-platform-api.mk index 98a57d0090ed..4b70e59debc1 100644 --- a/platform/mellanox/mlnx-platform-api.mk +++ b/platform/mellanox/mlnx-platform-api.mk @@ -5,3 +5,4 @@ $(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/mlnx-platform-api $(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) +export mlnx_platform_api_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2))" From 235e7922641016f206acee31047e9c3f480fdb02 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Mon, 15 Jul 2019 13:35:02 +0300 Subject: [PATCH 2/8] 1. install necessary dependencys of chassis api on host, like sonic-daemon-base 2. remove dependency on the modules not feasible to install on host, like swsscomm, sdk, etc. --- .../build_templates/sonic_debian_extension.j2 | 6 ++ .../sonic_platform/chassis_host.py | 100 ++++++++++++++++++ .../sonic_platform/platform.py | 23 ++++ rules/sonic-daemon-base.mk | 1 + .../sonic_daemon_base/daemon_base.py | 7 +- 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py create mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/platform.py diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 98f0d0c5bbe3..ef9721346708 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -102,6 +102,12 @@ sudo cp {{platform_common_py2_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2 sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $PLATFORM_COMMON_PY2_WHEEL_NAME sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY2_WHEEL_NAME +# Install sonic-daemon-base Python 2 package +DAEMON_BASE_PY2_WHEEL_NAME=$(basename {{daemon_base_py2_wheel_path}}) +sudo cp {{daemon_base_py2_wheel_path}} $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install $DAEMON_BASE_PY2_WHEEL_NAME +sudo rm -rf $FILESYSTEM_ROOT/$DAEMON_BASE_PY2_WHEEL_NAME + # Install built Python Click package (and its dependencies via 'apt-get -y install -f') # Do this before installing sonic-utilities so that it doesn't attempt to install # an older version as part of its dependencies diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py new file mode 100644 index 000000000000..9e6c62935364 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.watchdog import get_watchdog + from sonic_daemon_base.daemon_base import Logger + from os import listdir + from os.path import isfile, join + import io + import syslog +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +HWMGMT_SYSTEM_ROOT = '/var/run/hw-management/system/' + +#reboot cause related definitions +REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT + +REBOOT_CAUSE_POWER_LOSS_FILE = 'reset_main_pwr_fail' +REBOOT_CAUSE_AUX_POWER_LOSS_FILE = 'reset_aux_pwr_or_ref' +REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE = 'reset_asic_thermal' +REBOOT_CAUSE_WATCHDOG_FILE = 'reset_hotswap_or_wd' +REBOOT_CAUSE_MLNX_FIRMWARE_RESET = 'reset_fw_reset' + +REBOOT_CAUSE_FILE_LENGTH = 1 + +# Global logger class instance +SYSLOG_IDENTIFIER = "mlnx-chassis" +logger = Logger(SYSLOG_IDENTIFIER) + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + super(Chassis, self).__init__() + + # Initialize watchdog + self._watchdog = get_watchdog() + + def _read_generic_file(self, filename, len): + """ + Read a generic file, returns the contents of the file + """ + result = '' + try: + fileobj = io.open(filename) + result = fileobj.read(len) + fileobj.close() + return result + except: + logger.log_warning("Fail to read file {}, maybe it doesn't exist".format(filename)) + return '' + + def _verify_reboot_cause(self, filename): + ''' + Open and read the reboot cause file in + /var/run/hwmanagement/system (which is defined as REBOOT_CAUSE_ROOT) + If a reboot cause file doesn't exists, returns '0'. + ''' + return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + # read reboot causes files in the following order + minor_cause = '' + if self._verify_reboot_cause(REBOOT_CAUSE_POWER_LOSS_FILE): + major_cause = self.REBOOT_CAUSE_POWER_LOSS + elif self._verify_reboot_cause(REBOOT_CAUSE_AUX_POWER_LOSS_FILE): + major_cause = self.REBOOT_CAUSE_POWER_LOSS + elif self._verify_reboot_cause(REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE): + major_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC + elif self._verify_reboot_cause(REBOOT_CAUSE_WATCHDOG_FILE): + major_cause = self.REBOOT_CAUSE_WATCHDOG + else: + major_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + if self._verify_reboot_cause(REBOOT_CAUSE_MLNX_FIRMWARE_RESET): + minor_cause = "Reset by ASIC firmware" + else: + major_cause = self.REBOOT_CAUSE_NON_HARDWARE + + return major_cause, minor_cause diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py new file mode 100644 index 000000000000..2ef67907e02a --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Mellanox +# +# implementation of new platform api +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase +# from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +class Platform(PlatformBase): + def __init__(self, daemon = None): + PlatformBase.__init__(self) + if daemon is None: + from sonic_platform.chassis_host import Chassis + self._chassis = Chassis() + else: + from sonic_platform.chassis import Chassis + self._chassis = Chassis() diff --git a/rules/sonic-daemon-base.mk b/rules/sonic-daemon-base.mk index dad0900e75ca..5385c18f1f12 100644 --- a/rules/sonic-daemon-base.mk +++ b/rules/sonic-daemon-base.mk @@ -5,3 +5,4 @@ $(SONIC_DAEMON_BASE_PY2)_SRC_PATH = $(SRC_PATH)/sonic-daemon-base $(SONIC_DAEMON_BASE_PY2)_PYTHON_VERSION = 2 SONIC_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY2) +export daemon_base_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_DAEMON_BASE_PY2))" diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index 4f26806f4f11..443303882acf 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -7,7 +7,6 @@ import os import sys import syslog - from swsscommon import swsscommon except ImportError, e: raise ImportError (str(e) + " - required module not found") @@ -38,6 +37,7 @@ # def db_connect(db): + from swsscommon import swsscommon return swsscommon.DBConnector(db, REDIS_HOSTNAME, REDIS_PORT, @@ -89,6 +89,11 @@ def log_debug(self, msg, also_print_to_console=False): # class DaemonBase(object): + + DAEMON_WATCHDOG = "watch-dog" + DAEMON_SYSEEPROM = "syseepromd" + DAEMON_XCVRD = "xcvrd" + DAEMON_PSUD = "psud" def __init__(self): # Register our signal handlers signal.signal(signal.SIGHUP, self.signal_handler) From 69168ca4c61e6f4864723445043001000d1de7ad Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 17 Jul 2019 01:39:15 +0300 Subject: [PATCH 3/8] add dependency on SONIC_PLATFORM_API_PY2 for SONIC_INSTALLERS --- slave.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/slave.mk b/slave.mk index 925cad3b3236..b8a5ce711c29 100644 --- a/slave.mk +++ b/slave.mk @@ -598,7 +598,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2)) \ + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_API_PY2)) $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms export debs_path="$(STRETCH_DEBS_PATH)" From 0e46276bcdaf032a2d5d21edfe8e9f4ec3d5d5b0 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 17 Jul 2019 10:17:42 +0300 Subject: [PATCH 4/8] fix type in process-reboot-cause --- files/image_config/process-reboot-cause/process-reboot-cause | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 0d5ae78137fa..2e152c699ce7 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -70,7 +70,7 @@ def main(): # if there is no sonic_platform package installed, we only provide # software-related reboot causes. try: - import sonic_platform + import sonic_platform.platform # Check if the previous reboot was caused by hardware platform = sonic_platform.platform.Platform() From a45d957600f59150a2c328a34c376fbebc520e34 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Wed, 17 Jul 2019 10:19:26 +0300 Subject: [PATCH 5/8] fix the issue "'NoneType' object has no attribute 'closelog'" which results from referencing an already destroyed global variable when destructuring daemon_base.Logger by introducing a class member to represent the global --- .../sonic_daemon_base/daemon_base.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index 443303882acf..b762c1b02fe4 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -6,7 +6,6 @@ import subprocess import os import sys - import syslog except ImportError, e: raise ImportError (str(e) + " - required module not found") @@ -49,37 +48,39 @@ def db_connect(db): class Logger(object): def __init__(self, syslog_identifier): - syslog.openlog(ident=syslog_identifier, logoption=syslog.LOG_NDELAY, facility=syslog.LOG_DAEMON) + import syslog + self.syslog = syslog + self.syslog.openlog(ident=syslog_identifier, logoption=self.syslog.LOG_NDELAY, facility=self.syslog.LOG_DAEMON) def __del__(self): - syslog.closelog() + self.syslog.closelog() def log_error(self, msg, also_print_to_console=False): - syslog.syslog(syslog.LOG_ERR, msg) + self.syslog.syslog(self.syslog.LOG_ERR, msg) if also_print_to_console: print msg def log_warning(self, msg, also_print_to_console=False): - syslog.syslog(syslog.LOG_WARNING, msg) + self.syslog.syslog(self.syslog.LOG_WARNING, msg) if also_print_to_console: print msg def log_notice(self, msg, also_print_to_console=False): - syslog.syslog(syslog.LOG_NOTICE, msg) + self.syslog.syslog(self.syslog.LOG_NOTICE, msg) if also_print_to_console: print msg def log_info(self, msg, also_print_to_console=False): - syslog.syslog(syslog.LOG_INFO, msg) + self.syslog.syslog(self.syslog.LOG_INFO, msg) if also_print_to_console: print msg def log_debug(self, msg, also_print_to_console=False): - syslog.syslog(syslog.LOG_DEBUG, msg) + self.syslog.syslog(self.syslog.LOG_DEBUG, msg) if also_print_to_console: print msg @@ -103,15 +104,15 @@ def __init__(self): # Signal handler def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...") + self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...") + self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...") + self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") + self.syslog.syslog(self.syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") # Returns platform and hwsku def get_platform_and_hwsku(self): From ca90b7a24109d9497409e4961c789603c1501ebd Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Thu, 18 Jul 2019 03:24:59 +0300 Subject: [PATCH 6/8] enhance the reboot cause by supporting aux power failure, long/short push on power button --- .../mlnx-platform-api/sonic_platform/chassis.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index f9875a296d35..7c0b81c4a7d4 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -41,9 +41,12 @@ REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT REBOOT_CAUSE_POWER_LOSS_FILE = 'reset_main_pwr_fail' +REBOOT_CAUSE_AUX_POWER_LOSS_FILE = 'reset_aux_pwr_or_ref' REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE = 'reset_asic_thermal' REBOOT_CAUSE_WATCHDOG_FILE = 'reset_hotswap_or_wd' REBOOT_CAUSE_MLNX_FIRMWARE_RESET = 'reset_fw_reset' +REBOOT_CAUSE_LONG_PB = 'reset_long_pb' +REBOOT_CAUSE_SHORT_PB = 'reset_short_pb' REBOOT_CAUSE_FILE_LENGTH = 1 @@ -193,7 +196,10 @@ def _verify_reboot_cause(self, filename): /var/run/hwmanagement/system (which is defined as REBOOT_CAUSE_ROOT) If a reboot cause file doesn't exists, returns '0'. ''' - return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + try: + return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) + except: + return False def get_reboot_cause(self): """ @@ -210,6 +216,8 @@ def get_reboot_cause(self): minor_cause = '' if self._verify_reboot_cause(REBOOT_CAUSE_POWER_LOSS_FILE): major_cause = self.REBOOT_CAUSE_POWER_LOSS + elif self._verify_reboot_cause(REBOOT_CAUSE_AUX_POWER_LOSS_FILE): + major_cause = self.REBOOT_CAUSE_POWER_LOSS elif self._verify_reboot_cause(REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE): major_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC elif self._verify_reboot_cause(REBOOT_CAUSE_WATCHDOG_FILE): @@ -218,9 +226,12 @@ def get_reboot_cause(self): major_cause = self.REBOOT_CAUSE_HARDWARE_OTHER if self._verify_reboot_cause(REBOOT_CAUSE_MLNX_FIRMWARE_RESET): minor_cause = "Reset by ASIC firmware" + elif self._verify_reboot_cause(REBOOT_CAUSE_LONG_PB): + minor_cause = "Reset by long press on power button" + elif self._verify_reboot_cause(REBOOT_CAUSE_SHORT_PB): + minor_cause = "Reset by short press on power button" else: major_cause = self.REBOOT_CAUSE_NON_HARDWARE - return major_cause, minor_cause def _get_cpld_version(self, version_file): From 18e271769ad96baa59dcec13596b90de7b3dfa6b Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Thu, 18 Jul 2019 06:30:26 +0300 Subject: [PATCH 7/8] optimize chassis's initialization by 1. removing iniaializations of varient components out from constructor and providing one initializer for each. 2. only import other modules when initializing it. by doing so, initializing time is reduced and unnecessary dependencies of chassis is removed for daemons who don't need them. --- .../sonic_platform/chassis.py | 29 +++-- .../sonic_platform/chassis_host.py | 100 ------------------ .../sonic_platform/platform.py | 10 +- 3 files changed, 28 insertions(+), 111 deletions(-) delete mode 100644 platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 7c0b81c4a7d4..9e50c9347bc8 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -12,13 +12,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.psu import Psu - from sonic_platform.fan import Fan - from sonic_platform.fan import FAN_PATH - from sonic_platform.sfp import SFP - from sonic_platform.watchdog import get_watchdog from sonic_daemon_base.daemon_base import Logger - from eeprom import Eeprom from os import listdir from os.path import isfile, join import io @@ -81,14 +75,27 @@ class Chassis(ChassisBase): def __init__(self): super(Chassis, self).__init__() + # move the initialization of each components to their dedicated initializer + # which will be called from platform + + def initialize_psu(self): + from sonic_platform.psu import Psu # Initialize PSU list + self.psu_module = Psu for index in range(MLNX_NUM_PSU): psu = Psu(index) self._psu_list.append(psu) + def initialize_watchdog(self): + from sonic_platform.watchdog import get_watchdog # Initialize watchdog self._watchdog = get_watchdog() + def initialize_fan(self): + from sonic_platform.fan import Fan + from sonic_platform.fan import FAN_PATH + self.fan_module = Fan + self.fan_path = FAN_PATH # Initialize FAN list multi_rotor_in_drawer = False num_of_fan, num_of_drawer = self._extract_num_of_fans_and_fan_drawers() @@ -101,6 +108,9 @@ def __init__(self): fan = Fan(index, index) self._fan_list.append(fan) + def initialize_sfp(self): + from sonic_platform.sfp import SFP + self.sfp_module = SFP # Initialize SFP list port_position_tuple = self._get_port_position_tuple_by_sku_name() self.PORT_START = port_position_tuple[0] @@ -115,9 +125,12 @@ def __init__(self): sfp_module = SFP(index, 'SFP') self._sfp_list.append(sfp_module) + def initialize_eeprom(self): + from eeprom import Eeprom # Initialize EEPROM self.eeprom = Eeprom() + def initialize_components_list(self): # Initialize component list self._component_name_list.append(COMPONENT_BIOS) self._component_name_list.append(COMPONENT_FIRMWARE) @@ -127,8 +140,8 @@ def __init__(self): def _extract_num_of_fans_and_fan_drawers(self): num_of_fan = 0 num_of_drawer = 0 - for f in listdir(FAN_PATH): - if isfile(join(FAN_PATH, f)): + for f in listdir(self.fan_path): + if isfile(join(self.fan_path, f)): match_obj = re.match('fan(\d+)_speed_get', f) if match_obj != None: if int(match_obj.group(1)) > num_of_fan: diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py deleted file mode 100644 index 9e6c62935364..000000000000 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis_host.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Mellanox -# -# Module contains an implementation of SONiC Platform Base API and -# provides the Chassis information which are available in the platform -# -############################################################################# - -import sys - -try: - from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.watchdog import get_watchdog - from sonic_daemon_base.daemon_base import Logger - from os import listdir - from os.path import isfile, join - import io - import syslog -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - -HWMGMT_SYSTEM_ROOT = '/var/run/hw-management/system/' - -#reboot cause related definitions -REBOOT_CAUSE_ROOT = HWMGMT_SYSTEM_ROOT - -REBOOT_CAUSE_POWER_LOSS_FILE = 'reset_main_pwr_fail' -REBOOT_CAUSE_AUX_POWER_LOSS_FILE = 'reset_aux_pwr_or_ref' -REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE = 'reset_asic_thermal' -REBOOT_CAUSE_WATCHDOG_FILE = 'reset_hotswap_or_wd' -REBOOT_CAUSE_MLNX_FIRMWARE_RESET = 'reset_fw_reset' - -REBOOT_CAUSE_FILE_LENGTH = 1 - -# Global logger class instance -SYSLOG_IDENTIFIER = "mlnx-chassis" -logger = Logger(SYSLOG_IDENTIFIER) - -class Chassis(ChassisBase): - """Platform-specific Chassis class""" - - def __init__(self): - super(Chassis, self).__init__() - - # Initialize watchdog - self._watchdog = get_watchdog() - - def _read_generic_file(self, filename, len): - """ - Read a generic file, returns the contents of the file - """ - result = '' - try: - fileobj = io.open(filename) - result = fileobj.read(len) - fileobj.close() - return result - except: - logger.log_warning("Fail to read file {}, maybe it doesn't exist".format(filename)) - return '' - - def _verify_reboot_cause(self, filename): - ''' - Open and read the reboot cause file in - /var/run/hwmanagement/system (which is defined as REBOOT_CAUSE_ROOT) - If a reboot cause file doesn't exists, returns '0'. - ''' - return bool(int(self._read_generic_file(join(REBOOT_CAUSE_ROOT, filename), REBOOT_CAUSE_FILE_LENGTH).rstrip('\n'))) - - def get_reboot_cause(self): - """ - Retrieves the cause of the previous reboot - - Returns: - A tuple (string, string) where the first element is a string - containing the cause of the previous reboot. This string must be - one of the predefined strings in this class. If the first string - is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used - to pass a description of the reboot cause. - """ - # read reboot causes files in the following order - minor_cause = '' - if self._verify_reboot_cause(REBOOT_CAUSE_POWER_LOSS_FILE): - major_cause = self.REBOOT_CAUSE_POWER_LOSS - elif self._verify_reboot_cause(REBOOT_CAUSE_AUX_POWER_LOSS_FILE): - major_cause = self.REBOOT_CAUSE_POWER_LOSS - elif self._verify_reboot_cause(REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC_FILE): - major_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC - elif self._verify_reboot_cause(REBOOT_CAUSE_WATCHDOG_FILE): - major_cause = self.REBOOT_CAUSE_WATCHDOG - else: - major_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - if self._verify_reboot_cause(REBOOT_CAUSE_MLNX_FIRMWARE_RESET): - minor_cause = "Reset by ASIC firmware" - else: - major_cause = self.REBOOT_CAUSE_NON_HARDWARE - - return major_cause, minor_cause diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index 2ef67907e02a..a95bc9b9098f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -8,7 +8,7 @@ try: from sonic_platform_base.platform_base import PlatformBase -# from sonic_platform.chassis import Chassis + from sonic_platform.chassis import Chassis except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -16,8 +16,12 @@ class Platform(PlatformBase): def __init__(self, daemon = None): PlatformBase.__init__(self) if daemon is None: - from sonic_platform.chassis_host import Chassis self._chassis = Chassis() + self._chassis.initialize_watchdog() else: - from sonic_platform.chassis import Chassis self._chassis = Chassis() + self._chassis.initialize_psu() + self._chassis.initialize_fan() + self._chassis.initialize_sfp() + self._chassis.initialize_eeprom() + self._chassis.initialize_components_list() From e2fe79d7839477b6e8eaab2cb5d08302ef89d843 Mon Sep 17 00:00:00 2001 From: Stephen Sun Date: Thu, 25 Jul 2019 17:26:15 +0300 Subject: [PATCH 8/8] [sonic_platform] we decide to split chassis in a host/daemon basis rather than a per-daemon bases. adjust the argument of Platform() accordingly as well as all code that calls Platform. --- files/image_config/process-reboot-cause/process-reboot-cause | 2 +- .../mellanox/mlnx-platform-api/sonic_platform/platform.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index 2e152c699ce7..4d64b87402ce 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -73,7 +73,7 @@ def main(): import sonic_platform.platform # Check if the previous reboot was caused by hardware - platform = sonic_platform.platform.Platform() + platform = sonic_platform.platform.Platform(True) chassis = platform.get_chassis() diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py index a95bc9b9098f..fee01d2f8add 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py @@ -13,9 +13,9 @@ raise ImportError(str(e) + "- required module not found") class Platform(PlatformBase): - def __init__(self, daemon = None): + def __init__(self, is_host = False): PlatformBase.__init__(self) - if daemon is None: + if is_host: self._chassis = Chassis() self._chassis.initialize_watchdog() else: