96 |
|
|
97 |
static void do_validate(Service_T, ProcessTree_T *, int); |
static void do_validate(Service_T, ProcessTree_T *, int); |
98 |
static int do_not_validate(Service_T); |
static int do_not_validate(Service_T); |
|
static void vlog(char *, int, Service_T, char *,...); |
|
99 |
static int eval_actions(int, Service_T, char *, char *, int); |
static int eval_actions(int, Service_T, char *, char *, int); |
100 |
|
|
101 |
|
|
288 |
char report[STRLEN]; |
char report[STRLEN]; |
289 |
|
|
290 |
for(tl= s->timestamplist; tl; tl= tl->next) { |
for(tl= s->timestamplist; tl; tl= tl->next) { |
|
|
|
291 |
if(!check_timestamp_item(s, tl, report)) { |
if(!check_timestamp_item(s, tl, report)) { |
|
|
|
292 |
if (! eval_actions(tl->action, s, report, "timestamp", |
if (! eval_actions(tl->action, s, report, "timestamp", |
293 |
EVENT_TIMESTAMP)) { |
EVENT_TIMESTAMP)) { |
|
|
|
294 |
return FALSE; |
return FALSE; |
|
|
|
295 |
} |
} |
|
|
|
296 |
} |
} |
297 |
|
} |
|
} |
|
298 |
|
|
299 |
return TRUE; |
return TRUE; |
300 |
|
|
310 |
struct stat stat_buf; |
struct stat stat_buf; |
311 |
|
|
312 |
if(stat(s->path, &stat_buf) != 0) { |
if(stat(s->path, &stat_buf) != 0) { |
313 |
|
Event_post(s, EVENT_RESTART, |
314 |
log("'%s' doesn't exist\n", s->name); |
"Reason: directory '%s' doesn't exist\n", s->name); |
|
Event_post(s, EVENT_RESTART, "Reason: directory doesn't exist\n"); |
|
315 |
return FALSE; |
return FALSE; |
|
|
|
316 |
} |
} |
317 |
|
|
318 |
if(!S_ISDIR(stat_buf.st_mode)) { |
if(!S_ISDIR(stat_buf.st_mode)) { |
319 |
|
Event_post(s, EVENT_RESTART, |
320 |
log("'%s' is not directory\n", s->name); |
"Reason: '%s' is not directory\n", s->name); |
|
Event_post(s, EVENT_RESTART, "Reason: object is not directory\n"); |
|
321 |
return FALSE; |
return FALSE; |
|
|
|
322 |
} |
} |
323 |
|
|
324 |
if( s->perm != -1 && (stat_buf.st_mode & 07777) != s->perm ) { |
if( s->perm != -1 && (stat_buf.st_mode & 07777) != s->perm ) { |
325 |
|
Event_post(s, EVENT_RESTART, |
326 |
log("'%s' permission test failed -- current permission: %o\n", |
"Reason: '%s' permission test failed -- " |
327 |
s->name, stat_buf.st_mode&07777); |
"current permission: %o\n", s->name, stat_buf.st_mode&07777); |
|
Event_post(s, EVENT_RESTART, "Reason: permission test failed: %o\n", |
|
|
stat_buf.st_mode&07777); |
|
328 |
return FALSE; |
return FALSE; |
|
|
|
329 |
} |
} |
330 |
|
|
331 |
DEBUG("'%s' directory permission check passed [current permission=%o]\n", |
DEBUG("'%s' directory permission check passed [current permission=%o]\n", |
345 |
struct stat stat_buf; |
struct stat stat_buf; |
346 |
|
|
347 |
if(stat(s->path, &stat_buf) != 0) { |
if(stat(s->path, &stat_buf) != 0) { |
348 |
|
Event_post(s, EVENT_RESTART, "Reason: file '%s' doesn't exist\n", s->name); |
|
log("'%s' doesn't exist\n", s->name); |
|
|
Event_post(s, EVENT_RESTART, "Reason: file doesn't exist\n"); |
|
349 |
return FALSE; |
return FALSE; |
|
|
|
350 |
} |
} |
351 |
|
|
352 |
if(!S_ISREG(stat_buf.st_mode)) { |
if(!S_ISREG(stat_buf.st_mode)) { |
353 |
|
Event_post(s, EVENT_RESTART, "Reason: '%s' is not regular file\n", s->name); |
|
log("'%s' is not regular file\n", s->name); |
|
|
Event_post(s, EVENT_RESTART, "Reason: object is not file\n"); |
|
354 |
return FALSE; |
return FALSE; |
|
|
|
355 |
} |
} |
356 |
|
|
357 |
if( s->perm != -1 && (stat_buf.st_mode & 07777) != s->perm ) { |
if( s->perm != -1 && (stat_buf.st_mode & 07777) != s->perm ) { |
358 |
|
Event_post(s, EVENT_RESTART, |
359 |
log("'%s' permission test failed -- current permission: %o\n", |
"Reason: '%s' permission test failed -- " |
360 |
s->name, stat_buf.st_mode&07777); |
"current permission: %o\n", |
361 |
Event_post(s, EVENT_RESTART, "Reason: permission test failed: %o\n", |
s->name, stat_buf.st_mode&07777); |
|
stat_buf.st_mode&07777); |
|
362 |
return FALSE; |
return FALSE; |
|
|
|
363 |
} |
} |
364 |
|
|
365 |
DEBUG("'%s' file permission check passed [current permission=%o]\n", |
DEBUG("'%s' file permission check passed [current permission=%o]\n", |
381 |
|
|
382 |
/* Test devices */ |
/* Test devices */ |
383 |
if(s->devicelist) { |
if(s->devicelist) { |
|
|
|
384 |
if(!DeviceInfo_Usage(s->devinfo, s->path)) { |
if(!DeviceInfo_Usage(s->devinfo, s->path)) { |
|
|
|
385 |
Event_post(s, EVENT_RESTART, "Reason: unable to read device state\n"); |
Event_post(s, EVENT_RESTART, "Reason: unable to read device state\n"); |
386 |
return FALSE; |
return FALSE; |
|
|
|
387 |
} |
} |
|
|
|
388 |
for(td= s->devicelist; td; td= td->next) { |
for(td= s->devicelist; td; td= td->next) { |
|
|
|
389 |
if(!check_device_resources(s, td, report)) { |
if(!check_device_resources(s, td, report)) { |
|
|
|
390 |
if (! eval_actions(td->action, s, report, "device", |
if (! eval_actions(td->action, s, report, "device", |
391 |
EVENT_RESOURCE)) { |
EVENT_RESOURCE)) { |
|
|
|
392 |
return FALSE; |
return FALSE; |
|
|
|
393 |
} |
} |
|
|
|
394 |
} |
} |
|
|
|
395 |
} |
} |
|
|
|
396 |
} |
} |
397 |
|
|
398 |
return TRUE; |
return TRUE; |
399 |
|
|
400 |
} |
} |
411 |
pid_t pid= -1; |
pid_t pid= -1; |
412 |
char report[STRLEN]; |
char report[STRLEN]; |
413 |
|
|
414 |
/* Test for running process */ |
/* Test for running process */ |
415 |
if(!(pid= is_process_running(s))) { |
if(!(pid= is_process_running(s))) { |
416 |
|
/* Reset the proc info object to prevent false data in the first run */ |
417 |
/* Reset the proc info object to prevent false data in the first run */ |
memset(s->procinfo, 0, sizeof *(s->procinfo)); |
418 |
memset(s->procinfo, 0, sizeof *(s->procinfo)); |
Event_post(s, EVENT_START, "Reason: Process is not running."); |
419 |
|
return FALSE; |
420 |
Event_post(s, EVENT_START, "Reason: Process is not running."); |
} else { |
421 |
return FALSE; |
DEBUG("'%s' is running with pid %d\n", s->name, (int)pid); |
422 |
|
} |
|
} else { |
|
|
|
|
|
DEBUG("'%s' is running with pid %d\n", s->name, (int)pid); |
|
|
|
|
|
} |
|
|
|
|
|
if(Run.doprocess) { |
|
|
|
|
|
if(update_process_data(s, pt, treesize, pid)) { |
|
|
|
|
|
if(! check_process_state(s, report)) { |
|
|
|
|
|
Event_post(s, EVENT_RESOURCE, "Reason: %s\n", report); |
|
|
|
|
|
} else { |
|
|
|
|
|
DEBUG("'%s' check_process_state() passed.\n", s->name); |
|
|
|
|
|
} |
|
|
|
|
|
for(pr= s->resourcelist; pr; pr= pr->next) { |
|
|
|
|
|
if(!check_process_resources(s, pr, report)) { |
|
|
|
|
|
pr->cycle=0; |
|
|
|
|
|
if (! eval_actions(pr->action, s, report, "resource", |
|
|
EVENT_TIMESTAMP)) { |
|
|
|
|
|
reset_resource_counter(s); |
|
|
return FALSE; |
|
|
|
|
|
} |
|
423 |
|
|
424 |
} |
if(Run.doprocess) { |
425 |
|
if(update_process_data(s, pt, treesize, pid)) { |
426 |
} |
if(! check_process_state(s, report)) { |
427 |
|
Event_post(s, EVENT_RESOURCE, "Reason: %s\n", report); |
428 |
} else { |
} else { |
429 |
|
DEBUG("'%s' check_process_state() passed.\n", s->name); |
|
log("'%s' failed to get service data\n", s->name); |
|
|
|
|
430 |
} |
} |
|
|
|
|
} |
|
|
|
|
|
/* Test each host:port and protocol in the service's portlist */ |
|
|
for(pp= s->portlist; pp; pp= pp->next) { |
|
|
|
|
|
if(!check_process_connection(s, pp, report)) { |
|
431 |
|
|
432 |
Event_post(s, EVENT_RESTART, "Reason: %s\n", report); |
for(pr= s->resourcelist; pr; pr= pr->next) { |
433 |
|
if(!check_process_resources(s, pr, report)) { |
434 |
return FALSE; |
pr->cycle=0; |
435 |
|
if (! eval_actions(pr->action, s, report, "resource", |
436 |
|
EVENT_TIMESTAMP)) { |
437 |
|
reset_resource_counter(s); |
438 |
|
return FALSE; |
439 |
|
} |
440 |
|
} |
441 |
} |
} |
442 |
|
} else { |
443 |
|
log("'%s' failed to get service data\n", s->name); |
444 |
} |
} |
445 |
|
} |
446 |
|
|
447 |
return TRUE; |
/* Test each host:port and protocol in the service's portlist */ |
448 |
|
for(pp= s->portlist; pp; pp= pp->next) { |
449 |
|
if(!check_process_connection(s, pp, report)) { |
450 |
|
Event_post(s, EVENT_RESTART, "Reason: %s\n", report); |
451 |
|
return FALSE; |
452 |
|
} |
453 |
|
} |
454 |
|
|
455 |
|
return TRUE; |
456 |
|
|
457 |
} |
} |
458 |
|
|
459 |
|
|
469 |
|
|
470 |
/* Control comes here if a timeout occures */ |
/* Control comes here if a timeout occures */ |
471 |
if(sigsetjmp(timeout, TRUE)) { |
if(sigsetjmp(timeout, TRUE)) { |
472 |
|
snprintf(report, STRLEN, "timed out when testing %s [%s]", |
|
snprintf(report, STRLEN, |
|
|
"timed out when testing %s [%s]", |
|
473 |
pp->address, pp->protocol->name); |
pp->address, pp->protocol->name); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
474 |
rv= FALSE; |
rv= FALSE; |
475 |
goto error; |
goto error; |
476 |
|
|
482 |
|
|
483 |
/* Open a socket to the destination INET[hostname:port] or UNIX[pathname] */ |
/* Open a socket to the destination INET[hostname:port] or UNIX[pathname] */ |
484 |
if((pp->socket= create_generic_socket(pp)) < 0) { |
if((pp->socket= create_generic_socket(pp)) < 0) { |
|
|
|
485 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
486 |
"does not accept connection at %s.", |
"does not accept connection at %s.", |
487 |
pp->address); |
pp->address); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
488 |
rv= FALSE; |
rv= FALSE; |
489 |
goto error; |
goto error; |
|
|
|
490 |
} else { |
} else { |
|
|
|
491 |
DEBUG("'%s' succeeded connecting to %s\n", s->name, pp->address); |
DEBUG("'%s' succeeded connecting to %s\n", s->name, pp->address); |
|
|
|
492 |
} |
} |
493 |
|
|
494 |
/* Verify that the socket is ready for i|o */ |
/* Verify that the socket is ready for i|o */ |
495 |
if(!check_connection_io(pp)) { |
if(!check_connection_io(pp)) { |
|
|
|
496 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
497 |
"socket at %s is not ready for i|o -- %s", |
"socket at %s is not ready for i|o -- %s", |
498 |
pp->address, STRERROR); |
pp->address, STRERROR); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
499 |
rv= FALSE; |
rv= FALSE; |
500 |
goto error; |
goto error; |
|
|
|
501 |
} |
} |
502 |
|
|
503 |
if(pp->ssl != NULL) { |
if(pp->ssl != NULL) { |
|
|
|
504 |
if(!embed_ssl_socket(pp->ssl, pp->socket)) { |
if(!embed_ssl_socket(pp->ssl, pp->socket)) { |
|
|
|
505 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
506 |
"failed establish SSL communication on socket at %s", |
"failed establish SSL communication on socket at %s", |
507 |
pp->address); |
pp->address); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
508 |
rv= FALSE; |
rv= FALSE; |
509 |
goto error; |
goto error; |
|
|
|
510 |
} |
} |
|
|
|
511 |
if(pp->certmd5 != NULL) { |
if(pp->certmd5 != NULL) { |
|
|
|
512 |
if(! check_ssl_md5sum(pp->ssl, pp->certmd5)) { |
if(! check_ssl_md5sum(pp->ssl, pp->certmd5)) { |
|
|
|
513 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
514 |
"md5sums of SSL certificates do not match at %s", |
"md5sums of SSL certificates do not match at %s", |
515 |
pp->address); |
pp->address); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
516 |
rv= FALSE; |
rv= FALSE; |
517 |
goto error; |
goto error; |
|
|
|
518 |
} |
} |
|
|
|
519 |
} |
} |
|
|
|
520 |
} |
} |
521 |
|
|
522 |
/* Run the protocol verification routine through the socket */ |
/* Run the protocol verification routine through the socket */ |
523 |
if(! pp->protocol->check(pp)) { |
if(! pp->protocol->check(pp)) { |
|
|
|
524 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
525 |
"test with protocol [%s] failed at %s.", |
"test with protocol [%s] failed at %s.", |
526 |
pp->protocol->name, pp->address); |
pp->protocol->name, pp->address); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
527 |
rv= FALSE; |
rv= FALSE; |
528 |
goto error; |
goto error; |
|
|
|
529 |
} else { |
} else { |
|
|
|
530 |
DEBUG("'%s' succeeded testing protocol [%s] at %s\n", |
DEBUG("'%s' succeeded testing protocol [%s] at %s\n", |
531 |
s->name, pp->protocol->name, pp->address); |
s->name, pp->protocol->name, pp->address); |
532 |
} |
} |
533 |
|
|
534 |
error: |
error: |
|
|
|
535 |
alarm(0); |
alarm(0); |
|
|
|
536 |
if(pp->ssl != NULL) { |
if(pp->ssl != NULL) { |
|
|
|
537 |
cleanup_ssl_socket(pp->ssl); |
cleanup_ssl_socket(pp->ssl); |
|
|
|
538 |
} |
} |
|
|
|
539 |
close_socket(pp->socket); |
close_socket(pp->socket); |
540 |
|
|
541 |
return rv; |
return rv; |
556 |
pi= s->procinfo; |
pi= s->procinfo; |
557 |
|
|
558 |
if(pi->status_flag & PROCESS_ZOMBIE) { |
if(pi->status_flag & PROCESS_ZOMBIE) { |
|
|
|
559 |
snprintf(report, STRLEN, |
snprintf(report, STRLEN, |
560 |
"process with pid %d is a zombie\n", pi->pid); |
"process with pid %d is a zombie\n", pi->pid); |
|
|
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
561 |
/* We do not check the process anymore if it's a zombie |
/* We do not check the process anymore if it's a zombie |
562 |
since such a process is (usually) unmanageable */ |
since such a process is (usually) unmanageable */ |
563 |
LOCK(Run.mutex) |
LOCK(Run.mutex) |
564 |
s->do_monitor= FALSE; |
s->do_monitor= FALSE; |
565 |
END_LOCK; |
END_LOCK; |
|
|
|
566 |
return FALSE; |
return FALSE; |
|
|
|
567 |
} else { |
} else { |
|
|
|
568 |
DEBUG("'%s' zombie check passed [status_flag=%04x]\n", |
DEBUG("'%s' zombie check passed [status_flag=%04x]\n", |
569 |
s->name, pi->status_flag); |
s->name, pi->status_flag); |
|
|
|
570 |
} |
} |
571 |
|
|
572 |
return TRUE; |
return TRUE; |
573 |
|
|
574 |
} |
} |
584 |
ASSERT(s); |
ASSERT(s); |
585 |
|
|
586 |
for(pr= s->resourcelist; pr; pr= pr->next) { |
for(pr= s->resourcelist; pr; pr= pr->next) { |
587 |
|
pr->cycle=0; |
|
pr->cycle=0; |
|
|
|
|
588 |
} |
} |
589 |
|
|
590 |
} |
} |
606 |
|
|
607 |
switch(pr->resource_id) { |
switch(pr->resource_id) { |
608 |
case RESOURCE_ID_CPU_PERCENT: |
case RESOURCE_ID_CPU_PERCENT: |
609 |
if(compare_value(pr->operator, pi->cpu_percent, pr->limit)) { |
if(compare_value(pr->operator, pi->cpu_percent, pr->limit)) { |
610 |
|
snprintf(report, STRLEN, |
611 |
vlog(report, STRLEN, s, |
"cpu usage of %.1f%% matches resource limit [cpu usage%s%.1f%%]", |
612 |
"cpu usage of %.1f%% matches resource limit [cpu usage%s%.1f%%]", |
pi->cpu_percent/10.0, operatorshortnames[pr->operator], |
613 |
pi->cpu_percent/10.0, operatorshortnames[pr->operator], |
pr->limit/10.0); |
614 |
pr->limit/10.0); |
okay= FALSE; |
615 |
|
} else { |
616 |
okay= FALSE; |
DEBUG("'%s' cpu usage check passed [current cpu usage=%.1f%%]\n", |
617 |
|
s->name, pi->cpu_percent/10.0); |
618 |
} else { |
} |
619 |
|
break; |
|
DEBUG("'%s' cpu usage check passed [current cpu usage=%.1f%%]\n", |
|
|
s->name, pi->cpu_percent/10.0); |
|
|
|
|
|
} |
|
|
break; |
|
|
|
|
|
case RESOURCE_ID_MEM_PERCENT: |
|
|
if(compare_value(pr->operator, pi->mem_percent, pr->limit)) { |
|
620 |
|
|
621 |
vlog(report, STRLEN, s, |
case RESOURCE_ID_MEM_PERCENT: |
622 |
|
if(compare_value(pr->operator, pi->mem_percent, pr->limit)) { |
623 |
|
snprintf(report, STRLEN, |
624 |
"mem usage of %.1f%% matches resource limit [mem usage%s%.1f%%]", |
"mem usage of %.1f%% matches resource limit [mem usage%s%.1f%%]", |
625 |
pi->mem_percent/10.0, operatorshortnames[pr->operator], |
pi->mem_percent/10.0, operatorshortnames[pr->operator], |
626 |
pr->limit/10.0); |
pr->limit/10.0); |
627 |
|
okay= FALSE; |
628 |
okay= FALSE; |
} else { |
629 |
|
DEBUG("'%s' mem usage check passed [current mem usage=%.1f%%]\n", |
630 |
} else { |
s->name, pi->mem_percent/10.0); |
631 |
|
} |
632 |
|
break; |
633 |
|
|
|
|
|
|
DEBUG("'%s' mem usage check passed [current mem usage=%.1f%%]\n", |
|
|
s->name, pi->mem_percent/10.0); |
|
|
|
|
|
} |
|
|
break; |
|
|
|
|
634 |
case RESOURCE_ID_MEM_KBYTE: |
case RESOURCE_ID_MEM_KBYTE: |
|
|
|
635 |
if(compare_value(pr->operator, pi->mem_kbyte, pr->limit)) { |
if(compare_value(pr->operator, pi->mem_kbyte, pr->limit)) { |
636 |
|
snprintf(report, STRLEN, |
|
vlog(report, STRLEN, s, |
|
637 |
"mem amount of %ldkB matches resource limit [mem amount%s%ldkB]", |
"mem amount of %ldkB matches resource limit [mem amount%s%ldkB]", |
638 |
pi->mem_kbyte, operatorshortnames[pr->operator], |
pi->mem_kbyte, operatorshortnames[pr->operator], |
639 |
pr->limit); |
pr->limit); |
|
|
|
640 |
okay= FALSE; |
okay= FALSE; |
|
|
|
641 |
} else { |
} else { |
|
|
|
|
|
|
642 |
DEBUG("'%s' mem amount check passed [current mem amount=%ldkB]\n", |
DEBUG("'%s' mem amount check passed [current mem amount=%ldkB]\n", |
643 |
s->name, pi->mem_kbyte); |
s->name, pi->mem_kbyte); |
|
|
|
644 |
} |
} |
645 |
break; |
break; |
646 |
|
|
647 |
case RESOURCE_ID_LOAD1: |
case RESOURCE_ID_LOAD1: |
|
|
|
648 |
if(compare_value(pr->operator, (int)(Run.loadavg[0]*10.0), pr->limit)) { |
if(compare_value(pr->operator, (int)(Run.loadavg[0]*10.0), pr->limit)) { |
649 |
|
snprintf(report, STRLEN, |
650 |
vlog(report, STRLEN, s, |
"loadavg(1min) of %.1f matches resource limit " |
651 |
"loadavg(1min) of %.1f matches resource limit " |
"[loadavg(1min)%s%.1f]", |
652 |
"[loadavg(1min)%s%.1f]", |
Run.loadavg[0], operatorshortnames[pr->operator], |
653 |
Run.loadavg[0], operatorshortnames[pr->operator], |
pr->limit/10.0); |
|
pr->limit/10.0); |
|
|
|
|
654 |
okay= FALSE; |
okay= FALSE; |
|
|
|
655 |
} else { |
} else { |
|
|
|
|
|
|
656 |
DEBUG("'%s' loadavg(1min) check passed [current loadavg(1min)=%.1f]\n", |
DEBUG("'%s' loadavg(1min) check passed [current loadavg(1min)=%.1f]\n", |
657 |
s->name, Run.loadavg[0]); |
s->name, Run.loadavg[0]); |
|
|
|
658 |
} |
} |
659 |
break; |
break; |
660 |
|
|
661 |
case RESOURCE_ID_LOAD5: |
case RESOURCE_ID_LOAD5: |
|
|
|
662 |
if(compare_value(pr->operator, (int)(Run.loadavg[1]*10.0), pr->limit)) { |
if(compare_value(pr->operator, (int)(Run.loadavg[1]*10.0), pr->limit)) { |
663 |
|
snprintf(report, STRLEN, |
664 |
vlog(report, STRLEN, s, |
"loadavg(5min) of %.1f matches resource limit " |
665 |
"loadavg(5min) of %.1f matches resource limit " |
"[loadavg(5min)%s%.1f]", |
666 |
"[loadavg(5min)%s%.1f]", |
Run.loadavg[1], operatorshortnames[pr->operator], |
667 |
Run.loadavg[1], operatorshortnames[pr->operator], |
pr->limit/10.0); |
|
pr->limit/10.0); |
|
|
|
|
668 |
okay= FALSE; |
okay= FALSE; |
|
|
|
669 |
} else { |
} else { |
|
|
|
|
|
|
670 |
DEBUG("'%s' loadavg(5min) check passed [current loadavg(5min)=%.1f]\n", |
DEBUG("'%s' loadavg(5min) check passed [current loadavg(5min)=%.1f]\n", |
671 |
s->name, Run.loadavg[1]); |
s->name, Run.loadavg[1]); |
|
|
|
672 |
} |
} |
673 |
break; |
break; |
|
|
|
|
case RESOURCE_ID_LOAD15: |
|
|
|
|
|
if(compare_value(pr->operator, (int)(Run.loadavg[2]*10.0), pr->limit)) { |
|
|
|
|
|
vlog(report, STRLEN, s, |
|
|
"loadavg(15min) of %.1f matches resource limit " |
|
|
"[loadavg(15min)%s%.1f]", |
|
|
Run.loadavg[2], operatorshortnames[pr->operator], |
|
|
pr->limit/10.0); |
|
|
|
|
|
okay= FALSE; |
|
674 |
|
|
675 |
} else { |
case RESOURCE_ID_LOAD15: |
676 |
|
if(compare_value(pr->operator, (int)(Run.loadavg[2]*10.0), pr->limit)) { |
677 |
DEBUG("'%s' loadavg(15min) check passed " |
snprintf(report, STRLEN, |
678 |
"[current loadavg(15min)=%.1f]\n", |
"loadavg(15min) of %.1f matches resource limit " |
679 |
s->name, Run.loadavg[2]); |
"[loadavg(15min)%s%.1f]", |
680 |
|
Run.loadavg[2], operatorshortnames[pr->operator], |
681 |
|
pr->limit/10.0); |
682 |
|
okay= FALSE; |
683 |
|
} else { |
684 |
|
DEBUG("'%s' loadavg(15min) check passed " |
685 |
|
"[current loadavg(15min)=%.1f]\n", |
686 |
|
s->name, Run.loadavg[2]); |
687 |
|
} |
688 |
|
break; |
689 |
|
|
|
} |
|
|
break; |
|
|
|
|
690 |
case RESOURCE_ID_CHILDREN: |
case RESOURCE_ID_CHILDREN: |
691 |
|
if(compare_value(pr->operator, pi->children, pr->limit)) { |
692 |
if(compare_value(pr->operator, pi->children, pr->limit)) { |
snprintf(report, STRLEN, |
693 |
|
"children of %i matches resource limit [children%s%ld]", |
694 |
vlog(report, STRLEN, s, |
pi->children, operatorshortnames[pr->operator], |
695 |
"children of %i matches resource limit " |
pr->limit); |
696 |
"[children%s%i]", |
okay= FALSE; |
697 |
pi->children, operatorshortnames[pr->operator], |
} else { |
698 |
pr->limit); |
DEBUG("'%s' children check passed [current children=%i]\n", |
699 |
|
s->name, pi->children); |
700 |
okay= FALSE; |
} |
|
|
|
|
} else { |
|
|
|
|
|
DEBUG("'%s' children check passed " |
|
|
"[current children=%i]\n", |
|
|
s->name, pi->children); |
|
|
|
|
|
} |
|
701 |
break; |
break; |
702 |
|
|
703 |
case RESOURCE_ID_TOTAL_MEM_KBYTE: |
case RESOURCE_ID_TOTAL_MEM_KBYTE: |
|
|
|
704 |
if(compare_value(pr->operator, pi->total_mem_kbyte, pr->limit)) { |
if(compare_value(pr->operator, pi->total_mem_kbyte, pr->limit)) { |
705 |
|
snprintf(report, STRLEN, |
706 |
vlog(report, STRLEN, s, |
"total mem amount of %ldkB matches resource limit" |
707 |
"total mem amount of %ldkB matches resource limit" |
" [total mem amount%s%ldkB]", |
708 |
" [total mem amount%s%ldkB]", |
pi->total_mem_kbyte, operatorshortnames[pr->operator], |
709 |
pi->total_mem_kbyte, operatorshortnames[pr->operator], |
pr->limit); |
|
pr->limit); |
|
|
|
|
710 |
okay= FALSE; |
okay= FALSE; |
|
|
|
711 |
} else { |
} else { |
712 |
|
DEBUG("'%s' total mem amount check passed " |
713 |
DEBUG("'%s' total mem amount check passed" |
"[current total mem amount=%ldkB]\n", |
714 |
" [current total mem amount=%ldkB]\n", |
s->name, pi->total_mem_kbyte); |
|
s->name, pi->total_mem_kbyte); |
|
|
|
|
715 |
} |
} |
716 |
break; |
break; |
717 |
|
|
718 |
default: |
default: |
|
|
|
719 |
log("'%s' error: unknow resource ID: [%d]\n", s->name, pr->resource_id); |
log("'%s' error: unknow resource ID: [%d]\n", s->name, pr->resource_id); |
|
|
|
720 |
} |
} |
721 |
|
|
722 |
if(okay && pr->cycle > 0) { |
if(okay && pr->cycle > 0) { |
|
|
|
723 |
pr->cycle--; |
pr->cycle--; |
|
|
|
724 |
} else if(! okay) { |
} else if(! okay) { |
|
|
|
725 |
pr->cycle++; |
pr->cycle++; |
|
|
|
726 |
} |
} |
727 |
|
|
728 |
if(pr->cycle >= pr->max_cycle) { |
if(pr->cycle >= pr->max_cycle) { |
|
|
|
729 |
return FALSE; |
return FALSE; |
|
|
|
730 |
} |
} |
731 |
|
|
732 |
return TRUE; |
return TRUE; |
742 |
ASSERT(s); |
ASSERT(s); |
743 |
|
|
744 |
if(!s->def_timeout) { |
if(!s->def_timeout) { |
|
|
|
745 |
return FALSE; |
return FALSE; |
|
|
|
746 |
} |
} |
747 |
|
|
748 |
/* |
/* |
749 |
* Start counting cycles |
* Start counting cycles |
750 |
*/ |
*/ |
751 |
if(s->nstart > 0) { |
if(s->nstart > 0) { |
|
|
|
752 |
s->ncycle++; |
s->ncycle++; |
|
|
|
753 |
} |
} |
754 |
|
|
755 |
/* |
/* |
756 |
* Check timeout |
* Check timeout |
757 |
*/ |
*/ |
758 |
if(s->nstart >= s->to_start && s->ncycle <= s->to_cycle) { |
if(s->nstart >= s->to_start && s->ncycle <= s->to_cycle) { |
|
|
|
759 |
Event_post(s, EVENT_TIMEOUT, |
Event_post(s, EVENT_TIMEOUT, |
760 |
"Service '%s' timed out and will not be checked anymore.\n", |
"Service '%s' timed out and will not be checked anymore.\n", |
761 |
s->name); |
s->name); |
|
|
|
762 |
return TRUE; |
return TRUE; |
|
|
|
763 |
} |
} |
764 |
|
|
765 |
/* |
/* |
767 |
* cycle interval is passed |
* cycle interval is passed |
768 |
*/ |
*/ |
769 |
if(s->ncycle > s->to_cycle) { |
if(s->ncycle > s->to_cycle) { |
|
|
|
770 |
s->ncycle= 0; |
s->ncycle= 0; |
771 |
s->nstart= 0; |
s->nstart= 0; |
|
|
|
772 |
} |
} |
773 |
|
|
774 |
return FALSE; |
return FALSE; |
785 |
ASSERT(s); |
ASSERT(s); |
786 |
|
|
787 |
if(!s->def_every) { |
if(!s->def_every) { |
|
|
|
788 |
return FALSE; |
return FALSE; |
|
|
|
789 |
} |
} |
790 |
|
|
791 |
if(++s->nevery < s->every) { |
if(++s->nevery < s->every) { |
|
|
|
792 |
return TRUE; |
return TRUE; |
|
|
|
793 |
} |
} |
|
|
|
794 |
s->nevery= 0; |
s->nevery= 0; |
795 |
|
|
796 |
return FALSE; |
return FALSE; |
842 |
ASSERT(t); |
ASSERT(t); |
843 |
|
|
844 |
if((int)time(&now) == -1) { |
if((int)time(&now) == -1) { |
845 |
vlog(report, STRLEN, s, "can't get actual time"); |
snprintf(report, STRLEN, "can't get actual time"); |
846 |
return FALSE; |
return FALSE; |
847 |
} |
} |
848 |
|
|
849 |
if(!(timestamp= get_timestamp(t->pathname, S_IFDIR|S_IFREG))) { |
if(!(timestamp= get_timestamp(t->pathname, S_IFDIR|S_IFREG))) { |
850 |
vlog(report, STRLEN, s, "can't get timestamp for %s", t->pathname); |
snprintf(report, STRLEN, "can't get timestamp for %s", t->pathname); |
851 |
return FALSE; |
return FALSE; |
852 |
} |
} |
853 |
|
|
854 |
if(compare_value(t->operator, (int)(now - timestamp), t->time)) { |
if(compare_value(t->operator, (int)(now - timestamp), t->time)) { |
855 |
vlog(report, STRLEN, s, "timestamp test failed for %s", t->pathname); |
snprintf(report, STRLEN, "timestamp test failed for %s", t->pathname); |
856 |
return FALSE; |
return FALSE; |
857 |
} |
} |
858 |
|
|
873 |
ASSERT(td); |
ASSERT(td); |
874 |
|
|
875 |
if( (td->limit_percent < 0) && (td->limit_absolute < 0) ) { |
if( (td->limit_percent < 0) && (td->limit_absolute < 0) ) { |
|
|
|
876 |
log("'%s' error: device limit not set\n", t->name); |
log("'%s' error: device limit not set\n", t->name); |
877 |
return FALSE; |
return FALSE; |
|
|
|
878 |
} |
} |
879 |
|
|
880 |
switch(td->resource) { |
switch(td->resource) { |
881 |
|
|
882 |
case RESOURCE_ID_INODE: |
case RESOURCE_ID_INODE: |
883 |
|
if(t->devinfo->f_files <= 0) { |
884 |
if(t->devinfo->f_files <= 0) { |
DEBUG("'%s' filesystem doesn't support inodes\n", t->name); |
885 |
|
return TRUE; |
|
DEBUG("'%s' filesystem doesn't support inodes\n", t->name); |
|
|
return TRUE; |
|
|
|
|
|
} |
|
|
|
|
|
if(td->limit_percent >= 0) { |
|
|
|
|
|
if(compare_value( |
|
|
td->operator, |
|
|
100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
|
|
t->devinfo->f_files, td->limit_percent)) { |
|
|
|
|
|
vlog(report, STRLEN, t, |
|
|
"inode usage %d%% matches resource limit [inode usage%s%d%%]", |
|
|
100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
|
|
t->devinfo->f_files, |
|
|
operatorshortnames[td->operator], |
|
|
td->limit_percent); |
|
|
|
|
|
return FALSE; |
|
|
|
|
886 |
} |
} |
887 |
|
|
888 |
} else { |
if(td->limit_percent >= 0) { |
889 |
|
if(compare_value( |
890 |
if(compare_value(td->operator, t->devinfo->f_files - |
td->operator, |
891 |
t->devinfo->f_filesfree, td->limit_absolute)) { |
100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
892 |
|
t->devinfo->f_files, td->limit_percent)) { |
893 |
vlog(report, STRLEN, t, |
snprintf(report, STRLEN, |
894 |
"inode usage %d matches resource limit [inode usage%s%d]", |
"inode usage %ld%% matches resource limit [inode usage%s%d%%]", |
895 |
t->devinfo->f_files - t->devinfo->f_filesfree, |
100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
896 |
operatorshortnames[td->operator], |
t->devinfo->f_files, |
897 |
td->limit_absolute); |
operatorshortnames[td->operator], |
898 |
|
td->limit_percent); |
899 |
return FALSE; |
return FALSE; |
900 |
|
} |
901 |
|
} else { |
902 |
|
if(compare_value(td->operator, t->devinfo->f_files - |
903 |
|
t->devinfo->f_filesfree, td->limit_absolute)) { |
904 |
|
snprintf(report, STRLEN, |
905 |
|
"inode usage %ld matches resource limit [inode usage%s%ld]", |
906 |
|
t->devinfo->f_files - t->devinfo->f_filesfree, |
907 |
|
operatorshortnames[td->operator], |
908 |
|
td->limit_absolute); |
909 |
|
return FALSE; |
910 |
|
} |
911 |
} |
} |
912 |
|
|
913 |
} |
DEBUG("'%s' inode usage check passed [current inode usage=%.1f%%]\n", |
914 |
|
t->name, |
915 |
DEBUG("'%s' inode usage check passed [current inode usage=%.1f%%]\n", |
(float) 100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
916 |
t->name, |
t->devinfo->f_files); |
917 |
(float) 100 * (t->devinfo->f_files - t->devinfo->f_filesfree) / |
|
918 |
t->devinfo->f_files); |
return TRUE; |
|
|
|
|
return TRUE; |
|
919 |
|
|
920 |
case RESOURCE_ID_SPACE: |
case RESOURCE_ID_SPACE: |
|
|
|
921 |
if(td->limit_percent >= 0) { |
if(td->limit_percent >= 0) { |
|
|
|
922 |
if(compare_value( |
if(compare_value( |
923 |
td->operator, |
td->operator, |
924 |
100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
925 |
t->devinfo->f_blocks, td->limit_percent)) { |
t->devinfo->f_blocks, td->limit_percent)) { |
926 |
|
snprintf(report, STRLEN, |
927 |
vlog(report, STRLEN, t, |
"space usage %ld%% matches resource limit [space usage%s%d%%]", |
928 |
"space usage %d%% matches resource limit [space usage%s%d%%]", |
100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
929 |
100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
t->devinfo->f_blocks, operatorshortnames[td->operator], |
930 |
t->devinfo->f_blocks, operatorshortnames[td->operator], |
td->limit_percent); |
|
td->limit_percent); |
|
|
|
|
931 |
return FALSE; |
return FALSE; |
|
|
|
932 |
} |
} |
|
|
|
933 |
} else { |
} else { |
|
|
|
934 |
if(compare_value(td->operator, t->devinfo->f_blocks - |
if(compare_value(td->operator, t->devinfo->f_blocks - |
935 |
t->devinfo->f_blocksfree, td->limit_absolute)) { |
t->devinfo->f_blocksfree, td->limit_absolute)) { |
936 |
|
snprintf(report, STRLEN, |
937 |
vlog(report, STRLEN, t, |
"space usage %ld blocks matches resource limit [space usage%s%ld blocks]", |
938 |
"space usage %d blocks matches resource limit [space usage%s%d blocks]", |
t->devinfo->f_blocks - t->devinfo->f_blocksfree, |
939 |
t->devinfo->f_blocks - t->devinfo->f_blocksfree, |
operatorshortnames[td->operator], |
940 |
operatorshortnames[td->operator], |
td->limit_absolute); |
941 |
td->limit_absolute); |
return FALSE; |
|
|
|
|
return FALSE; |
|
|
|
|
942 |
} |
} |
|
|
|
943 |
} |
} |
944 |
|
DEBUG("'%s' space usage check passed [current space usage=%.1f%%]\n", |
945 |
DEBUG("'%s' space usage check passed [current space usage=%.1f%%]\n", |
t->name, |
946 |
t->name, |
(float) 100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
947 |
(float) 100 * (t->devinfo->f_blocks - t->devinfo->f_blocksfree) / |
t->devinfo->f_blocks); |
948 |
t->devinfo->f_blocks); |
return TRUE; |
949 |
|
|
|
return TRUE; |
|
|
|
|
950 |
default: |
default: |
951 |
|
log("'%s' error: unknow resource type: [%d]\n", t->name, td->resource); |
952 |
log("'%s' error: unknow resource type: [%d]\n", t->name, td->resource); |
return FALSE; |
|
return FALSE; |
|
|
|
|
953 |
} |
} |
954 |
|
|
955 |
} |
} |
956 |
|
|
957 |
|
|
966 |
|
|
967 |
|
|
968 |
/** |
/** |
|
* Logging with report generation |
|
|
*/ |
|
|
static void vlog(char * report, int n, Service_T s, char *m,...) { |
|
|
|
|
|
va_list ap; |
|
|
char *tmp = NULL; |
|
|
|
|
|
va_start(ap, m); |
|
|
|
|
|
if(m) { |
|
|
|
|
|
tmp=format(m,ap); |
|
|
|
|
|
} |
|
|
|
|
|
va_end(ap); |
|
|
|
|
|
strncpy(report, tmp, n); |
|
|
log("'%s' %s\n", s->name, report); |
|
|
|
|
|
free(tmp); |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
969 |
* Comparison of values. Returns TRUE if comparison matches, otherwise |
* Comparison of values. Returns TRUE if comparison matches, otherwise |
970 |
* FALSE. |
* FALSE. |
971 |
*/ |
*/ |
972 |
static int compare_value(int operator, int left, int right) { |
static int compare_value(int operator, int left, int right) { |
973 |
|
|
974 |
switch(operator) { |
switch(operator) { |
975 |
|
case OPERATOR_GREATER: |
|
case OPERATOR_GREATER: |
|
|
|
|
976 |
if(left > right) |
if(left > right) |
977 |
return TRUE; |
return TRUE; |
978 |
break; |
break; |
979 |
|
case OPERATOR_LESS: |
|
case OPERATOR_LESS: |
|
|
|
|
980 |
if(left < right) |
if(left < right) |
981 |
return TRUE; |
return TRUE; |
982 |
break; |
break; |
983 |
|
case OPERATOR_EQUAL: |
|
case OPERATOR_EQUAL: |
|
|
|
|
984 |
if(left == right) |
if(left == right) |
985 |
return TRUE; |
return TRUE; |
986 |
break; |
break; |
987 |
|
case OPERATOR_NOTEQUAL: |
|
case OPERATOR_NOTEQUAL: |
|
|
|
|
988 |
if(left != right) |
if(left != right) |
989 |
return TRUE; |
return TRUE; |
990 |
break; |
break; |
991 |
|
default: |
|
default: |
|
992 |
log("Unknow comparison operator\n"); |
log("Unknow comparison operator\n"); |
993 |
return FALSE; |
return FALSE; |
994 |
|
} |
995 |
|
|
996 |
} |
return FALSE; |
997 |
|
|
|
return FALSE; |
|
|
|
|
998 |
} |
} |
999 |
|
|