root/src/stratcond.c

Revision 87c5db762537e0b7cfa9746cea9dde1ae1de0813, 6.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 2 years ago)

we need to heartbeat right off the bat

  • 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
33 #include "noit_defines.h"
34
35 #include <assert.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <limits.h>
42
43 #include "eventer/eventer.h"
44 #include "utils/noit_log.h"
45 #include "utils/noit_hash.h"
46 #include "utils/noit_security.h"
47 #include "utils/noit_watchdog.h"
48 #include "utils/noit_lockfile.h"
49 #include "noit_main.h"
50 #include "noit_listener.h"
51 #include "noit_console.h"
52 #include "noit_module.h"
53 #include "noit_conf.h"
54 #include "noit_rest.h"
55 #include "noit_capabilities_listener.h"
56 #include "stratcon_jlog_streamer.h"
57 #include "stratcon_datastore.h"
58 #include "stratcon_iep.h"
59 #include "stratcon_realtime_http.h"
60
61 #define APPNAME "stratcon"
62 static char *config_file = ETC_DIR "/" APPNAME ".conf";
63 static const char *droptouser = NULL;
64 static const char *droptogroup = NULL;
65 static const char *chrootpath = NULL;
66 static int foreground = 0;
67 static int debug = 0;
68 static int strict_module_load = 0;
69 static char *glider = NULL;
70
71 #include "man/stratcond.usage.h"
72 static void usage(const char *progname) {
73   printf("Usage for %s:\n", progname);
74 #ifdef STRATCOND_USAGE
75   assert(write(STDOUT_FILENO,
76               STRATCOND_USAGE,
77               sizeof(STRATCOND_USAGE)-1) == sizeof(STRATCOND_USAGE)-1);
78 #else
79   printf("\nError in usage, build problem.\n");
80 #endif
81   return;
82 }
83
84 void parse_clargs(int argc, char **argv) {
85   int c;
86   while((c = getopt(argc, argv, "Mrshc:dDu:g:t:l:L:G:")) != EOF) {
87     switch(c) {
88       case 'M':
89         strict_module_load = 1;
90         break;
91       case 'G':
92         glider = strdup(optarg);
93         break;
94       case 'l':
95         noit_main_enable_log(optarg);
96         break;
97       case 'L':
98         noit_main_disable_log(optarg);
99         break;
100       case 'r':
101         stratcon_iep_set_enabled(0);
102         break;
103       case 's':
104         stratcon_datastore_set_enabled(0);
105         break;
106       case 'h':
107         usage(argv[0]);
108         exit(1);
109         break;
110       case 'u':
111         droptouser = strdup(optarg);
112         break;
113       case 'g':
114         droptogroup = strdup(optarg);
115         break;
116       case 't':
117         chrootpath = strdup(optarg);
118         break;
119       case 'c':
120         config_file = strdup(optarg);
121         break;
122       case 'd':
123         debug++;
124         break;
125       case 'D':
126         foreground = 1;
127         break;
128       default:
129         break;
130     }
131   }
132 }
133
134 static
135 int configure_eventer() {
136   int rv = 0;
137   noit_hash_table *table;
138   table = noit_conf_get_hash(NULL, "/" APPNAME "/eventer/config");
139   if(table) {
140     noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
141     const char *key, *value;
142     int klen;
143     while(noit_hash_next_str(table, &iter, &key, &klen, &value)) {
144       int subrv;
145       if((subrv = eventer_propset(key, value)) != 0)
146         rv = subrv;
147     }
148     noit_hash_destroy(table, free, free);
149     free(table);
150   }
151   return rv;
152 }
153
154 static int child_main() {
155   char conf_str[1024];
156
157   noit_watchdog_child_heartbeat();
158
159   /* Next (re)load the configs */
160   if(noit_conf_load(config_file) == -1) {
161     fprintf(stderr, "Cannot load config: '%s'\n", config_file);
162     exit(2);
163   }
164
165   noit_log_reopen_all();
166
167   /* Lastly, run through all other system inits */
168   if(!noit_conf_get_stringbuf(NULL, "/" APPNAME "/eventer/@implementation",
169                               conf_str, sizeof(conf_str))) {
170     noitL(noit_stderr, "Cannot find '%s' in configuration\n",
171           "/" APPNAME "/eventer/@implementation");
172     exit(2);
173   }
174   if(eventer_choose(conf_str) == -1) {
175     noitL(noit_stderr, "Cannot choose eventer %s\n", conf_str);
176     exit(2);
177   }
178   if(configure_eventer() != 0) {
179     noitL(noit_stderr, "Cannot configure eventer\n");
180     exit(2);
181   }
182   if(eventer_init() == -1) {
183     noitL(noit_stderr, "Cannot init eventer %s\n", conf_str);
184     exit(2);
185   }
186   /* rotation init requires, eventer_init() */
187   noit_conf_log_init_rotate(APPNAME, noit_false);
188
189   noit_watchdog_child_eventer_heartbeat();
190
191   noit_console_init(APPNAME);
192   noit_console_conf_init();
193   noit_http_rest_init();
194   stratcon_realtime_http_init(APPNAME);
195   noit_capabilities_listener_init();
196   noit_listener_init(APPNAME);
197
198   noit_module_init();
199   if(strict_module_load && noit_module_load_failures() > 0) {
200     noitL(noit_stderr, "Failed to load some modules and -M given.\n");
201     exit(2);
202   }
203
204   if(stratcon_datastore_get_enabled())
205     stratcon_datastore_init();
206
207   /* Drop privileges */
208   if(chrootpath && noit_security_chroot(chrootpath)) {
209     noitL(noit_stderr, "Failed to chroot(), exiting.\n");
210     exit(-1);
211   }
212   if(noit_security_usergroup(droptouser, droptogroup, noit_false)) {
213     noitL(noit_stderr, "Failed to drop privileges, exiting.\n");
214     exit(-1);
215   }
216
217   stratcon_jlog_streamer_init(APPNAME);
218
219   if(stratcon_iep_get_enabled())
220     stratcon_iep_init();
221   if(stratcon_datastore_get_enabled()) {
222     /* Write our log out, and setup a watchdog to write it out on change. */
223     stratcon_datastore_saveconfig(NULL);
224     noit_conf_coalesce_changes(10); /* 10 seconds of no changes before we write */
225   }
226   else
227     noit_conf_coalesce_changes(INT_MAX);
228
229   noit_conf_watch_and_journal_watchdog(stratcon_datastore_saveconfig, NULL);
230
231   eventer_loop();
232   return 0;
233 }
234
235 int main(int argc, char **argv) {
236   parse_clargs(argc, argv);
237   return noit_main(APPNAME, config_file, debug, foreground,
238                    glider, droptouser, droptogroup, child_main);
239 }
Note: See TracBrowser for help on using the browser.