From 8fc0f21d89e3f3c45b6da18fe2ed270c033861ef Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Tue, 5 Oct 2021 02:59:21 +0000 Subject: [PATCH 1/2] Implement chassis.get_change_event() * models: AS4630-54TE, AS9726-32D Signed-off-by: Sean Wu --- .../sonic_platform/chassis.py | 9 ++- .../sonic_platform/event.py | 62 +++++++++++++++++++ .../sonic_platform/chassis.py | 8 +++ .../sonic_platform/event.py | 62 +++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/event.py create mode 100644 device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py index 7a54eee6f478..315fb0806d33 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase from .helper import APIHelper + from .event import SfpEvent except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -42,7 +43,6 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) self._api_helper = APIHelper() - self._api_helper = APIHelper() self.is_host = self._api_helper.is_host() self.config_data = {} @@ -59,6 +59,7 @@ def __initialize_sfp(self): for index in range(0, PORT_END): sfp = Sfp(index) self._sfp_list.append(sfp) + self._sfpevent = SfpEvent(self._sfp_list) self.sfp_module_initialized = True def __initialize_fan(self): @@ -176,6 +177,12 @@ def get_reboot_cause(self): return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause) + def get_change_event(self, timeout=0): + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + return self._sfpevent.get_sfp_event(timeout) + def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/event.py new file mode 100644 index 000000000000..2d296e5137b2 --- /dev/null +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/event.py @@ -0,0 +1,62 @@ +try: + import time + from .helper import APIHelper + from sonic_py_common.logger import Logger +except ImportError as e: + raise ImportError(repr(e) + " - required module not found") + +POLL_INTERVAL_IN_SEC = 1 + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + def __init__(self, sfp_list): + self._api_helper = APIHelper() + self._sfp_list = sfp_list + self._logger = Logger() + self._sfp_change_event_data = {'present': 0} + + def get_presence_bitmap(self): + bitmap = 0 + for sfp in self._sfp_list: + modpres = sfp.get_presence() + i=sfp.port_num-1 + if modpres: + bitmap = bitmap | (1 << i) + return bitmap + + def get_sfp_event(self, timeout=2000): + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + + if timeout < 1000: + cd_ms = 1000 + else: + cd_ms = timeout + + while cd_ms > 0: + bitmap = self.get_presence_bitmap() + changed_ports = self._sfp_change_event_data['present'] ^ bitmap + if changed_ports != 0: + break + time.sleep(POLL_INTERVAL_IN_SEC) + # timeout=0 means wait for event forever + if timeout != 0: + cd_ms = cd_ms - POLL_INTERVAL_IN_SEC * 1000 + + if changed_ports != 0: + for sfp in self._sfp_list: + i=sfp.port_num-1 + if (changed_ports & (1 << i)): + if (bitmap & (1 << i)) == 0: + port_dict[i+1] = '0' + else: + port_dict[i+1] = '1' + + + # Update the cache dict + self._sfp_change_event_data['present'] = bitmap + return True, change_dict + else: + return True, change_dict diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py index 7eb9601d8b56..5a8c34c311d3 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase from .helper import APIHelper + from .event import SfpEvent except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -59,6 +60,7 @@ def __initialize_sfp(self): else: sfp_module = Sfp(index, 'SFP') self._sfp_list.append(sfp_module) + self._sfpevent = SfpEvent(self._sfp_list) self.sfp_module_initialized = True def __initialize_fan(self): @@ -177,6 +179,12 @@ def get_reboot_cause(self): return ('REBOOT_CAUSE_NON_HARDWARE', sw_reboot_cause) + def get_change_event(self, timeout=0): + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + return self._sfpevent.get_sfp_event(timeout) + def get_sfp(self, index): """ Retrieves sfp represented by (1-based) index diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py new file mode 100644 index 000000000000..624706904f3c --- /dev/null +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/event.py @@ -0,0 +1,62 @@ +try: + import time + from .helper import APIHelper + from sonic_py_common.logger import Logger +except ImportError as e: + raise ImportError(repr(e) + " - required module not found") + +POLL_INTERVAL_IN_SEC = 1 + +class SfpEvent: + ''' Listen to insert/remove sfp events ''' + + def __init__(self, sfp_list): + self._api_helper = APIHelper() + self._sfp_list = sfp_list + self._logger = Logger() + self._sfp_change_event_data = {'present': 0} + + def get_presence_bitmap(self): + bitmap = 0 + for sfp in self._sfp_list: + modpres = sfp.get_presence() + i=sfp._port_num-1 + if modpres: + bitmap = bitmap | (1 << i) + return bitmap + + def get_sfp_event(self, timeout=2000): + port_dict = {} + change_dict = {} + change_dict['sfp'] = port_dict + + if timeout < 1000: + cd_ms = 1000 + else: + cd_ms = timeout + + while cd_ms > 0: + bitmap = self.get_presence_bitmap() + changed_ports = self._sfp_change_event_data['present'] ^ bitmap + if changed_ports != 0: + break + time.sleep(POLL_INTERVAL_IN_SEC) + # timeout=0 means wait for event forever + if timeout != 0: + cd_ms = cd_ms - POLL_INTERVAL_IN_SEC * 1000 + + if changed_ports != 0: + for sfp in self._sfp_list: + i=sfp._port_num-1 + if (changed_ports & (1 << i)): + if (bitmap & (1 << i)) == 0: + port_dict[i+1] = '0' + else: + port_dict[i+1] = '1' + + + # Update the cache dict + self._sfp_change_event_data['present'] = bitmap + return True, change_dict + else: + return True, change_dict From 98e69115a6485edc0b1323d845019fd122b8a48c Mon Sep 17 00:00:00 2001 From: Sean Wu Date: Wed, 6 Oct 2021 02:03:33 +0000 Subject: [PATCH 2/2] Fix is_host() API might make OS stuck * The original design will use 'docker' to check operating environment. But that command might get stuck occasionally when it is called in the context of 'determine-reboot-cause.service'. It is suspetced the reason why it gets stucked is related to the service status of 'containerd'. * Change to use 'which systemctl' to check operation environment. When systemctl exists, returns 0. (In Host os env) When it does not exist, returns 1. (In docker os env) Signed-off-by: Sean Wu --- .../x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py | 2 +- .../x86_64-accton_as4630_54te-r0/sonic_platform/helper.py | 2 +- .../accton/x86_64-accton_as4630_54te-r0/sonic_platform/sfp.py | 2 +- .../x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py | 2 +- .../accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py | 2 +- device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py index 315fb0806d33..46795334ffaf 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py @@ -27,7 +27,7 @@ PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" SYSLED_FNODE = "/sys/class/leds/diag/brightness" SYSLED_MODES = { "0" : "STATUS_LED_COLOR_OFF", diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py index b124ca29f0df..90436db1525e 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py @@ -4,7 +4,7 @@ from mmap import * from sonic_py_common import device_info -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" EMPTY_STRING = "" diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/sfp.py index 25e5bce8fe40..4f70de013723 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/sfp.py @@ -126,7 +126,7 @@ class Sfp(SfpBase): # Path to sysfs PLATFORM_ROOT_PATH = "/usr/share/sonic/device" PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = "docker > /dev/null 2>&1" + HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" PLATFORM = "x86_64-accton_as4630_54te-r0" HWSKU = "Accton-AS4630-54TE" diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py index 5a8c34c311d3..12ac81878fb3 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/chassis.py @@ -29,7 +29,7 @@ PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/" REBOOT_CAUSE_FILE = "reboot-cause.txt" PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt" -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" class Chassis(ChassisBase): diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py index 4cd60ac90611..b9429919a197 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/helper.py @@ -4,7 +4,7 @@ from mmap import * from sonic_py_common import device_info -HOST_CHK_CMD = "docker > /dev/null 2>&1" +HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" EMPTY_STRING = "" diff --git a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py index 70c6838a8e88..a7edabcb979f 100644 --- a/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as9726_32d-r0/sonic_platform/sfp.py @@ -272,7 +272,7 @@ class Sfp(SfpBase): """Platform-specific Sfp class""" - HOST_CHK_CMD = "docker > /dev/null 2>&1" + HOST_CHK_CMD = "which systemctl > /dev/null 2>&1" PLATFORM = "x86_64-accton_as9726_32d-r0" HWSKU = "Accton-AS9726-32D"