Skip to content

Commit 117dc2b

Browse files
keboliulguohan
authored andcommitted
[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
1 parent 92eb7b4 commit 117dc2b

File tree

8 files changed

+245
-2
lines changed

8 files changed

+245
-2
lines changed

platform/mellanox/docker-syncd-mlnx-rpc.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz
44
$(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc
5-
$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT)
5+
$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(MLNX_SFPD)
66
$(DOCKER_SYNCD_MLNX_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_MLNX)
77
SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC)
88
ifeq ($(ENABLE_SYNCD_RPC),y)

platform/mellanox/docker-syncd-mlnx.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
DOCKER_SYNCD_MLNX = docker-syncd-mlnx.gz
44
$(DOCKER_SYNCD_MLNX)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx
5-
$(DOCKER_SYNCD_MLNX)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API)
5+
$(DOCKER_SYNCD_MLNX)_DEPENDS += $(SYNCD) $(PYTHON_SDK_API) $(MLNX_SFPD)
66
$(DOCKER_SYNCD_MLNX)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE)
77
SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX)
88
ifneq ($(ENABLE_SYNCD_RPC),y)

platform/mellanox/docker-syncd-mlnx/start.sh

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ rm -f /var/run/rsyslogd.pid
55
supervisorctl start rsyslogd
66

77
supervisorctl start syncd
8+
9+
supervisorctl start mlnx-sfpd

platform/mellanox/docker-syncd-mlnx/supervisord.conf

+8
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,11 @@ autostart=false
2626
autorestart=false
2727
stdout_logfile=syslog
2828
stderr_logfile=syslog
29+
30+
[program:mlnx-sfpd]
31+
command=/usr/bin/mlnx-sfpd
32+
priority=4
33+
autostart=false
34+
autorestart=false
35+
stdout_logfile=syslog
36+
stderr_logfile=syslog

