root/src/noitd.c

Revision d67f22b57d0e1b25242dfcb7f7a14586730d03d7, 8.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 months ago)

hook up clustering configs

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007-2010, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  * Copyright (c) 2015, Circonus, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  *       copyright notice, this list of conditions and the following
14  *       disclaimer in the documentation and/or other materials provided
15  *       with the distribution.
16  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
17  *       of its contributors may be used to endorse or promote products
18  *       derived from this software without specific prior written
19  *       permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "noit_config.h"
35 #include "noit_version.h"
36 #include <mtev_defines.h>
37
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <sys/mman.h>
45 #include <signal.h>
46 #ifdef HAVE_SYS_WAIT_H
47 #include <sys/wait.h>
48 #endif
49
50 #include <mtev_main.h>
51 #include <eventer/eventer.h>
52 #include <mtev_memory.h>
53 #include <mtev_log.h>
54 #include <mtev_hash.h>
55 #include <mtev_security.h>
56 #include <mtev_watchdog.h>
57 #include <mtev_lockfile.h>
58 #include <mtev_listener.h>
59 #include <mtev_console.h>
60 #include <mtev_rest.h>
61 #include <mtev_reverse_socket.h>
62 #include <mtev_capabilities_listener.h>
63 #include <mtev_conf.h>
64 #include <mtev_events_rest.h>
65 #include <mtev_cluster.h>
66
67 #include "noit_mtev_bridge.h"
68 #include "noit_jlog_listener.h"
69 #include "noit_check_rest.h"
70 #include "noit_livestream_listener.h"
71 #include "noit_module.h"
72 #include "noit_conf_checks.h"
73 #include "noit_filters.h"
74
75 #define APPNAME "noit"
76 #define CHILD_WATCHDOG_TIMEOUT 5 /*seconds*/
77
78 static char *config_file = ETC_DIR "/" APPNAME ".conf";
79 static char *xpath = NULL;
80 static const char *droptouser = NULL;
81 static const char *droptogroup = NULL;
82 static const char *chrootpath = NULL;
83 static int foreground = 0;
84 static int debug = 0;
85 static int strict_module_load = 0;
86 static char *glider = NULL;
87
88 #include "man/noitd.usage.h"
89 static void usage(const char *progname) {
90   printf("Usage for %s:\n", progname);
91 #ifdef NOITD_USAGE
92   assert(write(STDOUT_FILENO,
93                NOITD_USAGE,
94                sizeof(NOITD_USAGE)-1) == sizeof(NOITD_USAGE)-1);
95 #else
96   printf("\nError in usage, build problem.\n");
97 #endif
98   return;
99 }
100
101 void parse_clargs(int argc, char **argv) {
102   int c;
103   while((c = getopt(argc, argv, "x:Mhc:dDu:g:n:t:l:L:G:")) != EOF) {
104     switch(c) {
105       case 'x':
106         xpath = strdup(optarg);
107         foreground = 1;
108         break;
109       case 'G':
110         glider = strdup(optarg);
111         break;
112       case 'M':
113         strict_module_load = 1;
114         break;
115       case 'h':
116         usage(argv[0]);
117         exit(1);
118         break;
119       case 'l':
120         mtev_main_enable_log(optarg);
121         break;
122       case 'L':
123         mtev_main_disable_log(optarg);
124         break;
125       case 'n':
126         {
127           char *cp = optarg ? strchr(optarg, ':') : NULL;
128           if(!cp) mtev_listener_skip(optarg, 0);
129           else {
130             if(cp == optarg) optarg = NULL;
131             *cp++ = '\0';
132             mtev_listener_skip(optarg, atoi(cp));
133           }
134         }
135         break;
136       case 'u':
137         droptouser = strdup(optarg);
138         break;
139       case 'g':
140         droptogroup = strdup(optarg);
141         break;
142       case 't':
143         chrootpath = strdup(optarg);
144         break;
145       case 'c':
146         config_file = strdup(optarg);
147         break;
148       case 'D':
149         foreground++;
150         break;
151       case 'd':
152         debug++;
153         break;
154       default:
155         break;
156     }
157   }
158 }
159
160 static int __reload_needed = 0;
161 static void request_conf_reload(int sig) {
162   if(sig == SIGHUP) {
163     __reload_needed = 1;
164   }
165 }
166 static int notice_hup(eventer_t e, int mask, void *unused, struct timeval *now) {
167   if(__reload_needed) {
168     mtevL(noit_error, "SIGHUP received, performing reload\n");
169     if(mtev_conf_load(config_file) == -1) {
170       mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
171       exit(-1);
172     }
173     noit_poller_reload(NULL);
174     __reload_needed = 0;
175   }
176   return 0;
177 }
178
179 static int noit_console_stopword(const char *word) {
180   return(!strcmp(word, "check") ||
181          !strcmp(word, "noit") ||
182          !strcmp(word, "filterset") ||
183          !strcmp(word, "config"));
184 }
185 const char *reverse_prefix = "noit/";
186 const char *reverse_prefix_cns[] = { NULL };
187
188 static int child_main() {
189   eventer_t e;
190   char noit_version[80];
191
192   /* Send out a birth notice. */
193   mtev_watchdog_child_heartbeat();
194   mtev_override_console_stopword(noit_console_stopword);
195
196   /* Load our config...
197    * to ensure it is current w.r.t. to this child starting */
198   if(mtev_conf_load(config_file) == -1) {
199     mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
200     exit(2);
201   }
202   if(xpath) {
203     int cnt, i;
204     mtev_conf_section_t *parts = NULL;
205     parts = mtev_conf_get_sections(NULL, xpath, &cnt);
206     if(cnt == 0) exit(2);
207     for(i=0; i<cnt; i++) {
208       fprintf(stdout, "%d: ", i); fflush(stdout);
209       mtev_conf_write_section(parts[i], 1);
210     }
211     free(parts);
212     exit(0);
213   }
214
215   mtev_log_reopen_all();
216   mtevL(noit_notice, "process starting: %d\n", (int)getpid());
217   mtev_log_go_asynch();
218
219   signal(SIGHUP, request_conf_reload);
220
221   /* initialize the eventer */
222   if(eventer_init() == -1) {
223     mtevL(noit_stderr, "Cannot initialize eventer\n");
224     exit(-1);
225   }
226   /* rotation init requires, eventer_init() */
227   mtev_conf_log_init_rotate(APPNAME, mtev_false);
228
229   /* Setup our heartbeat */
230   mtev_watchdog_child_eventer_heartbeat();
231
232   e = eventer_alloc();
233   e->mask = EVENTER_RECURRENT;
234   e->callback = notice_hup;
235   eventer_add_recurrent(e);
236
237   /* Initialize all of our listeners */
238   mtev_console_init(APPNAME);
239   mtev_console_conf_init();
240   mtev_capabilities_listener_init();
241   noit_build_version(noit_version, sizeof(noit_version));
242   mtev_capabilities_add_feature("noit", noit_version);
243   mtev_http_rest_init();
244   mtev_reverse_socket_init(reverse_prefix, reverse_prefix_cns);
245   mtev_reverse_socket_acl(mtev_reverse_socket_denier);
246   mtev_events_rest_init();
247   noit_console_conf_checks_init();
248   noit_jlog_listener_init();
249   noit_check_rest_init();
250   noit_filters_rest_init();
251   noit_livestream_listener_init();
252
253   mtev_dso_init();
254   noit_module_init();
255   mtev_dso_post_init();
256   if(strict_module_load &&
257      (mtev_dso_load_failures() > 0 || noit_module_load_failures() > 0)) {
258     mtevL(noit_stderr, "Failed to load some modules and -M given.\n");
259     exit(2);
260   }
261
262   mtev_listener_init(APPNAME);
263   mtev_cluster_init();
264
265   /* Drop privileges */
266   mtev_conf_security_init(APPNAME, droptouser, droptogroup, chrootpath);
267
268   /* Prepare for launch... */
269   noit_filters_init();
270   noit_poller_init();
271
272   /* Write our log out, and setup a watchdog to write it out on change. */
273   mtev_conf_write_log(NULL);
274   mtev_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
275   mtev_conf_watch_and_journal_watchdog(mtev_conf_write_log, NULL);
276
277   eventer_loop();
278   return 0;
279 }
280
281 int main(int argc, char **argv) {
282   int lock = MTEV_LOCK_OP_LOCK;
283   noit_mtev_bridge_init();
284   mtev_memory_init();
285   parse_clargs(argc, argv);
286   if (xpath) lock = MTEV_LOCK_OP_NONE;
287   return mtev_main(APPNAME, config_file, debug, foreground,
288                    lock, glider, droptouser, droptogroup,
289                    child_main);
290 }
Note: See TracBrowser for help on using the browser.