1
- #!/usr/bin/env python
1
+ #!/usr/bin/env python3
2
2
3
3
"""
4
4
ledd
@@ -15,7 +15,7 @@ from swsscommon import swsscommon
15
15
16
16
#============================= Constants =============================
17
17
18
- VERSION = '1 .0'
18
+ VERSION = '2 .0'
19
19
20
20
SYSLOG_IDENTIFIER = "ledd"
21
21
@@ -33,6 +33,7 @@ LED_CLASS_NAME = "LedControl"
33
33
SELECT_TIMEOUT = 1000
34
34
35
35
LEDUTIL_LOAD_ERROR = 1
36
+ LEDUTIL_RUNTIME_ERROR = 2
36
37
37
38
38
39
class DaemonLedd (daemon_base .DaemonBase ):
@@ -56,50 +57,67 @@ class DaemonLedd(daemon_base.DaemonBase):
56
57
namespaces = multi_asic .get_front_end_namespaces ()
57
58
58
59
# Subscribe to PORT table notifications in the Application DB
59
- appl_db = {}
60
- self .sst = {}
60
+ self .tables = {}
61
61
self .sel = swsscommon .Select ()
62
62
63
63
for namespace in namespaces :
64
- # Open a handle to the Application database, in all namespaces
65
- appl_db [namespace ] = daemon_base .db_connect ("APPL_DB" , namespace = namespace )
66
- self .sst [namespace ] = swsscommon .SubscriberStateTable (appl_db [namespace ], swsscommon .APP_PORT_TABLE_NAME )
67
- self .sel .addSelectable (self .sst [namespace ])
68
-
69
- # Run daemon
70
- def run (self ):
71
- # Use timeout to prevent ignoring the signals we want to handle
72
- # in signal_handler() (e.g. SIGTERM for graceful shutdown)
73
- (state , selectableObj ) = self .sel .select (SELECT_TIMEOUT )
74
-
75
- if state == swsscommon .Select .TIMEOUT :
76
- # Do not flood log when select times out
77
- return 1
78
-
79
- if state != swsscommon .Select .OBJECT :
80
- self .log_warning ("sel.select() did not return swsscommon.Select.OBJECT" )
81
- return 2
64
+ self .subscribeDbTable ("APPL_DB" , swsscommon .APP_PORT_TABLE_NAME , namespace )
65
+
66
+ def connectDB (self , dbname , namespace ):
67
+ db = daemon_base .db_connect (dbname , namespace = namespace )
68
+ return db
69
+
70
+ def subscribeDbTable (self , dbname , tblname , namespace ):
71
+ db = self .connectDB (dbname , namespace )
72
+ self .tables [namespace ] = swsscommon .SubscriberStateTable (db , tblname )
73
+ self .sel .addSelectable (self .tables [namespace ])
74
+
75
+ def isFrontPanelPort (self , port_name ):
76
+ return not port_name .startswith ((backplane_prefix (), inband_prefix (), recirc_prefix ()))
77
+
78
+ def updatePortLedColor (self , port_name , port_status ):
79
+ self .led_control .port_link_state_change (port_name , port_status )
80
+
81
+ def getEventNamespace (self , selectObj ):
82
+ # Get the corresponding namespace from redisselect db connector object
83
+ return selectObj .getDbConnector ().getNamespace ()
84
+
85
+ def processPortTableEvent (self , selectableObj ):
86
+ ''' Process (if any) event from the PORT table in the Application DB '''
82
87
83
88
# Get the redisselect object from selectable object
84
89
redisSelectObj = swsscommon .CastSelectableToRedisSelectObj (selectableObj )
90
+ namespace = self .getEventNamespace (redisSelectObj )
85
91
86
- # Get the corresponding namespace from redisselect db connector object
87
- namespace = redisSelectObj .getDbConnector ().getNamespace ()
88
-
89
- (key , op , fvp ) = self .sst [namespace ].pop ()
92
+ (key , op , fvp ) = self .tables [namespace ].pop ()
90
93
if fvp :
91
94
# TODO: Once these flag entries have been removed from the DB,
92
95
# we can remove this check
93
96
if key in ["PortConfigDone" , "PortInitDone" ]:
94
- return 3
97
+ return
95
98
96
99
fvp_dict = dict (fvp )
97
100
98
- if op == "SET" and "oper_status" in fvp_dict :
99
- if not key .startswith ((backplane_prefix (), inband_prefix (), recirc_prefix ())):
100
- self .led_control .port_link_state_change (key , fvp_dict ["oper_status" ])
101
- else :
102
- return 4
101
+ if op == "SET" and "oper_status" in fvp_dict and self .isFrontPanelPort (key ):
102
+ self .updatePortLedColor (key , fvp_dict ["oper_status" ])
103
+
104
+
105
+
106
+ # Run daemon
107
+ def run (self ):
108
+ # Use timeout to prevent ignoring the signals we want to handle
109
+ # in signal_handler() (e.g. SIGTERM for graceful shutdown)
110
+ (state , selectableObj ) = self .sel .select (SELECT_TIMEOUT )
111
+
112
+ if state == swsscommon .Select .TIMEOUT :
113
+ # NOOP - Nothing to process here
114
+ return 0
115
+
116
+ if state != swsscommon .Select .OBJECT :
117
+ self .log_warning ("sel.select() did not return swsscommon.Select.OBJECT - May be socket closed???" )
118
+ return - 1 ## Fail here so that the daemon can be restarted
119
+
120
+ self .processPortTableEvent (selectableObj )
103
121
104
122
return 0
105
123
@@ -126,8 +144,9 @@ def main():
126
144
127
145
# Listen indefinitely for changes to the PORT table in the Application DB's
128
146
while True :
129
- ledd .run ()
130
-
147
+ if 0 != ledd .run ():
148
+ print ("ledd.run() failed... Exiting" )
149
+ sys .exit (LEDUTIL_RUNTIME_ERROR )
131
150
132
151
if __name__ == '__main__' :
133
- main ()
152
+ main ()
0 commit comments