root/src/noitd.c

Revision 24d09e9a00ecb13c1b50e10fdf69a16369789b81, 7.5 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 1 day ago)

Change asynch loggers to start synchronous and require explicit change.

noit_log_go_a?synch() will make all logs (that support it) go
asynchronous or synchronous. This allows us to start up (parent)
with synchronous logging and then only enable that in the child.
This makes reopening the log file form the parent easier. Also
add support for reopening a single type of log and have the watchdog
reopen the "file" type logs in case they've been rotated out. Attempt
to make newly created log files have the same ownership as the
previous log file.

  • 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   noit_log_go_asynch();
198
199   signal(SIGHUP, request_conf_reload);
200
201   /* initialize the eventer */
202   if(eventer_init() == -1) {
203     noitL(noit_stderr, "Cannot initialize eventer\n");
204     exit(-1);
205   }
206   /* rotation init requires, eventer_init() */
207   noit_conf_log_init_rotate(APPNAME, noit_false);
208
209   /* Setup our heartbeat */
210   noit_watchdog_child_eventer_heartbeat();
211
212   e = eventer_alloc();
213   e->mask = EVENTER_RECURRENT;
214   e->callback = noitice_hup;
215   eventer_add_recurrent(e);
216
217   /* Initialize all of our listeners */
218   noit_console_init(APPNAME);
219   noit_console_conf_init();
220   noit_console_conf_checks_init();
221   noit_capabilities_listener_init();
222   noit_jlog_listener_init();
223   noit_http_rest_init();
224   noit_reverse_socket_init();
225   noit_events_rest_init();
226   noit_check_rest_init();
227   noit_filters_rest_init();
228   noit_livestream_listener_init();
229
230   noit_module_init();
231   if(strict_module_load && noit_module_load_failures() > 0) {
232     noitL(noit_stderr, "Failed to load some modules and -M given.\n");
233     exit(2);
234   }
235
236   /* Drop privileges */
237   if(chrootpath && noit_security_chroot(chrootpath)) {
238     noitL(noit_stderr, "Failed to chroot(), exiting.\n");
239     exit(2);
240   }
241   if(noit_security_usergroup(droptouser, droptogroup, noit_false)) {
242     noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
243     exit(2);
244   }
245
246   /* Prepare for launch... */
247   noit_filters_init();
248   noit_poller_init();
249   noit_listener_init(APPNAME);
250
251   /* Write our log out, and setup a watchdog to write it out on change. */
252   noit_conf_write_log(NULL);
253   noit_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
254   noit_conf_watch_and_journal_watchdog(noit_conf_write_log, NULL);
255
256   eventer_loop();
257   return 0;
258 }
259
260 int main(int argc, char **argv) {
261   int lock = NOIT_LOCK_OP_LOCK;
262   parse_clargs(argc, argv);
263   if (xpath) lock = NOIT_LOCK_OP_NONE;
264   return noit_main(APPNAME, config_file, debug, foreground,
265                    lock, glider, droptouser, droptogroup,
266                    child_main);
267 }
Note: See TracBrowser for help on using the browser.