platform/mellanox/mlnx-sfpd.mk

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# mlnx-sfpd (SONiC MLNX platform sfp event monitoring daemon) Debian package
2+
3+
MLNX_SFPD = python-mlnx-sfpd_1.0-1_all.deb
4+
$(MLNX_SFPD)_SRC_PATH = $(PLATFORM_PATH)/mlnx-sfpd
5+
SONIC_PYTHON_STDEB_DEBS += $(MLNX_SFPD)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#!/usr/bin/env python
2+
'''
3+
This code is for a mlnx platform specific daemon, mlnx-sfpd.
4+
Which listen to the SDK for the SFP change event and post the event to DB.
5+
'''
6+
7+
from __future__ import print_function
8+
import sys, errno
9+
import os
10+
import time
11+
import syslog
12+
import signal
13+
import json
14+
from python_sdk_api.sx_api import *
15+
from swsssdk import SonicV2Connector
16+
17+
VERSION = '1.0'
18+
19+
SYSLOG_IDENTIFIER = "mlnx-sfpd"
20+
21+
REDIS_HOSTIP = "127.0.0.1"
22+
23+
SDK_SFP_STATE_IN = 0x1
24+
SDK_SFP_STATE_OUT = 0x2
25+
STATUS_PLUGIN = '1'
26+
STATUS_PLUGOUT = '0'
27+
STATUS_UNKNOWN = '2'
28+
29+
sfp_value_status_dict = {SDK_SFP_STATE_IN:STATUS_PLUGIN, SDK_SFP_STATE_OUT:STATUS_PLUGOUT}
30+
31+
#========================== Syslog wrappers ==========================
32+
33+
def log_info(msg, also_print_to_console=False):
34+
syslog.openlog(SYSLOG_IDENTIFIER)
35+
syslog.syslog(syslog.LOG_INFO, msg)
36+
syslog.closelog()
37+
38+
if also_print_to_console:
39+
print(msg)
40+
41+
def log_warning(msg, also_print_to_console=False):
42+
syslog.openlog(SYSLOG_IDENTIFIER)
43+
syslog.syslog(syslog.LOG_WARNING, msg)
44+
syslog.closelog()
45+
46+
if also_print_to_console:
47+
print(msg)
48+
49+
def log_error(msg, also_print_to_console=False):
50+
syslog.openlog(SYSLOG_IDENTIFIER)
51+
syslog.syslog(syslog.LOG_ERR, msg)
52+
syslog.closelog()
53+
54+
if also_print_to_console:
55+
print(msg)
56+
57+
#========================== Signal Handling ==========================
58+
59+
def signal_handler(sig, frame):
60+
if sig == signal.SIGHUP:
61+
log_info("Caught SIGHUP - ignoring...")
62+
return
63+
elif sig == signal.SIGINT:
64+
log_info("Caught SIGINT - exiting...")
65+
sys.exit(128 + sig)
66+
elif sig == signal.SIGTERM:
67+
log_info("Caught SIGTERM - exiting...")
68+
sys.exit(128 + sig)
69+
else:
70+
log_warning("Caught unhandled signal '" + sig + "'")
71+
72+
73+
def sx_recv(fd_p, handle):
74+
# recv parameters
75+
pkt_size = 2000
76+
pkt_size_p = new_uint32_t_p()
77+
uint32_t_p_assign(pkt_size_p, pkt_size)
78+
pkt = new_uint8_t_arr(pkt_size)
79+
recv_info_p = new_sx_receive_info_t_p()
80+
pmpe_t = sx_event_pmpe_t()
81+
logical_port_list = new_sx_port_log_id_t_arr(4)
82+
port_attributes_list = new_sx_port_attributes_t_arr(64)
83+
port_cnt_p = new_uint32_t_p()
84+
uint32_t_p_assign(port_cnt_p,64)
85+
label_port_list = []
86+
87+
rc = sx_lib_host_ifc_recv(fd_p, pkt, pkt_size_p, recv_info_p)
88+
if rc != 0:
89+
log_error("event receive exit with error, rc %d" % rc)
90+
exit(rc)
91+
92+
pmpe_t = recv_info_p.event_info.pmpe
93+
port_list_size = pmpe_t.list_size
94+
logical_port_list = pmpe_t.log_port_list
95+
module_state = pmpe_t.module_state
96+
97+
for i in range(0, port_list_size):
98+
logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i)
99+
rc = sx_api_port_device_get(handle, 1 , 0, port_attributes_list, port_cnt_p)
100+
port_cnt = uint32_t_p_value(port_cnt_p)
101+
102+
for i in range(0,port_cnt):
103+
port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list,i)
104+
if port_attributes.log_port == logical_port:
105+
lable_port = port_attributes.port_mapping.module_port
106+
break
107+
label_port_list.append(lable_port)
108+
109+
return label_port_list, module_state
110+
111+
def send_sfp_notification(db, interface, state):
112+
sfp_notify = [interface,state]
113+
msg = json.dumps(sfp_notify,separators=(',',':'))
114+
db.publish('STATE_DB','TRANSCEIVER_NOTIFY', msg)
115+
return
116+
117+
# main start
118+
def main():
119+
# Register our signal handlers
120+
signal.signal(signal.SIGHUP, signal_handler)
121+
signal.signal(signal.SIGINT, signal_handler)
122+
signal.signal(signal.SIGTERM, signal_handler)
123+
124+
#open SDK handler
125+
log_info("starting mlnx-sfpd...")
126+
rc, handle = sx_api_open(None)
127+
retry_time = 1
128+
while rc != SX_STATUS_SUCCESS:
129+
time.sleep(2**retry_time)
130+
retry_time += 1
131+
rc, handle = sx_api_open(None)
132+
if retry_time > 20:
133+
log_error("Failed to open api handle.\nPlease check that SDK is running.")
134+
sys.exit(errno.EACCES)
135+
136+
#open recv fd
137+
rx_fd_p = new_sx_fd_t_p()
138+
rc = sx_api_host_ifc_open(handle, rx_fd_p)
139+
if rc != 0:
140+
log_error("sx_api_host_ifc_open exit with error, rc %d" % rc)
141+
exit(rc)
142+
143+
# set up general host ifc parameters
144+
swid = 0
145+
cmd = SX_ACCESS_CMD_REGISTER
146+
uc_p = new_sx_user_channel_t_p()
147+
uc_p.type = SX_USER_CHANNEL_TYPE_FD
148+
uc_p.channel.fd = rx_fd_p
149+
trap_id = SX_TRAP_ID_PMPE
150+
151+
rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p)
152+
if rc != 0:
153+
log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc)
154+
exit(rc)
155+
156+
#connect to state db for notification sending
157+
state_db = SonicV2Connector(host=REDIS_HOSTIP)
158+
state_db.connect(state_db.STATE_DB)
159+
160+
#main loop for sfp event listening
161+
log_info("mlnx-sfpd started")
162+
while True:
163+
state = STATUS_UNKNOWN
164+
port_list, module_state = sx_recv(rx_fd_p, handle)
165+
if module_state in sfp_value_status_dict: state = sfp_value_status_dict[module_state]
166+
167+
if state != STATUS_UNKNOWN:
168+
for port in port_list:
169+
log_info("SFP on port %d state %s" % (port, state))
170+
send_sfp_notification(state_db, str(port), state)
171+
172+
log_info("sfp change event handling done")
173+
174+
'''
175+
# TODO: clean open handlers before exit, need find out which errors can be raised by SDK in this case.
176+
# unregister trap id
177+
cmd = SX_ACCESS_CMD_DEREGISTER
178+
rc = sx_api_host_ifc_trap_id_register_set(handle, cmd, swid, trap_id, uc_p)
179+
if rc != 0:
180+
log_error("sx_api_host_ifc_trap_id_register_set exit with error, rc %d" % rc)
181+
exit(rc)
182+
183+
# close read fp
184+
rc = sx_api_host_ifc_close(handle, rx_fd_p)
185+
if rc != 0:
186+
log_error("sx_api_host_ifc_close exit with error, rc %d" % rc)
187+
exit(rc)
188+
189+
# close sdk handler
190+
rc = sx_api_close(handle)
191+
if rc != 0:
192+
log_error("exit with error, rc %d" % rc)
193+
exit(rc)
194+
195+
log_info("mlnx-sfpd exited")
196+
'''
197+
198+
if __name__ == '__main__':
199+
main()

