diff --git a/src/l.l b/src/l.l index 2093943..94edd9e 100644 --- a/src/l.l +++ b/src/l.l @@ -190,6 +190,7 @@ timeout { return TIMEOUT; } checksum { return CHECKSUM; } mailserver { return MAILSERVER; } every { return EVERY; } +settle { return SETTLE; } host { return HOST; } hostheader { return HOSTHEADER; } system { return SYSTEM; } diff --git a/src/monit.h b/src/monit.h index 71883a8..4c30a15 100644 --- a/src/monit.h +++ b/src/monit.h @@ -718,6 +718,9 @@ typedef struct myservice { int every; /**< Check this program at given cycles */ int nevery; /**< Counter for every. When nevery == every, check */ int def_every; /**< TRUE if every is defined for the service */ + int settle; /**< Check this program at given cycles */ + int nsettle; /**< Counter for every. When nevery == every, check */ + int def_settle; /**< TRUE if every is defined for the service */ int visited; /**< Service visited flag, set if dependencies are used */ int depend_visited;/**< Depend visited flag, set if dependencies are used */ Command_T start; /**< The start command for the service */ diff --git a/src/p.y b/src/p.y index d718c7e..68c9e5f 100644 --- a/src/p.y +++ b/src/p.y @@ -246,6 +246,7 @@ static void reset_rateset(); static void check_name(char *); static void check_every(int); + static void check_settle(int); static int check_perm(int); static void check_hostname (char *); static void check_exec(char *); @@ -272,7 +273,7 @@ %token PIDFILE START STOP PATHTOK %token HOST HOSTNAME PORT TYPE UDP TCP TCPSSL PROTOCOL CONNECTION %token ALERT NOALERT MAILFORMAT UNIXSOCKET SIGNATURE -%token TIMEOUT RESTART CHECKSUM EVERY +%token TIMEOUT RESTART CHECKSUM EVERY SETTLE %token DEFAULT HTTP APACHESTATUS FTP SMTP POP IMAP CLAMAV NNTP NTP3 MYSQL DNS %token SSH DWP LDAP2 LDAP3 RDATE RSYNC TNS PGSQL POSTFIXPOLICY SIP LMTP GPS RADIUS MEMCACHE %token STRING PATH MAILADDR MAILFROM MAILREPLYTO MAILSUBJECT @@ -349,6 +350,7 @@ optproc : start | actionrate | alert | every + | settle | mode | group | depend @@ -365,6 +367,7 @@ optfile : start | timestamp | actionrate | every + | settle | alert | permission | uid @@ -386,6 +389,7 @@ optfilesys : start | exist | actionrate | every + | settle | alert | permission | uid @@ -408,6 +412,7 @@ optdir : start | timestamp | actionrate | every + | settle | alert | permission | uid @@ -429,6 +434,7 @@ opthost : start | actionrate | alert | every + | settle | mode | group | depend @@ -443,6 +449,7 @@ optsystem : start | actionrate | alert | every + | settle | group | depend | resourcesystem @@ -458,6 +465,7 @@ optfifo : start | timestamp | actionrate | every + | settle | alert | permission | uid @@ -475,6 +483,7 @@ optstatus : actionrate | exist | alert | every + | settle | group | depend ; @@ -1292,6 +1301,14 @@ every : EVERY NUMBER CYCLE { current->every = $2; } ; + +settle : SETTLE NUMBER CYCLE { + check_settle($2); + current->def_settle = TRUE; + current->settle = $2; + } + ; + mode : MODE ACTIVE { current->mode = MODE_ACTIVE; @@ -3354,6 +3371,13 @@ static void check_every(int every) { yyerror2("an EVERY statement must have a value greater than 1"); } +/* + * Settle statement semantic check + */ +static void check_settle(int settle) { + if (settle <= 1) + yyerror2("a SETTLE statement must have a value greater than 1"); +} /* * Check hostname diff --git a/src/util.c b/src/util.c index 023f5a9..8c86f6f 100644 --- a/src/util.c +++ b/src/util.c @@ -1012,6 +1012,9 @@ void Util_printService(Service_T s) { if(s->def_every) printf(" %-20s = Check service every %d cycles\n", "Every", s->every); + if(s->def_settle) + printf(" %-20s = After start of service allow for %d cycles of settle period\n", "Settle", s->settle); + for (ar = s->actionratelist; ar; ar = ar->next) printf(" %-20s = If restarted %d times within %d cycle(s) then %s\n", "Timeout", ar->count, ar->cycle, Util_describeAction(ar->action->failed, buf, sizeof(buf))); diff --git a/src/validate.c b/src/validate.c index 7cda675..a187674 100644 --- a/src/validate.c +++ b/src/validate.c @@ -161,12 +161,12 @@ int validate() { if (! do_scheduled_action(s) && s->monitor && ! check_skip(s)) { check_timeout(s); // Can disable monitoring => need to check s->monitor again if (s->monitor) { + /* The monitoring may be disabled by some matching rule in s->check in the last cycle + * so we have to check again before setting to MONITOR_YES */ + if (s->monitor != MONITOR_NOT) + s->monitor = MONITOR_YES; if (! s->check(s)) errors++; - /* The monitoring may be disabled by some matching rule in s->check - * so we have to check again before setting to MONITOR_YES */ - if (s->monitor != MONITOR_NOT) - s->monitor = MONITOR_YES; } } gettimeofday(&s->collected, NULL); @@ -1295,13 +1295,20 @@ static int check_skip(Service_T s) { return TRUE; } - if (!s->def_every) + if (!s->def_every && !s->def_settle) return FALSE; - if (++s->nevery < s->every) + if (s->def_every && ++s->nevery < s->every) return TRUE; + if (!s->def_settle) + return FALSE; + + if ((s->monitor == MONITOR_INIT) && (++s->nsettle < s->settle)) + return TRUE; + s->nevery = 0; + s->nsettle = 0; return FALSE;