|
12 | 12 | try: |
13 | 13 | import sys |
14 | 14 | import time |
| 15 | + import signal |
| 16 | + import threading |
15 | 17 | from swsscommon import swsscommon |
| 18 | + from sonic_daemon_base.daemon_base import Logger |
16 | 19 | from sonic_daemon_base.daemon_base import DaemonBase |
17 | 20 | except ImportError, e: |
18 | 21 | raise ImportError (str(e) + " - required module not found") |
19 | 22 |
|
20 | | -#============================= Constants ============================= |
| 23 | +# |
| 24 | +# Constants ==================================================================== |
| 25 | +# |
| 26 | + |
| 27 | +SYSLOG_IDENTIFIER = "psud" |
21 | 28 |
|
22 | 29 | PLATFORM_SPECIFIC_MODULE_NAME = "psuutil" |
23 | 30 | PLATFORM_SPECIFIC_CLASS_NAME = "PsuUtil" |
24 | 31 |
|
| 32 | +CHASSIS_INFO_NUM_PSUS_FIELD = 'num_psus' |
| 33 | + |
| 34 | +PSU_INFO_PRESENCE_FIELD = 'presence' |
| 35 | +PSU_INFO_STATUS_FIELD = 'status' |
| 36 | + |
25 | 37 | PSU_INFO_UPDATE_PERIOD_SECS = 3 |
26 | 38 |
|
| 39 | +PSUUTIL_LOAD_ERROR = 1 |
| 40 | +DAEMON_INIT_ERROR = 2 |
| 41 | + |
| 42 | +logger = Logger(SYSLOG_IDENTIFIER) |
| 43 | + |
| 44 | +# |
| 45 | +# Helper functions ============================================================= |
| 46 | +# |
| 47 | + |
| 48 | +def psu_db_update(psuutil, psu_tbl, num_psus): |
| 49 | + for psu_index in range(1, num_psus + 1): |
| 50 | + fvs = swsscommon.FieldValuePairs([(PSU_INFO_PRESENCE_FIELD, |
| 51 | + 'true' if psuutil.get_psu_presence(psu_index) else 'false'), |
| 52 | + (PSU_INFO_STATUS_FIELD, |
| 53 | + 'true' if psuutil.get_psu_status(psu_index) else 'false')]) |
| 54 | + psu_tbl.set("PSU {}".format(psu_index), fvs) |
| 55 | + |
| 56 | +# |
| 57 | +# Daemon ======================================================================= |
| 58 | +# |
| 59 | + |
27 | 60 | class DaemonPsud(DaemonBase): |
28 | 61 | def __init__(self): |
29 | 62 | DaemonBase.__init__(self) |
30 | 63 |
|
31 | | - def __exit__(self): |
32 | | - DaemonBase.__exit__(self) |
| 64 | + self.stop = threading.Event() |
33 | 65 |
|
| 66 | + # Signal handler |
| 67 | + def signal_handler(self, sig, frame): |
| 68 | + if sig == signal.SIGHUP: |
| 69 | + logger.log_info("Caught SIGHUP - ignoring...") |
| 70 | + elif sig == signal.SIGINT: |
| 71 | + logger.log_info("Caught SIGINT - exiting...") |
| 72 | + self.stop.set() |
| 73 | + elif sig == signal.SIGTERM: |
| 74 | + logger.log_info("Caught SIGTERM - exiting...") |
| 75 | + self.stop.set() |
| 76 | + else: |
| 77 | + logger.log_warning("Caught unhandled signal '" + sig + "'") |
| 78 | + |
| 79 | + # Run daemon |
34 | 80 | def run(self): |
| 81 | + logger.log_info("Starting up...") |
| 82 | + |
35 | 83 | # Load platform-specific psuutil class |
36 | 84 | platform_psuutil = self.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME) |
37 | 85 | if not platform_psuutil: |
38 | | - self.log_error("failed to load psuutil") |
39 | | - sys.exit(1) |
| 86 | + logger.log_error("Failed to load psuutil", True) |
| 87 | + sys.exit(PSUUTIL_LOAD_ERROR) |
40 | 88 |
|
41 | | - state_db = self.db_connect(swsscommon.STATE_DB) |
| 89 | + # Connect to STATE_DB and create psu/chassis info tables |
| 90 | + state_db = DaemonBase.db_connect(swsscommon.STATE_DB) |
42 | 91 | psu_tbl = swsscommon.Table(state_db, "PSU_INFO") |
43 | 92 | chassis_tbl = swsscommon.Table(state_db, "CHASSIS_INFO") |
| 93 | + |
| 94 | + # Post psu number info to STATE_DB |
44 | 95 | num_psus = platform_psuutil.get_num_psus() |
45 | | - fvs = swsscommon.FieldValuePairs([('num_psus', str(num_psus))]) |
| 96 | + fvs = swsscommon.FieldValuePairs([(CHASSIS_INFO_NUM_PSUS_FIELD, str(num_psus))]) |
46 | 97 | chassis_tbl.set('chassis 1', fvs) |
47 | 98 |
|
48 | | - # Start main loop to listen to the PSU change event. |
49 | | - self.log_info("Start main loop") |
50 | | - while True: |
| 99 | + # Start main loop |
| 100 | + logger.log_info("Start daemon main loop") |
| 101 | + |
| 102 | + while not self.stop.wait(PSU_INFO_UPDATE_PERIOD_SECS): |
51 | 103 | psu_db_update(platform_psuutil, psu_tbl, num_psus) |
52 | | - time.sleep(PSU_INFO_UPDATE_PERIOD_SECS) |
53 | 104 |
|
54 | | - # Clean all the information from DB and then exit |
| 105 | + logger.log_info("Stop daemon main loop") |
| 106 | + |
| 107 | + # Delete all the information from DB and then exit |
55 | 108 | for psu_index in range(1, num_psus + 1): |
56 | 109 | psu_tbl._del("PSU {}".format(psu_index)) |
| 110 | + |
57 | 111 | chassis_tbl._del('chassis 1') |
58 | | - return 1 |
59 | 112 |
|
60 | | -def psu_db_update(psuutil, psu_tbl, num_psus): |
61 | | - for psu_index in range(1, num_psus + 1): |
62 | | - fvs = swsscommon.FieldValuePairs([('presence', |
63 | | - 'true' if psuutil.get_psu_presence(psu_index) else 'false'), |
64 | | - ('status', |
65 | | - 'true' if psuutil.get_psu_status(psu_index) else 'false')]) |
66 | | - psu_tbl.set("PSU {}".format(psu_index), fvs) |
| 113 | + logger.log_info("Shutting down...") |
| 114 | + |
| 115 | +# |
| 116 | +# Main ========================================================================= |
| 117 | +# |
67 | 118 |
|
68 | 119 | def main(): |
69 | | - daemon_psud = DaemonPsud() |
70 | | - if not daemon_psud: |
71 | | - print "Failed to load psu daemon utilities" |
72 | | - sys.exit(1) |
| 120 | + psud = DaemonPsud() |
| 121 | + if not psud: |
| 122 | + logger.log_error("Failed to instantiate PSU daemon") |
| 123 | + sys.exit(DAEMON_INIT_ERROR) |
73 | 124 |
|
74 | | - daemon_psud.run() |
| 125 | + psud.run() |
75 | 126 |
|
76 | 127 | if __name__ == '__main__': |
77 | 128 | main() |
0 commit comments