platform/mellanox/mlnx-sfpd/setup.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='mlnx-sfpd',
5+
version='1.0',
6+
description='SFP event mmonitoring daemon for SONiC on mellanox platform',
7+
license='Apache 2.0',
8+
author='SONiC Community',
9+
url='https://github.com/Azure/sonic-buildimage/',
10+
maintainer='Kebo Liu',
11+
maintainer_email='kebol@mellanox.com',
12+
scripts=[
13+
'scripts/mlnx-sfpd',
14+
],
15+
classifiers=[
16+
'Development Status :: 4 - Beta',
17+
'Environment :: No Input/Output (Daemon)',
18+
'Intended Audience :: Developers',
19+
'Intended Audience :: Information Technology',
20+
'Intended Audience :: System Administrators',
21+
'License :: OSI Approved :: Apache Software License',
22+
'Natural Language :: English',
23+
'Operating System :: POSIX :: Linux',
24+
'Programming Language :: Python :: 2.7',
25+
'Topic :: System :: Hardware',
26+
],
27+
keywords='sonic SONiC SFP sfp MELLANOX mellanox daemon SFPD sfpd',
28+
)

platform/mellanox/rules.mk

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ include $(PLATFORM_PATH)/one-image.mk
1010
include $(PLATFORM_PATH)/libsaithrift-dev.mk
1111
include $(PLATFORM_PATH)/python-saithrift.mk
1212
include $(PLATFORM_PATH)/docker-ptf-mlnx.mk
13+
include $(PLATFORM_PATH)/mlnx-sfpd.mk
1314

1415
SONIC_ALL += $(SONIC_ONE_IMAGE) \
1516
$(DOCKER_FPM)

0 commit comments

Comments
 (0)