root/src/stratcond.c

Revision 304ec80b8cf842fc0abe5f9029790908b6455957, 7.6 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 days ago)

Convert to libmtev.

  • 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
36 #include <assert.h>
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   assert(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 = "stratcon/";
178 const char *reverse_prefix_cns[] = { "noit/", NULL };
179
180 static int child_main() {
181   char conf_str[1024];
182
183   mtev_watchdog_child_heartbeat();
184
185   /* Next (re)load the configs */
186   if(mtev_conf_load(config_file) == -1) {
187     fprintf(stderr, "Cannot load config: '%s'\n", config_file);
188     exit(2);
189   }
190
191   mtev_log_reopen_all();
192   mtevL(noit_notice, "process starting: %d\n", (int)getpid());
193   mtev_log_go_asynch();
194
195   /* Lastly, run through all other system inits */
196   if(!mtev_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
197                               conf_str, sizeof(conf_str))) {
198     mtevL(noit_stderr, "Cannot find '%s' in configuration\n",
199           "/" APPNAME "/eventer/@implementation");
200     exit(2);
201   }
202   if(eventer_choose(conf_str) == -1) {
203     mtevL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
204     exit(2);
205   }
206   if(configure_eventer() != 0) {
207     mtevL(noit_stderr, "Cannot configure eventer\n");
208     exit(2);
209   }
210   if(eventer_init() == -1) {
211     mtevL(noit_stderr, "Cannot init eventer %s\n", conf_str);
212     exit(2);
213   }
214   /* rotation init requires, eventer_init() */
215   mtev_conf_log_init_rotate(APPNAME, mtev_false);
216
217   mtev_watchdog_child_eventer_heartbeat();
218
219   mtev_console_init(APPNAME);
220   mtev_console_conf_init();
221   mtev_http_rest_init();
222   mtev_reverse_socket_init(reverse_prefix, reverse_prefix_cns);
223   mtev_events_rest_init();
224   stratcon_realtime_http_init(APPNAME);
225   mtev_capabilities_listener_init();
226   mtev_listener_init(APPNAME);
227
228   mtev_dso_init();
229   mtev_dso_post_init();
230   if(strict_module_load && mtev_dso_load_failures() > 0) {
231     mtevL(noit_stderr, "Failed to load some modules and -M given.\n");
232     exit(2);
233   }
234
235   if(stratcon_datastore_get_enabled())
236     stratcon_datastore_init();
237
238   /* Drop privileges */
239   mtev_conf_security_init(APPNAME, droptouser, droptogroup, chrootpath);
240
241   stratcon_jlog_streamer_init(APPNAME);
242
243   if(stratcon_iep_get_enabled())
244     stratcon_iep_init();
245   if(stratcon_datastore_get_enabled()) {
246     /* Write our log out, and setup a watchdog to write it out on change. */
247     stratcon_datastore_saveconfig(NULL);
248     mtev_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
249   }
250   else
251     mtev_conf_coalesce_changes(INT_MAX);
252
253   mtev_conf_watch_and_journal_watchdog(stratcon_datastore_saveconfig, NULL);
254
255   eventer_loop();
256   return 0;
257 }
258
259 int main(int argc, char **argv) {
260   noit_mtev_bridge_init();
261   mtev_memory_init();
262   parse_clargs(argc, argv);
263   return mtev_main(APPNAME, config_file, debug, foreground,
264                    MTEV_LOCK_OP_LOCK, glider, droptouser, droptogroup,
265                    child_main);
266 }
Note: See TracBrowser for help on using the browser.