00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023
00024 #ifdef HAVE_SYS_TYPES_H
00025 #include <sys/types.h>
00026 #endif
00027
00028 #include <sys/socket.h>
00029 #include <stdlib.h>
00030
00031 #ifdef HAVE_STRING_H
00032 #include <string.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038
00039 #include "monitor.h"
00040 #include "net.h"
00041 #include "ssl.h"
00042
00043
00044
00045 static void wait_stop(Process_T);
00046 static void wait_start(Process_T);
00047 static void do_stop(Process_T);
00048 static void do_start(Process_T);
00049 static void do_depend(Process_T, char *);
00050
00051
00064
00065
00066
00071 void control(char *action) {
00072
00073 Process_T p;
00074
00075 ASSERT(action);
00076
00077 for(p= processlist; p; p= p->next) {
00078 if(p->visited)
00079 continue;
00080 if(exist_daemon()) {
00081 d_check_process(p->name, action);
00082 } else {
00083 check_process(p->name, action);
00084 }
00085 }
00086
00087 reset_depend();
00088
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void control_group(char *G, char *action) {
00098
00099 Process_T p;
00100
00101 ASSERT(G);
00102 ASSERT(action);
00103
00104 for(p= processlist; p; p= p->next) {
00105 if(p->visited)
00106 continue;
00107 if(is(p->group, G)) {
00108 if(exist_daemon()) {
00109 d_check_process(p->name, action);
00110 } else {
00111 check_process(p->name, action);
00112 }
00113 }
00114 }
00115
00116 reset_depend();
00117
00118 }
00119
00120
00126 void d_check_process(char *P, char *action) {
00127
00128 int s;
00129 char req[2*STRLEN];
00130 char *auth= get_basic_authentication_header();
00131 ssl_connection *ssl= NULL;
00132
00133 ASSERT(P);
00134 ASSERT(action);
00135
00136 if(Run.httpdssl) {
00137
00138 ssl= new_ssl_connection(Run.httpsslpem, SSL_VERSION_AUTO);
00139
00140 }
00141
00142 s= create_socket(Run.bind_addr?Run.bind_addr:"localhost",
00143 Run.httpdport, SOCK_STREAM);
00144
00145 if(s < 0) {
00146
00147 error("%s: Cannot connect to the monit daemon. "
00148 "Did you start it with http support?\n", prog);
00149 goto error;
00150
00151 } else {
00152 snprintf(req, sizeof(req),
00153 "GET /%s?action=%s HTTP/1.0\r\n%s\r\n", P, action, auth);
00154
00155 if(ssl) {
00156
00157 if(!embed_ssl_socket(ssl, s)) {
00158
00159 fprintf(stdout, "Failed to establish SSL communication to monit"
00160 " server\n");
00161 goto error;
00162 }
00163
00164 send_ssl_socket(ssl, req, sizeof(req));
00165
00166 close_ssl_socket(ssl);
00167 close_socket(s);
00168
00169 } else {
00170
00171 sock_send(s, req, sizeof(req), 0);
00172 close_socket(s);
00173
00174 }
00175 }
00176
00177 if(Run.httpdssl) {
00178
00179 delete_ssl_socket(ssl);
00180
00181 }
00182
00183 error:
00184 free(auth);
00185
00186 }
00187
00188
00194 void check_process(char *P, char *action) {
00195
00196 Process_T p= NULL;
00197
00198 ASSERT(P);
00199 ASSERT(action);
00200
00201 if(NULL==(p= get_process(P))) {
00202 error("%s: Cannot %s program '%s' -- not found in %s\n",
00203 prog, action, P, Run.controlfile);
00204 return;
00205 }
00206
00207 if(is(action, "start")) {
00208
00209 if(is_process_running(p)) {
00210
00211 if(!p->do_validate) {
00212
00213 LOCK(Run.mutex)
00214 p->do_validate= TRUE;
00215 END_LOCK;
00216
00217 if(Run.debug)
00218 log("Monitoring enabled -- process %s\n", p->name);
00219
00220 }
00221
00222 return;
00223 }
00224
00225 if(!p->start) {
00226 error("%s: Start method not defined -- process %s\n",
00227 prog, P);
00228 return;
00229 }
00230
00231 do_depend(p, "stop");
00232 do_start(p);
00233 do_depend(p, "start");
00234
00235 } else if(is(action, "stop")) {
00236
00237 if(!p->stop) {
00238 error("%s: Stop method not defined -- process %s\n",
00239 prog, P);
00240 return;
00241 }
00242
00243 do_depend(p, "stop");
00244 do_stop(p);
00245
00246 } else if(is(action, "restart")) {
00247
00248 if(!p->start || !p->stop) {
00249 error("%s: Start or stop method not defined -- process %s\n",
00250 prog, P);
00251 return;
00252 }
00253
00254 do_depend(p, "stop");
00255 do_stop(p);
00256 do_start(p);
00257 do_depend(p, "start");
00258
00259 }
00260
00261 }
00262
00263
00264
00265
00266
00267 void reset_depend() {
00268
00269 Process_T p;
00270
00271 for (p= processlist; p; p= p->next) {
00272 p->visited= FALSE;
00273 p->depend_visited= FALSE;
00274 }
00275
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 static void do_start(Process_T p) {
00288
00289 ASSERT(p);
00290
00291 if(p->visited)
00292 return;
00293
00294 p->visited= TRUE;
00295
00296 if(p->dependantlist) {
00297
00298 Dependant_T d;
00299
00300 for(d= p->dependantlist; d; d= d->next ) {
00301
00302 Process_T dp= get_process(d->dependant);
00303 ASSERT(dp);
00304 do_start(dp);
00305
00306 }
00307 }
00308
00309 if(p->start && (!is_process_running(p))) {
00310 log("start: (%s) %s\n", p->name, p->start->arg[0]);
00311 spawn(p, p->start);
00312 wait_start(p);
00313 }
00314
00315 LOCK(Run.mutex)
00316 p->do_validate= TRUE;
00317 END_LOCK;
00318
00319 if(Run.debug)
00320 log("Monitoring enabled -- process %s\n", p->name);
00321
00322 }
00323
00324
00325
00326
00327
00328
00329 static void do_stop(Process_T p) {
00330
00331 ASSERT(p);
00332
00333 if(p->depend_visited)
00334 return;
00335
00336 p->depend_visited= TRUE;
00337
00338 LOCK(Run.mutex)
00339 p->do_validate= FALSE;
00340 END_LOCK;
00341
00342 if(Run.debug)
00343 log("Monitoring disabled -- process %s\n", p->name);
00344
00345 if(p->stop && is_process_running(p)) {
00346 log("stop: (%s) %s\n", p->name, p->stop->arg[0]);
00347 spawn(p, p->stop);
00348 wait_stop(p);
00349 }
00350
00351
00352 memset(p->procinfo, 0, sizeof *(p->procinfo));
00353
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 static void do_depend(Process_T p, char *action) {
00367
00368 Process_T parent;
00369
00370 ASSERT(p);
00371
00372 for(parent= processlist; parent; parent= parent->next) {
00373
00374 if(parent->dependantlist) {
00375
00376 Dependant_T d;
00377
00378 for(d= parent->dependantlist; d; d= d->next)
00379 if(is(d->dependant, p->name))
00380 break;
00381
00382 if(d) {
00383
00384 if(is(action, "start"))
00385 do_start(parent);
00386
00387 do_depend(parent, action);
00388
00389 if(is(action, "stop"))
00390 do_stop(parent);
00391
00392 }
00393 }
00394 }
00395 }
00396
00397
00398
00399
00400
00401
00402 static void wait_start(Process_T p) {
00403
00404 int max_tries= Run.polltime;
00405
00406 ASSERT(p);
00407
00408 while(max_tries--) {
00409 if(is_process_running(p))
00410 break;
00411 sleep(1);
00412 }
00413
00414 if(!is_process_running(p))
00415 log("%s: Warning process '%s' was not started\n", prog, p->name);
00416
00417 }
00418
00419
00420
00421
00422
00423
00424 static void wait_stop(Process_T p) {
00425
00426 int max_tries= Run.polltime;
00427
00428 ASSERT(p);
00429
00430 while(max_tries--) {
00431 if(!is_process_running(p))
00432 break;
00433 sleep(1);
00434 }
00435
00436 if(is_process_running(p))
00437 log("%s: Warning process '%s' was not stopped\n", prog, p->name);
00438
00439 }