root/src/noitd.c

Revision 229c7f9e18cc5409c42a955a656fdb31df1f7462, 8.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 1 month ago)

use 0.0.2 APIs to apply ACLs to reverse connections

  • 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
66 #include "noit_mtev_bridge.h"
67 #include "noit_jlog_listener.h"
68 #include "noit_check_rest.h"
69 #include "noit_livestream_listener.h"
70 #include "noit_module.h"
71 #include "noit_conf_checks.h"
72 #include "noit_filters.h"
73
74 #define APPNAME "noit"
75 #define CHILD_WATCHDOG_TIMEOUT 5 /*seconds*/
76
77 static char *config_file = ETC_DIR "/" APPNAME ".conf";
78 static char *xpath = NULL;
79 static const char *droptouser = NULL;
80 static const char *droptogroup = NULL;
81 static const char *chrootpath = NULL;
82 static int foreground = 0;
83 static int debug = 0;
84 static int strict_module_load = 0;
85 static char *glider = NULL;
86
87 #include "man/noitd.usage.h"
88 static void usage(const char *progname) {
89   printf("Usage for %s:\n", progname);
90 #ifdef NOITD_USAGE
91   assert(write(STDOUT_FILENO,
92                NOITD_USAGE,
93                sizeof(NOITD_USAGE)-1) == sizeof(NOITD_USAGE)-1);
94 #else
95   printf("\nError in usage, build problem.\n");
96 #endif
97   return;
98 }
99
100 void parse_clargs(int argc, char **argv) {
101   int c;
102   while((c = getopt(argc, argv, "x:Mhc:dDu:g:n:t:l:L:G:")) != EOF) {
103     switch(c) {
104       case 'x':
105         xpath = strdup(optarg);
106         foreground = 1;
107         break;
108       case 'G':
109         glider = strdup(optarg);
110         break;
111       case 'M':
112         strict_module_load = 1;
113         break;
114       case 'h':
115         usage(argv[0]);
116         exit(1);
117         break;
118       case 'l':
119         mtev_main_enable_log(optarg);
120         break;
121       case 'L':
122         mtev_main_disable_log(optarg);
123         break;
124       case 'n':
125         {
126           char *cp = optarg ? strchr(optarg, ':') : NULL;
127           if(!cp) mtev_listener_skip(optarg, 0);
128           else {
129             if(cp == optarg) optarg = NULL;
130             *cp++ = '\0';
131             mtev_listener_skip(optarg, atoi(cp));
132           }
133         }
134         break;
135       case 'u':
136         droptouser = strdup(optarg);
137         break;
138       case 'g':
139         droptogroup = strdup(optarg);
140         break;
141       case 't':
142         chrootpath = strdup(optarg);
143         break;
144       case 'c':
145         config_file = strdup(optarg);
146         break;
147       case 'D':
148         foreground++;
149         break;
150       case 'd':
151         debug++;
152         break;
153       default:
154         break;
155     }
156   }
157 }
158
159 static int __reload_needed = 0;
160 static void request_conf_reload(int sig) {
161   if(sig == SIGHUP) {
162     __reload_needed = 1;
163   }
164 }
165 static int notice_hup(eventer_t e, int mask, void *unused, struct timeval *now) {
166   if(__reload_needed) {
167     mtevL(noit_error, "SIGHUP received, performing reload\n");
168     if(mtev_conf_load(config_file) == -1) {
169       mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
170       exit(-1);
171     }
172     noit_poller_reload(NULL);
173     __reload_needed = 0;
174   }
175   return 0;
176 }
177
178 static int noit_console_stopword(const char *word) {
179   return(!strcmp(word, "check") ||
180          !strcmp(word, "noit") ||
181          !strcmp(word, "filterset") ||
182          !strcmp(word, "config"));
183 }
184 const char *reverse_prefix = "noit/";
185 const char *reverse_prefix_cns[] = { NULL };
186
187 static int child_main() {
188   eventer_t e;
189   char noit_version[80];
190
191   /* Send out a birth notice. */
192   mtev_watchdog_child_heartbeat();
193   mtev_override_console_stopword(noit_console_stopword);
194
195   /* Load our config...
196    * to ensure it is current w.r.t. to this child starting */
197   if(mtev_conf_load(config_file) == -1) {
198     mtevL(noit_error, "Cannot load config: '%s'\n", config_file);
199     exit(2);
200   }
201   if(xpath) {
202     int cnt, i;
203     mtev_conf_section_t *parts = NULL;
204     parts = mtev_conf_get_sections(NULL, xpath, &cnt);
205     if(cnt == 0) exit(2);
206     for(i=0; i<cnt; i++) {
207       fprintf(stdout, "%d: ", i); fflush(stdout);
208       mtev_conf_write_section(parts[i], 1);
209     }
210     free(parts);
211     exit(0);
212   }
213
214   mtev_log_reopen_all();
215   mtevL(noit_notice, "process starting: %d\n", (int)getpid());
216   mtev_log_go_asynch();
217
218   signal(SIGHUP, request_conf_reload);
219
220   /* initialize the eventer */
221   if(eventer_init() == -1) {
222     mtevL(noit_stderr, "Cannot initialize eventer\n");
223     exit(-1);
224   }
225   /* rotation init requires, eventer_init() */
226   mtev_conf_log_init_rotate(APPNAME, mtev_false);
227
228   /* Setup our heartbeat */
229   mtev_watchdog_child_eventer_heartbeat();
230
231   e = eventer_alloc();
232   e->mask = EVENTER_RECURRENT;
233   e->callback = notice_hup;
234   eventer_add_recurrent(e);
235
236   /* Initialize all of our listeners */
237   mtev_console_init(APPNAME);
238   mtev_console_conf_init();
239   mtev_capabilities_listener_init();
240   noit_build_version(noit_version, sizeof(noit_version));
241   mtev_capabilities_add_feature("noit", noit_version);
242   mtev_http_rest_init();
243   mtev_reverse_socket_init(reverse_prefix, reverse_prefix_cns);
244   mtev_reverse_socket_acl(mtev_reverse_socket_denier);
245   mtev_events_rest_init();
246   noit_console_conf_checks_init();
247   noit_jlog_listener_init();
248   noit_check_rest_init();
249   noit_filters_rest_init();
250   noit_livestream_listener_init();
251
252   mtev_dso_init();
253   noit_module_init();
254   mtev_dso_post_init();
255   if(strict_module_load &&
256      (mtev_dso_load_failures() > 0 || noit_module_load_failures() > 0)) {
257     mtevL(noit_stderr, "Failed to load some modules and -M given.\n");
258     exit(2);
259   }
260
261   mtev_listener_init(APPNAME);
262
263   /* Drop privileges */
264   mtev_conf_security_init(APPNAME, droptouser, droptogroup, chrootpath);
265
266   /* Prepare for launch... */
267   noit_filters_init();
268   noit_poller_init();
269
270   /* Write our log out, and setup a watchdog to write it out on change. */
271   mtev_conf_write_log(NULL);
272   mtev_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
273   mtev_conf_watch_and_journal_watchdog(mtev_conf_write_log, NULL);
274
275   eventer_loop();
276   return 0;
277 }
278
279 int main(int argc, char **argv) {
280   int lock = MTEV_LOCK_OP_LOCK;
281   noit_mtev_bridge_init();
282   mtev_memory_init();
283   parse_clargs(argc, argv);
284   if (xpath) lock = MTEV_LOCK_OP_NONE;
285   return mtev_main(APPNAME, config_file, debug, foreground,
286                    lock, glider, droptouser, droptogroup,
287                    child_main);
288 }
Note: See TracBrowser for help on using the browser.