-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[docker-syncd-mlnx] add new mlnx-sfpd daemon to docker-syncd-mlnx (#1841
) * This new daemon will listen to the SDK for the SDK change event, * after got a SFP change event will publish a notification via DB. modified: platform/mellanox/docker-syncd-mlnx-rpc.mk modified: platform/mellanox/docker-syncd-mlnx.mk modified: platform/mellanox/docker-syncd-mlnx/start.sh modified: platform/mellanox/docker-syncd-mlnx/supervisord.conf new file: platform/mellanox/mlnx-sfpd.mk new file: platform/mellanox/mlnx-sfpd/scripts/mlnx-sfpd new file: platform/mellanox/mlnx-sfpd/setup.py modified: platform/mellanox/rules.mk signed-off-by Liu Kebo kebol@mellanox.com
- Loading branch information
Showing
8 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ rm -f /var/run/rsyslogd.pid | |
supervisorctl start rsyslogd | ||
|
||
supervisorctl start syncd | ||
|
||
supervisorctl start mlnx-sfpd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# mlnx-sfpd (SONiC MLNX platform sfp event monitoring daemon) Debian package | ||
|
||
MLNX_SFPD = python-mlnx-sfpd_1.0-1_all.deb | ||
$(MLNX_SFPD)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sfpd | ||
SONIC_PYTHON_STDEB_DEBS += $(MLNX_SFPD) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
#!/usr/bin/env python | ||
''' | ||
This code is for a mlnx platform specific daemon, mlnx-sfpd. | ||
Which listen to the SDK for the SFP change event and post the event to DB. | ||
''' | ||
|
||
from __future__ import print_function | ||
import sys, errno | ||
import os | ||
import time | ||
import syslog | ||
import signal | ||
import json | ||
from python_sdk_api.sx_api import * | ||
from swsssdk import SonicV2Connector | ||
|
||
VERSION = '1.0' | ||
|
||
SYSLOG_IDENTIFIER = "mlnx-sfpd" | ||
|
||
REDIS_HOSTIP = "127.0.0.1" | ||
|
||
SDK_SFP_STATE_IN = 0x1 | ||
SDK_SFP_STATE_OUT = 0x2 | ||
STATUS_PLUGIN = '1' | ||
STATUS_PLUGOUT = '0' | ||
STATUS_UNKNOWN = '2' | ||
|
||
sfp_value_status_dict = {SDK_SFP_STATE_IN:STATUS_PLUGIN, SDK_SFP_STATE_OUT:STATUS_PLUGOUT} | ||
|
||
#========================== 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: | ||
print(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: | ||
print(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: | ||
print(msg) | ||
|
||
#========================== Signal Handling ========================== | ||
|
||
def signal_handler(sig, frame): | ||
if sig == signal.SIGHUP: | ||
log_info("Caught SIGHUP - ignoring...") | ||
return | ||
elif sig == signal.SIGINT: | ||
log_info("Caught SIGINT - exiting...") | ||
sys.exit(128 + sig) | ||
elif sig == signal.SIGTERM: | ||
log_info("Caught SIGTERM - exiting...") | ||
sys.exit(128 + sig) | ||
else: | ||
log_warning("Caught unhandled signal '" + sig + "'") | ||
|
||
|
||
def sx_recv(fd_p, handle): | ||
# recv parameters | ||
pkt_size = 2000 | ||
pkt_size_p = new_uint32_t_p() | ||
uint32_t_p_assign(pkt_size_p, pkt_size) | ||
pkt = new_uint8_t_arr(pkt_size) | ||
recv_info_p = new_sx_receive_info_t_p() | ||
pmpe_t = sx_event_pmpe_t() | ||
logical_port_list = new_sx_port_log_id_t_arr(4) | ||
port_attributes_list = new_sx_port_attributes_t_arr(64) | ||
port_cnt_p = new_uint32_t_p() | ||
uint32_t_p_assign(port_cnt_p,64) | ||
label_port_list = [] | ||
|
||
rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p) | ||
if rc != 0: | ||
log_error("event receive exit with error, rc %d" % rc) | ||
exit(rc) | ||
|
||
pmpe_t = recv_info_p.event_info.pmpe | ||
port_list_size = pmpe_t.list_size | ||
logical_port_list = pmpe_t.log_port_list | ||
module_state = pmpe_t.module_state | ||
|
||
for i in range(0, port_list_size): | ||
logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) | ||
rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p) | ||
port_cnt = uint32_t_p_value(port_cnt_p) | ||
|
||
for i in range(0,port_cnt): | ||
port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i) | ||
if port_attributes.log_port == logical_port: | ||
lable_port = port_attributes.port_mapping.module_port | ||
break | ||
label_port_list.append(lable_port) | ||
|
||
return label_port_list, module_state | ||
|
||
def send_sfp_notification(db, interface, state): | ||
sfp_notify = [interface,state] | ||
msg = json.dumps(sfp_notify,separators=(',',':')) | ||
db.publish('STATE_DB','TRANSCEIVER_NOTIFY', msg) | ||
return | ||
|
||
# main start | ||
def main(): | ||
# Register our signal handlers | ||
signal.signal(signal.SIGHUP, signal_handler) | ||
signal.signal(signal.SIGINT, signal_handler) | ||
signal.signal(signal.SIGTERM, signal_handler) | ||
|
||
#open SDK handler | ||
log_info("starting mlnx-sfpd...") | ||
rc, handle = sx_api_open(None) | ||
retry_time = 1 | ||
while rc != SX_STATUS_SUCCESS: | ||
time.sleep(2**retry_time) | ||
retry_time += 1 | ||
rc, handle = sx_api_open(None) | ||
if retry_time > 20: | ||
log_error("Failed to open api handle.\nPlease check that SDK is running.") | ||
sys.exit(errno.EACCES) | ||
|
||
#open recv fd | ||
rx_fd_p = new_sx_fd_t_p() | ||
rc = sx_api_host_ifc_open(handle, rx_fd_p) | ||
if rc != 0: | ||
log_error("sx_api_host_ifc_open exit with error, rc %d" % rc) | ||
exit(rc) | ||
|
||
# set up general host ifc parameters | ||
swid = 0 | ||
cmd = SX_ACCESS_CMD_REGISTER | ||
uc_p = new_sx_user_channel_t_p() | ||
uc_p.type = SX_USER_CHANNEL_TYPE_FD | ||
uc_p.channel.fd = rx_fd_p | ||
trap_id = SX_TRAP_ID_PMPE | ||
|
||
rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p) | ||
if rc != 0: | ||
log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc) | ||
exit(rc) | ||
|
||
#connect to state db for notification sending | ||
state_db = SonicV2Connector(host=REDIS_HOSTIP) | ||
state_db.connect(state_db.STATE_DB) | ||
|
||
#main loop for sfp event listening | ||
log_info("mlnx-sfpd started") | ||
while True: | ||
state = STATUS_UNKNOWN | ||
port_list, module_state = sx_recv(rx_fd_p, handle) | ||
if module_state in sfp_value_status_dict: state = sfp_value_status_dict[module_state] | ||
|
||
if state != STATUS_UNKNOWN: | ||
for port in port_list: | ||
log_info("SFP on port %d state %s" % (port, state)) | ||
send_sfp_notification(state_db, str(port), state) | ||
|
||
log_info("sfp change event handling done") | ||
|
||
''' | ||
# TODO: clean open handlers before exit, need find out which errors can be raised by SDK in this case. | ||
# unregister trap id | ||
cmd = SX_ACCESS_CMD_DEREGISTER | ||
rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p) | ||
if rc != 0: | ||
log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc) | ||
exit(rc) | ||
# close read fp | ||
rc = sx_api_host_ifc_close(handle, rx_fd_p) | ||
if rc != 0: | ||
log_error("sx_api_host_ifc_close exit with error, rc %d" % rc) | ||
exit(rc) | ||
# close sdk handler | ||
rc = sx_api_close(handle) | ||
if rc != 0: | ||
log_error("exit with error, rc %d" % rc) | ||
exit(rc) | ||
log_info("mlnx-sfpd exited") | ||
''' | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from setuptools import setup | ||
|
||
setup( | ||
name='mlnx-sfpd', | ||
version='1.0', | ||
description='SFP event mmonitoring daemon for SONiC on mellanox platform', | ||
license='Apache 2.0', | ||
author='SONiC Community', | ||
url='https://github.com/Azure/sonic-buildimage/', | ||
maintainer='Kebo Liu', | ||
maintainer_email='kebol@mellanox.com', | ||
scripts=[ | ||
'scripts/mlnx-sfpd', | ||
], | ||
classifiers=[ | ||
'Development Status :: 4 - Beta', | ||
'Environment :: No Input/Output (Daemon)', | ||
'Intended Audience :: Developers', | ||
'Intended Audience :: Information Technology', | ||
'Intended Audience :: System Administrators', | ||
'License :: OSI Approved :: Apache Software License', | ||
'Natural Language :: English', | ||
'Operating System :: POSIX :: Linux', | ||
'Programming Language :: Python :: 2.7', | ||
'Topic :: System :: Hardware', | ||
], | ||
keywords='sonic SONiC SFP sfp MELLANOX mellanox daemon SFPD sfpd', | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters