root/src/noit_main.c

Revision 559e017dc530d5467cb14742be11d9f328bf4e01, 7.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

use of these cause core dumps. testing testing testing.

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2011, 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 "utils/noit_log.h"
47 #include "noit_conf.h"
48 #include "utils/noit_security.h"
49 #include "utils/noit_watchdog.h"
50 #include "utils/noit_lockfile.h"
51 #include "eventer/eventer.h"
52
53 #define MAX_CLI_LOGS 128
54 static char *enable_logs[MAX_CLI_LOGS];
55 static int enable_logs_cnt = 0;
56 static char *disable_logs[MAX_CLI_LOGS];
57 static int disable_logs_cnt = 0;
58
59 void
60 noit_main_enable_log(const char *name) {
61   if(enable_logs_cnt >= MAX_CLI_LOGS) return;
62   enable_logs[enable_logs_cnt++] = strdup(name);
63 }
64 void
65 noit_main_disable_log(const char *name) {
66   if(disable_logs_cnt >= MAX_CLI_LOGS) return;
67   disable_logs[disable_logs_cnt++] = strdup(name);
68 }
69 static int
70 configure_eventer(const char *appname) {
71   int rv = 0;
72   noit_hash_table *table;
73   char appscratch[1024];
74
75   snprintf(appscratch, sizeof(appscratch), "/%s/eventer/config", appname);
76   table = noit_conf_get_hash(NULL, appscratch);
77   if(table) {
78     noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
79     const char *key, *value;
80     int klen;
81     while(noit_hash_next_str(table, &iter, &key, &klen, &value)) {
82       int subrv;
83       if((subrv = eventer_propset(key, value)) != 0)
84         rv = subrv;
85     }
86     noit_hash_destroy(table, free, free);
87     free(table);
88   }
89   return rv;
90 }
91
92 void cli_log_switches() {
93   int i;
94   noit_log_stream_t ls;
95   for(i=0; i<enable_logs_cnt; i++) {
96     ls = noit_log_stream_find(enable_logs[i]);
97     if(!ls) noitL(noit_error, "No such log: '%s'\n", enable_logs[i]);
98     if(ls && !ls->enabled) {
99       noitL(noit_error, "Enabling %s\n", enable_logs[i]);
100       ls->enabled = 1;
101     }
102   }
103   for(i=0; i<disable_logs_cnt; i++) {
104     ls = noit_log_stream_find(disable_logs[i]);
105     if(!ls) noitL(noit_error, "No such log: '%s'\n", enable_logs[i]);
106     if(ls && ls->enabled) {
107       noitL(noit_error, "Disabling %s\n", disable_logs[i]);
108       ls->enabled = 0;
109     }
110   }
111 }
112
113 int
114 noit_main(const char *appname,
115           const char *config_filename, int debug, int foreground,
116           const char *_glider,
117           const char *drop_to_user, const char *drop_to_group,
118           int (*passed_child_main)(void)) {
119   int fd, lockfd;
120   char conf_str[1024];
121   char lockfile[PATH_MAX];
122   char user[32], group[32];
123   char *trace_dir = NULL;
124   char appscratch[1024];
125   char *glider = (char *)_glider;
126    
127   /* First initialize logging, so we can log errors */
128   noit_log_init();
129   noit_log_stream_add_stream(noit_debug, noit_stderr);
130   noit_log_stream_add_stream(noit_error, noit_stderr);
131
132   /* Next load the configs */
133   noit_conf_init(appname);
134   if(noit_conf_load(config_filename) == -1) {
135     fprintf(stderr, "Cannot load config: '%s'\n", config_filename);
136     exit(-1);
137   }
138
139   /* Reinitialize the logging system now that we have a config */
140   snprintf(user, sizeof(user), "%d", getuid());
141   snprintf(group, sizeof(group), "%d", getgid());
142   if(noit_security_usergroup(drop_to_user, drop_to_group, noit_true)) {
143     noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
144     exit(-1);
145   }
146   noit_conf_log_init(appname);
147   cli_log_switches();
148   if(noit_security_usergroup(user, group, noit_true)) {
149     noitL(noit_stderr, "Failed to regain privileges, exiting.\n");
150     exit(-1);
151   }
152   if(debug)
153     noit_debug->enabled = 1;
154
155   snprintf(appscratch, sizeof(appscratch), "/%s/watchdog/@glider", appname);
156   if(!glider) noit_conf_get_string(NULL, appscratch, &glider);
157   noit_watchdog_glider(glider);
158   snprintf(appscratch, sizeof(appscratch), "/%s/watchdog/@tracedir", appname);
159   noit_conf_get_string(NULL, appscratch, &trace_dir);
160   if(trace_dir) noit_watchdog_glider_trace_dir(trace_dir);
161
162   /* Lastly, run through all other system inits */
163   snprintf(appscratch, sizeof(appscratch), "/%s/eventer/@implementation", appname);
164   if(!noit_conf_get_stringbuf(NULL, appscratch, conf_str, sizeof(conf_str))) {
165     noitL(noit_stderr, "Cannot find '%s' in configuration\n", appscratch);
166     exit(-1);
167   }
168   if(eventer_choose(conf_str) == -1) {
169     noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
170     exit(-1);
171   }
172   if(configure_eventer(appname) != 0) {
173     noitL(noit_stderr, "Cannot configure eventer\n");
174     exit(-1);
175   }
176
177   noit_watchdog_prefork_init();
178
179   if(chdir("/") != 0) {
180     noitL(noit_stderr, "Failed chdir(\"/\"): %s\n", strerror(errno));
181     exit(-1);
182   }
183
184   /* Acquire the lock so that we can throw an error if it doesn't work.
185    * If we've started -D, we'll have the lock.
186    * If not we will daemon and must reacquire the lock.
187    */
188   lockfd = -1;
189   lockfile[0] = '\0';
190   snprintf(appscratch, sizeof(appscratch), "/%s/@lockfile", appname);
191   if(noit_conf_get_stringbuf(NULL, appscratch,
192                              lockfile, sizeof(lockfile))) {
193     if((lockfd = noit_lockfile_acquire(lockfile)) < 0) {
194       noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
195       exit(-1);
196     }
197   }
198
199   if(foreground) return passed_child_main();
200
201   /* This isn't inherited across forks... */
202   if(lockfd >= 0) noit_lockfile_release(lockfd);
203
204   fd = open("/dev/null", O_RDWR);
205   dup2(fd, STDIN_FILENO);
206   dup2(fd, STDOUT_FILENO);
207   dup2(fd, STDERR_FILENO);
208   if(fork()) exit(0);
209   setsid();
210   if(fork()) exit(0);
211
212   /* Reacquire the lock */
213   if(*lockfile) {
214     if(noit_lockfile_acquire(lockfile) < 0) {
215       noitL(noit_stderr, "Failed to acquire lock: %s\n", lockfile);
216       exit(-1);
217     }
218   }
219
220   signal(SIGHUP, SIG_IGN);
221   return noit_watchdog_start_child("noitd", passed_child_main, 0);
222 }
Note: See TracBrowser for help on using the browser.