comparison extensions/rt_default/rt_default.c @ 1336:cec0812038bb

rt_default: add reload support. When SIGUSR1 is sent to the freeDiameter process, rt_default reloads its config file. Written for Effortel Technologies SA, published with their consent.
author Thomas Klausner <tk@giga.or.at>
date Tue, 09 Apr 2019 15:46:50 +0200
parents f937feb72734
children 566bb46cc73f
comparison
equal deleted inserted replaced
1335:870eecffa3fe 1336:cec0812038bb
35 35
36 /* 36 /*
37 * Configurable routing of messages for freeDiameter. 37 * Configurable routing of messages for freeDiameter.
38 */ 38 */
39 39
40 #include <signal.h>
41
40 #include "rt_default.h" 42 #include "rt_default.h"
43
44 #define MODULE_NAME "rt_default"
45
46 #include <pthread.h>
47
48 static pthread_rwlock_t rtd_lock;
49
50 static char *rtd_config_file;
41 51
42 /* The callback called on new messages */ 52 /* The callback called on new messages */
43 static int rtd_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates) 53 static int rtd_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
44 { 54 {
45 struct msg * msg = *pmsg; 55 struct msg * msg = *pmsg;
46 TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); 56 TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
57 int ret;
47 58
48 CHECK_PARAMS(msg && candidates); 59 CHECK_PARAMS(msg && candidates);
49 60
61 if (pthread_rwlock_rdlock(&rtd_lock) != 0) {
62 fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME);
63 return 0;
64 }
50 /* Simply pass it to the appropriate function */ 65 /* Simply pass it to the appropriate function */
51 if (FD_IS_LIST_EMPTY(candidates)) { 66 if (FD_IS_LIST_EMPTY(candidates)) {
52 return 0; 67 ret = 0;
53 } else { 68 } else {
54 return rtd_process( msg, candidates ); 69 ret = rtd_process( msg, candidates );
55 } 70 }
71 if (pthread_rwlock_unlock(&rtd_lock) != 0) {
72 fd_log_notice("%s: read-unlock failed after rtd_out, exiting", MODULE_NAME);
73 exit(1);
74 }
75 return ret;
56 } 76 }
57 77
58 /* handler */ 78 /* handler */
59 static struct fd_rt_out_hdl * rtd_hdl = NULL; 79 static struct fd_rt_out_hdl * rtd_hdl = NULL;
60 80
81 static volatile int in_signal_handler = 0;
82
83 /* signal handler */
84 static void sig_hdlr(void)
85 {
86 if (in_signal_handler) {
87 fd_log_error("%s: already handling a signal, ignoring new one", MODULE_NAME);
88 return;
89 }
90 in_signal_handler = 1;
91
92 if (pthread_rwlock_wrlock(&rtd_lock) != 0) {
93 fd_log_error("%s: locking failed, aborting config reload", MODULE_NAME);
94 return;
95 }
96 rtd_conf_reload(rtd_config_file);
97 if (pthread_rwlock_unlock(&rtd_lock) != 0) {
98 fd_log_error("%s: unlocking failed after config reload, exiting", MODULE_NAME);
99 exit(1);
100 }
101
102 fd_log_notice("%s: reloaded configuration", MODULE_NAME);
103
104 in_signal_handler = 0;
105 }
106
107
61 /* entry point */ 108 /* entry point */
62 static int rtd_entry(char * conffile) 109 static int rtd_entry(char * conffile)
63 { 110 {
64 TRACE_ENTRY("%p", conffile); 111 TRACE_ENTRY("%p", conffile);
65 112
113 rtd_config_file = conffile;
114 pthread_rwlock_init(&rtd_lock, NULL);
115
116 if (pthread_rwlock_wrlock(&rtd_lock) != 0) {
117 fd_log_notice("%s: write-lock failed, aborting", MODULE_NAME);
118 return EDEADLK;
119 }
120
66 /* Initialize the repo */ 121 /* Initialize the repo */
67 CHECK_FCT( rtd_init() ); 122 CHECK_FCT( rtd_init() );
68 123
69 /* Parse the configuration file */ 124 /* Parse the configuration file */
70 CHECK_FCT( rtd_conf_handle(conffile) ); 125 CHECK_FCT( rtd_conf_handle(conffile) );
71 126
127 if (pthread_rwlock_unlock(&rtd_lock) != 0) {
128 fd_log_notice("%s: write-unlock failed, aborting", MODULE_NAME);
129 return EDEADLK;
130 }
131
132 /* Register reload callback */
133 CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr));
134
72 #if 0 135 #if 0
73 /* Dump the rules */ 136 /* Dump the rules */
74 rtd_dump(); 137 rtd_dump();
75 #endif /* 0 */ 138 #endif /* 0 */
76 139
89 /* Unregister the cb */ 152 /* Unregister the cb */
90 CHECK_FCT_DO( fd_rt_out_unregister ( rtd_hdl, NULL ), /* continue */ ); 153 CHECK_FCT_DO( fd_rt_out_unregister ( rtd_hdl, NULL ), /* continue */ );
91 154
92 /* Destroy the data */ 155 /* Destroy the data */
93 rtd_fini(); 156 rtd_fini();
94 157
158 pthread_rwlock_destroy(&rtd_lock);
159
95 /* Done */ 160 /* Done */
96 return ; 161 return ;
97 } 162 }
98 163
99 EXTENSION_ENTRY("rt_default", rtd_entry); 164 EXTENSION_ENTRY(MODULE_NAME, rtd_entry);
"Welcome to our mercurial repository"