From 1f4325e3bf188c6af1b1ffc43e2340e2e49f41d9 Mon Sep 17 00:00:00 2001 From: David Xiao <53024022+david-xk@users.noreply.github.com> Date: Mon, 10 Feb 2020 12:26:48 -0800 Subject: [PATCH] [Inventec][D6356] Update Inventec 6356 (#3839) * [Inventec][D6356] Update Inventec 6356 1.[Platform API] Add get_change_event implementation for Chassis class 2.[Platforn monitor] skip ledd to avoid pmon init failure --- .../led_proc_init.soc | 2 - .../pmon_daemon_control.json | 4 + .../d6356/sonic_platform/chassis.py | 36 ++++++ .../d6356/sonic_platform/transceiver_event.py | 116 ++++++++++++++++++ .../debian/platform-modules-d6356.init | 32 +++-- 5 files changed, 170 insertions(+), 20 deletions(-) create mode 100644 device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json create mode 100644 platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py diff --git a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc index 01b49772c..55c82d388 100644 --- a/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc +++ b/device/inventec/x86_64-inventec_d6356-r0/led_proc_init.soc @@ -1,5 +1,3 @@ -#led auto off -#led stop m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on diff --git a/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json b/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json new file mode 100644 index 000000000..44bad6494 --- /dev/null +++ b/device/inventec/x86_64-inventec_d6356-r0/pmon_daemon_control.json @@ -0,0 +1,4 @@ +{ + "skip_ledd": true +} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py index 761d21cf4..f961cb8cd 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/chassis.py @@ -14,6 +14,7 @@ try: from sonic_platform.sfp import Sfp from sonic_platform.qsfp import QSfp from sonic_platform.thermal import Thermal + from sonic_platform.transceiver_event import TransceiverEvent except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -53,6 +54,8 @@ class Chassis(ChassisBase): thermal = Thermal(index) self._thermal_list.append(thermal) + # Initialize TRANSCEIVER EVENT MONITOR + self.__xcvr_event = TransceiverEvent() ############################################## # Device methods @@ -147,3 +150,36 @@ class Chassis(ChassisBase): to pass a description of the reboot cause. """ raise NotImplementedError + +############################################## +# Other methods +############################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} + indicates that fan 0 has been removed, fan 2 + has been inserted and sfp 11 has been removed. + """ + + rc, xcvr_event = self.__xcvr_event.get_transceiver_change_event(timeout) + + return rc, {'sfp': xcvr_event} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py new file mode 100644 index 000000000..3eda411de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/sonic_platform/transceiver_event.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# +# Name: transceiver_event.py, version: 1.0 +# + +try: + import time + import socket + import re + import os + from collections import OrderedDict +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class NetlinkEventMonitor(object): + __instance = None + + def __new__(cls, *args, **kwargs): + if not cls.__instance: + # print(cls) + cls.__instance = super(NetlinkEventMonitor, cls).__new__(cls) + cls.__instance.__recieved_events = OrderedDict() + return cls.__instance + + def __init__(self, timeout): + # print('__init__', self) + NETLINK_KOBJECT_UEVENT = 15 + self.__socket = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT) + self.__timeout = timeout + + def start(self): + # print('start', self.__timeout) + self.__socket.bind((os.getpid(), -1)) + if 0 == self.__timeout: + self.__socket.settimeout(None) + else: + self.__socket.settimeout(self.__timeout/1000.0) + + def stop(self): + self.__socket.close() + + def __enter__(self): + # print('__enter__', self) + self.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + # print('__exit__', self) + self.stop() + + def __iter__(self): + # print('__iter__', self) + while True: + for item in self.next_events(): + yield item + + def next_events(self): + try: + data = self.__socket.recv(16384) + event = {} + for item in data.split(b'\x00'): + if not item: + # check if we have an event and if we already received it + if event and 'SEQNUM' in event: + event_seqnum = event['SEQNUM'] + if event_seqnum in self.__recieved_events: + pass + else: + # print("=", event_seqnum) + self.__recieved_events[event_seqnum] = event + length = len(self.__recieved_events) + # print("=", length) + if (length > 100): + self.__recieved_events.popitem(last=False) + yield event + event = {} + else: + try: + k, v = item.split(b'=', 1) + event[k.decode('ascii')] = v.decode('ascii') + # print("=",k,v) + except ValueError: + pass + except Exception: + yield {} + +class TransceiverEvent(object): + + def __init__(self): + pass + + def get_transceiver_change_event(self, timeout=0): + port_dict = {} + with NetlinkEventMonitor(timeout) as netlink_monitor: + for event in netlink_monitor: + if event and 'SUBSYSTEM' in event: + if event['SUBSYSTEM'] == 'swps': + #print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE'])) + portname = event['DEVPATH'].split("/")[-1] + rc = re.match(r"port(?P\d+)",portname) + if rc is not None: + if event['ACTION'] == "remove": + remove_num = int(rc.group("num")) + port_dict[remove_num] = "0" + elif event['ACTION'] == "add": + add_num = int(rc.group("num")) + port_dict[add_num] = "1" + return True, port_dict + else: + return False, {} + else: + pass + else: + return True, {} + diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init index eaeb97406..6d0f785fc 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/platform-modules-d6356.init @@ -29,30 +29,26 @@ do_monitor_stop() { case "$1" in start) - echo -n "Setting up board... " - -# depmod -a - /usr/local/bin/inventec_d6356_util.py -f install - do_monitor_${1} - echo "done." - ;; + echo -n "Setting up board... " + /usr/local/bin/inventec_d6356_util.py -f install + do_monitor_${1} + echo "done." + ;; stop) - - /usr/local/bin/inventec_d6356_util.py -f clean - do_monitor_${1} - echo "done." - - ;; + /usr/local/bin/inventec_d6356_util.py -f clean + do_monitor_${1} + echo "done." + ;; force-reload|restart) - echo "Not supported" - ;; + echo "Not supported" + ;; *) - echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}" - exit 1 - ;; + echo "Usage: /etc/init.d/platform-modules-d6356.init {start|stop}" + exit 1 + ;; esac exit 0