root/src/noitd.c

Revision 616a8f8c6e7dd3416cc65102d161c9ce50235dda, 7.5 kB (checked in by Philip Maddox <pmaddox@circonus.com>, 1 month ago)

Don't Lock Noitd If Only Reading Stuff From Config

If a user is utilizing the "-x" option to pull values from
the config files, we don't need to acquire the lock. Only lock
if we actually need to acquire the process lock.

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