root/src/stratcond.c

Revision 70c30ef22f6d1312375e0392164d755db5824cb5, 7.8 kB (checked in by Phil Maddox <philip.maddox@circonus.com>, 5 days ago)

Use mtevAssert and mtevFatal Instead Of assert() and abort()

Use libmtev calls to safely flush logs and abort rather than calling
the assert and abort calls directly.

  • 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 <mtev_defines.h>
35 #include "noit_version.h"
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #include <fcntl.h>
42 #include <limits.h>
43
44 #include <eventer/eventer.h>
45 #include <mtev_memory.h>
46 #include <mtev_log.h>
47 #include <mtev_hash.h>
48 #include <mtev_security.h>
49 #include <mtev_watchdog.h>
50 #include <mtev_lockfile.h>
51 #include <mtev_main.h>
52 #include <mtev_listener.h>
53 #include <mtev_console.h>
54 #include <mtev_conf.h>
55 #include <mtev_rest.h>
56 #include <mtev_reverse_socket.h>
57 #include <mtev_events_rest.h>
58 #include <mtev_capabilities_listener.h>
59
60 #include "noit_mtev_bridge.h"
61 #include "noit_config.h"
62 #include "noit_module.h"
63 #include "stratcon_jlog_streamer.h"
64 #include "stratcon_datastore.h"
65 #include "stratcon_iep.h"
66 #include "stratcon_realtime_http.h"
67
68 #define APPNAME "stratcon"
69 static char *config_file = ETC_DIR "/" APPNAME ".conf";
70 static const char *droptouser = NULL;
71 static const char *droptogroup = NULL;
72 static const char *chrootpath = NULL;
73 static int foreground = 0;
74 static int debug = 0;
75 static int strict_module_load = 0;
76 static char *glider = NULL;
77
78 #include "man/stratcond.usage.h"
79 static void usage(const char *progname) {
80   printf("Usage for %s:\n", progname);
81 #ifdef STRATCOND_USAGE
82   mtevAssert(write(STDOUT_FILENO,
83               STRATCOND_USAGE,
84               sizeof(STRATCOND_USAGE)-1) == sizeof(STRATCOND_USAGE)-1);
85 #else
86   printf("\nError in usage, build problem.\n");
87 #endif
88   return;
89 }
90
91 void parse_clargs(int argc, char **argv) {
92   int c;
93   while((c = getopt(argc, argv, "Mrshc:dDu:g:n:t:l:L:G:")) != EOF) {
94     switch(c) {
95       case 'M':
96         strict_module_load = 1;
97         break;
98       case 'G':
99         glider = strdup(optarg);
100         break;
101       case 'l':
102         mtev_main_enable_log(optarg);
103         break;
104       case 'L':
105         mtev_main_disable_log(optarg);
106         break;
107       case 'n':
108         {
109           char *cp = strchr(optarg, ':');
110           if(!cp) mtev_listener_skip(optarg, 0);
111           else {
112             if(cp == optarg) {
113               *cp++ = '\0';
114               mtev_listener_skip(NULL, atoi(cp));
115             }
116             else {
117               *cp++ = '\0';
118               mtev_listener_skip(optarg, atoi(cp));
119             }
120           }
121         }
122         break;
123       case 'r':
124         stratcon_iep_set_enabled(0);
125         break;
126       case 's':
127         stratcon_datastore_set_enabled(0);
128         break;
129       case 'h':
130         usage(argv[0]);
131         exit(1);
132         break;
133       case 'u':
134         droptouser = strdup(optarg);
135         break;
136       case 'g':
137         droptogroup = strdup(optarg);
138         break;
139       case 't':
140         chrootpath = strdup(optarg);
141         break;
142       case 'c':
143         config_file = strdup(optarg);
144         break;
145       case 'd':
146         debug++;
147         break;
148       case 'D':
149         foreground++;
150         break;
151       default:
152         break;
153     }
154   }
155 }
156
157 static
158 int configure_eventer() {
159   int rv = 0;
160   mtev_hash_table *table;
161   table = mtev_conf_get_hash(NULL, "/" APPNAME "/eventer/config");
162   if(table) {
163     mtev_hash_iter iter = MTEV_HASH_ITER_ZERO;
164     const char *key, *value;
165     int klen;
166     while(mtev_hash_next_str(table, &iter, &key, &klen, &value)) {
167       int subrv;
168       if((subrv = eventer_propset(key, value)) != 0)
169         rv = subrv;
170     }
171     mtev_hash_destroy(table, free, free);
172     free(table);
173   }
174   return rv;
175 }
176
177 const char *reverse_prefix = "noit/"; /* namespace out connections */
178 const char *reverse_prefix_cns[] = { "noit/", NULL };
179
180 static int child_main() {
181   char conf_str[1024];
182   char stratcon_version[80];
183
184   mtev_watchdog_child_heartbeat();
185
186   /* Next (re)load the configs */
187   if(mtev_conf_load(config_file) == -1) {
188     fprintf(stderr, "Cannot load config: '%s'\n", config_file);
189     exit(2);
190   }
191
192   mtev_log_reopen_all();
193   mtevL(noit_notice, "process starting: %d\n", (int)getpid());
194   mtev_log_go_asynch();
195
196   /* Lastly, run through all other system inits */
197   if(!mtev_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
198                               conf_str, sizeof(conf_str))) {
199     mtevL(noit_stderr, "Cannot find '%s' in configuration\n",
200           "/" APPNAME "/eventer/@implementation");
201     exit(2);
202   }
203   if(eventer_choose(conf_str) == -1) {
204     mtevL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
205     exit(2);
206   }
207   if(configure_eventer() != 0) {
208     mtevL(noit_stderr, "Cannot configure eventer\n");
209     exit(2);
210   }
211   if(eventer_init() == -1) {
212     mtevL(noit_stderr, "Cannot init eventer %s\n", conf_str);
213     exit(2);
214   }
215   /* rotation init requires, eventer_init() */
216   mtev_conf_log_init_rotate(APPNAME, mtev_false);
217
218   mtev_watchdog_child_eventer_heartbeat();
219
220   mtev_console_init(APPNAME);
221   mtev_console_conf_init();
222   mtev_http_rest_init();
223   mtev_reverse_socket_init(reverse_prefix, reverse_prefix_cns);
224   mtev_reverse_socket_acl(mtev_reverse_socket_denier);
225   mtev_events_rest_init();
226   stratcon_realtime_http_init(APPNAME);
227   mtev_capabilities_listener_init();
228   noit_build_version(stratcon_version, sizeof(stratcon_version));
229   mtev_capabilities_add_feature("stratcon", stratcon_version);
230   mtev_listener_init(APPNAME);
231
232   mtev_dso_init();
233   mtev_dso_post_init();
234   if(strict_module_load && mtev_dso_load_failures() > 0) {
235     mtevL(noit_stderr, "Failed to load some modules and -M given.\n");
236     exit(2);
237   }
238
239   if(stratcon_datastore_get_enabled())
240     stratcon_datastore_init();
241
242   /* Drop privileges */
243   mtev_conf_security_init(APPNAME, droptouser, droptogroup, chrootpath);
244
245   stratcon_jlog_streamer_init(APPNAME);
246
247   if(stratcon_iep_get_enabled())
248     stratcon_iep_init();
249   if(stratcon_datastore_get_enabled()) {
250     /* Write our log out, and setup a watchdog to write it out on change. */
251     stratcon_datastore_saveconfig(NULL);
252     mtev_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
253   }
254   else
255     mtev_conf_coalesce_changes(INT_MAX);
256
257   mtev_conf_watch_and_journal_watchdog(stratcon_datastore_saveconfig, NULL);
258
259   eventer_loop();
260   return 0;
261 }
262
263 int main(int argc, char **argv) {
264   noit_mtev_bridge_init();
265   mtev_memory_init();
266   parse_clargs(argc, argv);
267   return mtev_main(APPNAME, config_file, debug, foreground,
268                    MTEV_LOCK_OP_LOCK, glider, droptouser, droptogroup,
269                    child_main);
270 }
Note: See TracBrowser for help on using the browser.