diff options
| -rw-r--r-- | lib/utils_base.c | 19 | ||||
| -rw-r--r-- | lib/utils_base.h | 5 | ||||
| -rw-r--r-- | lib/utils_cmd.c | 42 | ||||
| -rw-r--r-- | lib/utils_cmd.h | 13 | ||||
| -rw-r--r-- | plugins/check_dbi.c | 1 | ||||
| -rw-r--r-- | plugins/check_pgsql.c | 1 | ||||
| -rw-r--r-- | plugins/common.h | 14 | ||||
| -rw-r--r-- | plugins/popen.c | 29 | ||||
| -rw-r--r-- | plugins/runcmd.c | 13 | ||||
| -rw-r--r-- | plugins/utils.c | 31 | ||||
| -rw-r--r-- | plugins/utils.h | 9 |
11 files changed, 70 insertions, 107 deletions
diff --git a/lib/utils_base.c b/lib/utils_base.c index 19a531f5..fd7058da 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c | |||
| @@ -37,6 +37,9 @@ | |||
| 37 | 37 | ||
| 38 | monitoring_plugin *this_monitoring_plugin=NULL; | 38 | monitoring_plugin *this_monitoring_plugin=NULL; |
| 39 | 39 | ||
| 40 | unsigned int timeout_state = STATE_CRITICAL; | ||
| 41 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; | ||
| 42 | |||
| 40 | int _np_state_read_file(FILE *); | 43 | int _np_state_read_file(FILE *); |
| 41 | 44 | ||
| 42 | void np_init( char *plugin_name, int argc, char **argv ) { | 45 | void np_init( char *plugin_name, int argc, char **argv ) { |
| @@ -359,6 +362,22 @@ char *np_extract_value(const char *varlist, const char *name, char sep) { | |||
| 359 | return value; | 362 | return value; |
| 360 | } | 363 | } |
| 361 | 364 | ||
| 365 | const char * | ||
| 366 | state_text (int result) | ||
| 367 | { | ||
| 368 | switch (result) { | ||
| 369 | case STATE_OK: | ||
| 370 | return "OK"; | ||
| 371 | case STATE_WARNING: | ||
| 372 | return "WARNING"; | ||
| 373 | case STATE_CRITICAL: | ||
| 374 | return "CRITICAL"; | ||
| 375 | case STATE_DEPENDENT: | ||
| 376 | return "DEPENDENT"; | ||
| 377 | default: | ||
| 378 | return "UNKNOWN"; | ||
| 379 | } | ||
| 380 | } | ||
| 362 | 381 | ||
| 363 | /* | 382 | /* |
| 364 | * Read a string representing a state (ok, warning... or numeric: 0, 1) and | 383 | * Read a string representing a state (ok, warning... or numeric: 0, 1) and |
diff --git a/lib/utils_base.h b/lib/utils_base.h index 42ae0c09..d7e7dffa 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h | |||
| @@ -61,6 +61,10 @@ void print_thresholds(const char *, thresholds *); | |||
| 61 | int check_range(double, range *); | 61 | int check_range(double, range *); |
| 62 | int get_status(double, thresholds *); | 62 | int get_status(double, thresholds *); |
| 63 | 63 | ||
| 64 | /* Handle timeouts */ | ||
| 65 | extern unsigned int timeout_state; | ||
| 66 | extern unsigned int timeout_interval; | ||
| 67 | |||
| 64 | /* All possible characters in a threshold range */ | 68 | /* All possible characters in a threshold range */ |
| 65 | #define NP_THRESHOLDS_CHARS "-0123456789.:@~" | 69 | #define NP_THRESHOLDS_CHARS "-0123456789.:@~" |
| 66 | 70 | ||
| @@ -107,5 +111,6 @@ void np_state_write_string(time_t, char *); | |||
| 107 | void np_init(char *, int argc, char **argv); | 111 | void np_init(char *, int argc, char **argv); |
| 108 | void np_set_args(int argc, char **argv); | 112 | void np_set_args(int argc, char **argv); |
| 109 | void np_cleanup(); | 113 | void np_cleanup(); |
| 114 | const char *state_text (int); | ||
| 110 | 115 | ||
| 111 | #endif /* _UTILS_BASE_ */ | 116 | #endif /* _UTILS_BASE_ */ |
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index 7eb9a3a0..795840d3 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | /** includes **/ | 41 | /** includes **/ |
| 42 | #include "common.h" | 42 | #include "common.h" |
| 43 | #include "utils.h" | ||
| 43 | #include "utils_cmd.h" | 44 | #include "utils_cmd.h" |
| 44 | #include "utils_base.h" | 45 | #include "utils_base.h" |
| 45 | #include <fcntl.h> | 46 | #include <fcntl.h> |
| @@ -65,31 +66,6 @@ extern char **environ; | |||
| 65 | # define SIG_ERR ((Sigfunc *)-1) | 66 | # define SIG_ERR ((Sigfunc *)-1) |
| 66 | #endif | 67 | #endif |
| 67 | 68 | ||
| 68 | /* This variable must be global, since there's no way the caller | ||
| 69 | * can forcibly slay a dead or ungainly running program otherwise. | ||
| 70 | * Multithreading apps and plugins can initialize it (via CMD_INIT) | ||
| 71 | * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array() | ||
| 72 | * for the first time. | ||
| 73 | * | ||
| 74 | * The check for initialized values is atomic and can | ||
| 75 | * occur in any number of threads simultaneously. */ | ||
| 76 | static pid_t *_cmd_pids = NULL; | ||
| 77 | |||
| 78 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. | ||
| 79 | * If that fails and the macro isn't defined, we fall back to an educated | ||
| 80 | * guess. There's no guarantee that our guess is adequate and the program | ||
| 81 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ | ||
| 82 | #define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */ | ||
| 83 | #define MAXFD_LIMIT 8192 /* upper limit of open files */ | ||
| 84 | #ifdef _SC_OPEN_MAX | ||
| 85 | static long maxfd = 0; | ||
| 86 | #elif defined(OPEN_MAX) | ||
| 87 | # define maxfd OPEN_MAX | ||
| 88 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
| 89 | # define maxfd DEFAULT_MAXFD | ||
| 90 | #endif | ||
| 91 | |||
| 92 | |||
| 93 | /** prototypes **/ | 69 | /** prototypes **/ |
| 94 | static int _cmd_open (char *const *, int *, int *) | 70 | static int _cmd_open (char *const *, int *, int *) |
| 95 | __attribute__ ((__nonnull__ (1, 2, 3))); | 71 | __attribute__ ((__nonnull__ (1, 2, 3))); |
| @@ -406,3 +382,19 @@ cmd_file_read ( char *filename, output *out, int flags) | |||
| 406 | 382 | ||
| 407 | return 0; | 383 | return 0; |
| 408 | } | 384 | } |
| 385 | |||
| 386 | void | ||
| 387 | timeout_alarm_handler (int signo) | ||
| 388 | { | ||
| 389 | size_t i; | ||
| 390 | if (signo == SIGALRM) { | ||
| 391 | printf (_("%s - Plugin timed out after %d seconds\n"), | ||
| 392 | state_text(timeout_state), timeout_interval); | ||
| 393 | |||
| 394 | if(_cmd_pids) for(i = 0; i < maxfd; i++) { | ||
| 395 | if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL); | ||
| 396 | } | ||
| 397 | |||
| 398 | exit (timeout_state); | ||
| 399 | } | ||
| 400 | } | ||
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h index ebaf15be..6f3aeb81 100644 --- a/lib/utils_cmd.h +++ b/lib/utils_cmd.h | |||
| @@ -32,4 +32,17 @@ void cmd_init (void); | |||
| 32 | #define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ | 32 | #define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ |
| 33 | #define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */ | 33 | #define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */ |
| 34 | 34 | ||
| 35 | /* This variable must be global, since there's no way the caller | ||
| 36 | * can forcibly slay a dead or ungainly running program otherwise. | ||
| 37 | * Multithreading apps and plugins can initialize it (via CMD_INIT) | ||
| 38 | * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array() | ||
| 39 | * for the first time. | ||
| 40 | * | ||
| 41 | * The check for initialized values is atomic and can | ||
| 42 | * occur in any number of threads simultaneously. */ | ||
| 43 | static pid_t *_cmd_pids = NULL; | ||
| 44 | |||
| 45 | RETSIGTYPE timeout_alarm_handler (int); | ||
| 46 | |||
| 47 | |||
| 35 | #endif /* _UTILS_CMD_ */ | 48 | #endif /* _UTILS_CMD_ */ |
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c index 826eb8d9..ced13d05 100644 --- a/plugins/check_dbi.c +++ b/plugins/check_dbi.c | |||
| @@ -35,6 +35,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 35 | 35 | ||
| 36 | #include "common.h" | 36 | #include "common.h" |
| 37 | #include "utils.h" | 37 | #include "utils.h" |
| 38 | #include "utils_cmd.h" | ||
| 38 | 39 | ||
| 39 | #include "netutils.h" | 40 | #include "netutils.h" |
| 40 | 41 | ||
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c index 5cd47093..11ce6916 100644 --- a/plugins/check_pgsql.c +++ b/plugins/check_pgsql.c | |||
| @@ -34,6 +34,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 34 | 34 | ||
| 35 | #include "common.h" | 35 | #include "common.h" |
| 36 | #include "utils.h" | 36 | #include "utils.h" |
| 37 | #include "utils_cmd.h" | ||
| 37 | 38 | ||
| 38 | #include "netutils.h" | 39 | #include "netutils.h" |
| 39 | #include <libpq-fe.h> | 40 | #include <libpq-fe.h> |
diff --git a/plugins/common.h b/plugins/common.h index 6bf4fca4..0f08e2f6 100644 --- a/plugins/common.h +++ b/plugins/common.h | |||
| @@ -225,4 +225,18 @@ enum { | |||
| 225 | # define __attribute__(x) /* do nothing */ | 225 | # define __attribute__(x) /* do nothing */ |
| 226 | #endif | 226 | #endif |
| 227 | 227 | ||
| 228 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. | ||
| 229 | * If that fails and the macro isn't defined, we fall back to an educated | ||
| 230 | * guess. There's no guarantee that our guess is adequate and the program | ||
| 231 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ | ||
| 232 | #define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */ | ||
| 233 | #define MAXFD_LIMIT 8192 /* upper limit of open files */ | ||
| 234 | #ifdef _SC_OPEN_MAX | ||
| 235 | static long maxfd = 0; | ||
| 236 | #elif defined(OPEN_MAX) | ||
| 237 | # define maxfd OPEN_MAX | ||
| 238 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
| 239 | # define maxfd DEFAULT_MAXFD | ||
| 240 | #endif | ||
| 241 | |||
| 228 | #endif /* _COMMON_H_ */ | 242 | #endif /* _COMMON_H_ */ |
diff --git a/plugins/popen.c b/plugins/popen.c index 592263fd..116d168d 100644 --- a/plugins/popen.c +++ b/plugins/popen.c | |||
| @@ -78,7 +78,6 @@ RETSIGTYPE popen_timeout_alarm_handler (int); | |||
| 78 | 78 | ||
| 79 | #define min(a,b) ((a) < (b) ? (a) : (b)) | 79 | #define min(a,b) ((a) < (b) ? (a) : (b)) |
| 80 | #define max(a,b) ((a) > (b) ? (a) : (b)) | 80 | #define max(a,b) ((a) > (b) ? (a) : (b)) |
| 81 | int open_max (void); /* {Prog openmax} */ | ||
| 82 | static void err_sys (const char *, ...) __attribute__((noreturn,format(printf, 1, 2))); | 81 | static void err_sys (const char *, ...) __attribute__((noreturn,format(printf, 1, 2))); |
| 83 | char *rtrim (char *, const char *); | 82 | char *rtrim (char *, const char *); |
| 84 | 83 | ||
| @@ -86,7 +85,6 @@ char *pname = NULL; /* caller can set this from argv[0] */ | |||
| 86 | 85 | ||
| 87 | /*int *childerr = NULL;*//* ptr to array allocated at run-time */ | 86 | /*int *childerr = NULL;*//* ptr to array allocated at run-time */ |
| 88 | /*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */ | 87 | /*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */ |
| 89 | static int maxfd; /* from our open_max(), {Prog openmax} */ | ||
| 90 | 88 | ||
| 91 | #ifdef REDHAT_SPOPEN_ERROR | 89 | #ifdef REDHAT_SPOPEN_ERROR |
| 92 | static volatile int childtermd = 0; | 90 | static volatile int childtermd = 0; |
| @@ -187,13 +185,11 @@ spopen (const char *cmdstring) | |||
| 187 | argv[i] = NULL; | 185 | argv[i] = NULL; |
| 188 | 186 | ||
| 189 | if (childpid == NULL) { /* first time through */ | 187 | if (childpid == NULL) { /* first time through */ |
| 190 | maxfd = open_max (); /* allocate zeroed out array for child pids */ | ||
| 191 | if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) | 188 | if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) |
| 192 | return (NULL); | 189 | return (NULL); |
| 193 | } | 190 | } |
| 194 | 191 | ||
| 195 | if (child_stderr_array == NULL) { /* first time through */ | 192 | if (child_stderr_array == NULL) { /* first time through */ |
| 196 | maxfd = open_max (); /* allocate zeroed out array for child pids */ | ||
| 197 | if ((child_stderr_array = calloc ((size_t)maxfd, sizeof (int))) == NULL) | 193 | if ((child_stderr_array = calloc ((size_t)maxfd, sizeof (int))) == NULL) |
| 198 | return (NULL); | 194 | return (NULL); |
| 199 | } | 195 | } |
| @@ -273,15 +269,6 @@ spclose (FILE * fp) | |||
| 273 | return (1); | 269 | return (1); |
| 274 | } | 270 | } |
| 275 | 271 | ||
| 276 | #ifdef OPEN_MAX | ||
| 277 | static int openmax = OPEN_MAX; | ||
| 278 | #else | ||
| 279 | static int openmax = 0; | ||
| 280 | #endif | ||
| 281 | |||
| 282 | #define OPEN_MAX_GUESS 256 /* if OPEN_MAX is indeterminate */ | ||
| 283 | /* no guarantee this is adequate */ | ||
| 284 | |||
| 285 | #ifdef REDHAT_SPOPEN_ERROR | 272 | #ifdef REDHAT_SPOPEN_ERROR |
| 286 | RETSIGTYPE | 273 | RETSIGTYPE |
| 287 | popen_sigchld_handler (int signo) | 274 | popen_sigchld_handler (int signo) |
| @@ -311,22 +298,6 @@ popen_timeout_alarm_handler (int signo) | |||
| 311 | } | 298 | } |
| 312 | 299 | ||
| 313 | 300 | ||
| 314 | int | ||
| 315 | open_max (void) | ||
| 316 | { | ||
| 317 | if (openmax == 0) { /* first time through */ | ||
| 318 | errno = 0; | ||
| 319 | if ((openmax = sysconf (_SC_OPEN_MAX)) < 0) { | ||
| 320 | if (errno == 0) | ||
| 321 | openmax = OPEN_MAX_GUESS; /* it's indeterminate */ | ||
| 322 | else | ||
| 323 | err_sys (_("sysconf error for _SC_OPEN_MAX")); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | return (openmax); | ||
| 327 | } | ||
| 328 | |||
| 329 | |||
| 330 | /* Fatal error related to a system call. | 301 | /* Fatal error related to a system call. |
| 331 | * Print a message and die. */ | 302 | * Print a message and die. */ |
| 332 | 303 | ||
diff --git a/plugins/runcmd.c b/plugins/runcmd.c index 1a7c904f..c3828678 100644 --- a/plugins/runcmd.c +++ b/plugins/runcmd.c | |||
| @@ -67,19 +67,6 @@ | |||
| 67 | * occur in any number of threads simultaneously. */ | 67 | * occur in any number of threads simultaneously. */ |
| 68 | static pid_t *np_pids = NULL; | 68 | static pid_t *np_pids = NULL; |
| 69 | 69 | ||
| 70 | /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX. | ||
| 71 | * If that fails and the macro isn't defined, we fall back to an educated | ||
| 72 | * guess. There's no guarantee that our guess is adequate and the program | ||
| 73 | * will die with SIGSEGV if it isn't and the upper boundary is breached. */ | ||
| 74 | #ifdef _SC_OPEN_MAX | ||
| 75 | static long maxfd = 0; | ||
| 76 | #elif defined(OPEN_MAX) | ||
| 77 | # define maxfd OPEN_MAX | ||
| 78 | #else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */ | ||
| 79 | # define maxfd 256 | ||
| 80 | #endif | ||
| 81 | |||
| 82 | |||
| 83 | /** prototypes **/ | 70 | /** prototypes **/ |
| 84 | static int np_runcmd_open(const char *, int *, int *) | 71 | static int np_runcmd_open(const char *, int *, int *) |
| 85 | __attribute__((__nonnull__(1, 2, 3))); | 72 | __attribute__((__nonnull__(1, 2, 3))); |
diff --git a/plugins/utils.c b/plugins/utils.c index 231af92b..ee620133 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
| @@ -36,9 +36,6 @@ extern const char *progname; | |||
| 36 | #define STRLEN 64 | 36 | #define STRLEN 64 |
| 37 | #define TXTBLK 128 | 37 | #define TXTBLK 128 |
| 38 | 38 | ||
| 39 | unsigned int timeout_state = STATE_CRITICAL; | ||
| 40 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; | ||
| 41 | |||
| 42 | time_t start_time, end_time; | 39 | time_t start_time, end_time; |
| 43 | 40 | ||
| 44 | /* ************************************************************************** | 41 | /* ************************************************************************** |
| @@ -148,33 +145,6 @@ print_revision (const char *command_name, const char *revision) | |||
| 148 | command_name, revision, PACKAGE, VERSION); | 145 | command_name, revision, PACKAGE, VERSION); |
| 149 | } | 146 | } |
| 150 | 147 | ||
| 151 | const char * | ||
| 152 | state_text (int result) | ||
| 153 | { | ||
| 154 | switch (result) { | ||
| 155 | case STATE_OK: | ||
| 156 | return "OK"; | ||
| 157 | case STATE_WARNING: | ||
| 158 | return "WARNING"; | ||
| 159 | case STATE_CRITICAL: | ||
| 160 | return "CRITICAL"; | ||
| 161 | case STATE_DEPENDENT: | ||
| 162 | return "DEPENDENT"; | ||
| 163 | default: | ||
| 164 | return "UNKNOWN"; | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | void | ||
| 169 | timeout_alarm_handler (int signo) | ||
| 170 | { | ||
| 171 | if (signo == SIGALRM) { | ||
| 172 | printf (_("%s - Plugin timed out after %d seconds\n"), | ||
| 173 | state_text(timeout_state), timeout_interval); | ||
| 174 | exit (timeout_state); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | int | 148 | int |
| 179 | is_numeric (char *number) | 149 | is_numeric (char *number) |
| 180 | { | 150 | { |
| @@ -708,4 +678,3 @@ char *sperfdata_int (const char *label, | |||
| 708 | 678 | ||
| 709 | return data; | 679 | return data; |
| 710 | } | 680 | } |
| 711 | |||
diff --git a/plugins/utils.h b/plugins/utils.h index a436e1ca..6aa316fe 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
| @@ -29,13 +29,6 @@ suite of plugins. */ | |||
| 29 | void support (void); | 29 | void support (void); |
| 30 | void print_revision (const char *, const char *); | 30 | void print_revision (const char *, const char *); |
| 31 | 31 | ||
| 32 | /* Handle timeouts */ | ||
| 33 | |||
| 34 | extern unsigned int timeout_state; | ||
| 35 | extern unsigned int timeout_interval; | ||
| 36 | |||
| 37 | RETSIGTYPE timeout_alarm_handler (int); | ||
| 38 | |||
| 39 | extern time_t start_time, end_time; | 32 | extern time_t start_time, end_time; |
| 40 | 33 | ||
| 41 | /* Test input types */ | 34 | /* Test input types */ |
| @@ -89,8 +82,6 @@ void usage4(const char *) __attribute__((noreturn)); | |||
| 89 | void usage5(void) __attribute__((noreturn)); | 82 | void usage5(void) __attribute__((noreturn)); |
| 90 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); | 83 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); |
| 91 | 84 | ||
| 92 | const char *state_text (int); | ||
| 93 | |||
| 94 | #define max(a,b) (((a)>(b))?(a):(b)) | 85 | #define max(a,b) (((a)>(b))?(a):(b)) |
| 95 | #define min(a,b) (((a)<(b))?(a):(b)) | 86 | #define min(a,b) (((a)<(b))?(a):(b)) |
| 96 | 87 | ||
