Imported Upstream version 1.4.16+git20130902
This commit is contained in:
parent
e76be63abf
commit
e70fb8c051
517 changed files with 44015 additions and 43295 deletions
|
@ -42,18 +42,21 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
|
|||
#include "regex.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
int process_arguments (int, char **);
|
||||
int validate_arguments (void);
|
||||
int check_thresholds (int);
|
||||
int convert_to_seconds (char *);
|
||||
void print_help (void);
|
||||
void print_usage (void);
|
||||
|
||||
int wmax = -1;
|
||||
int cmax = -1;
|
||||
int wmin = -1;
|
||||
int cmin = -1;
|
||||
char *warning_range = NULL;
|
||||
char *critical_range = NULL;
|
||||
thresholds *procs_thresholds = NULL;
|
||||
|
||||
int options = 0; /* bitmask of filter criteria to test against */
|
||||
#define ALL 1
|
||||
|
@ -67,6 +70,10 @@ int options = 0; /* bitmask of filter criteria to test against */
|
|||
#define PCPU 256
|
||||
#define ELAPSED 512
|
||||
#define EREG_ARGS 1024
|
||||
|
||||
#define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads:
|
||||
ppid of procs are compared to pid of this proc*/
|
||||
|
||||
/* Different metrics */
|
||||
char *metric_name;
|
||||
enum metric {
|
||||
|
@ -92,9 +99,21 @@ regex_t re_args;
|
|||
char *fmt;
|
||||
char *fails;
|
||||
char tmp[MAX_INPUT_BUFFER];
|
||||
int kthread_filter = 0;
|
||||
int usepid = 0; /* whether to test for pid or /proc/pid/exe */
|
||||
|
||||
FILE *ps_input = NULL;
|
||||
|
||||
static int
|
||||
stat_exe (const pid_t pid, struct stat *buf) {
|
||||
char *path;
|
||||
int ret;
|
||||
xasprintf(&path, "/proc/%d/exe", pid);
|
||||
ret = stat(path, buf);
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
|
@ -104,9 +123,13 @@ main (int argc, char **argv)
|
|||
char *procprog;
|
||||
|
||||
pid_t mypid = 0;
|
||||
struct stat statbuf;
|
||||
dev_t mydev = 0;
|
||||
ino_t myino = 0;
|
||||
int procuid = 0;
|
||||
pid_t procpid = 0;
|
||||
pid_t procppid = 0;
|
||||
pid_t kthread_ppid = 0;
|
||||
int procvsz = 0;
|
||||
int procrss = 0;
|
||||
int procseconds = 0;
|
||||
|
@ -127,6 +150,7 @@ main (int argc, char **argv)
|
|||
int crit = 0; /* number of processes in crit state */
|
||||
int i = 0, j = 0;
|
||||
int result = STATE_UNKNOWN;
|
||||
int ret;
|
||||
output chld_out, chld_err;
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
|
@ -137,7 +161,7 @@ main (int argc, char **argv)
|
|||
input_buffer = malloc (MAX_INPUT_BUFFER);
|
||||
procprog = malloc (MAX_INPUT_BUFFER);
|
||||
|
||||
asprintf (&metric_name, "PROCS");
|
||||
xasprintf (&metric_name, "PROCS");
|
||||
metric = METRIC_PROCS;
|
||||
|
||||
/* Parse extra opts if any */
|
||||
|
@ -146,8 +170,16 @@ main (int argc, char **argv)
|
|||
if (process_arguments (argc, argv) == ERROR)
|
||||
usage4 (_("Could not parse arguments"));
|
||||
|
||||
/* get our pid */
|
||||
/* find ourself */
|
||||
mypid = getpid();
|
||||
if (usepid || stat_exe(mypid, &statbuf) == -1) {
|
||||
/* usepid might have been set by -T */
|
||||
usepid = 1;
|
||||
} else {
|
||||
usepid = 0;
|
||||
mydev = statbuf.st_dev;
|
||||
myino = statbuf.st_ino;
|
||||
}
|
||||
|
||||
/* Set signal handling and alarm timeout */
|
||||
if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
|
||||
|
@ -176,7 +208,7 @@ main (int argc, char **argv)
|
|||
printf ("%s", input_line);
|
||||
|
||||
strcpy (procprog, "");
|
||||
asprintf (&procargs, "%s", "");
|
||||
xasprintf (&procargs, "%s", "");
|
||||
|
||||
cols = sscanf (input_line, PS_FORMAT, PS_VARLIST);
|
||||
|
||||
|
@ -186,7 +218,7 @@ main (int argc, char **argv)
|
|||
}
|
||||
if ( cols >= expected_cols ) {
|
||||
resultsum = 0;
|
||||
asprintf (&procargs, "%s", input_line + pos);
|
||||
xasprintf (&procargs, "%s", input_line + pos);
|
||||
strip (procargs);
|
||||
|
||||
/* Some ps return full pathname for command. This removes path */
|
||||
|
@ -202,7 +234,28 @@ main (int argc, char **argv)
|
|||
procetime, procprog, procargs);
|
||||
|
||||
/* Ignore self */
|
||||
if (mypid == procpid) continue;
|
||||
if ((usepid && mypid == procpid) ||
|
||||
(!usepid && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino) ||
|
||||
(ret == -1 && errno == ENOENT))) {
|
||||
if (verbose >= 3)
|
||||
printf("not considering - is myself or gone\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* filter kernel threads (childs of KTHREAD_PARENT)*/
|
||||
/* TODO adapt for other OSes than GNU/Linux
|
||||
sorry for not doing that, but I've no other OSes to test :-( */
|
||||
if (kthread_filter == 1) {
|
||||
/* get pid KTHREAD_PARENT */
|
||||
if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) )
|
||||
kthread_ppid = procpid;
|
||||
|
||||
if (kthread_ppid == procppid) {
|
||||
if (verbose >= 2)
|
||||
printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((options & STAT) && (strstr (statopts, procstat)))
|
||||
resultsum |= STAT;
|
||||
|
@ -238,24 +291,24 @@ main (int argc, char **argv)
|
|||
}
|
||||
|
||||
if (metric == METRIC_VSZ)
|
||||
i = check_thresholds (procvsz);
|
||||
i = get_status ((double)procvsz, procs_thresholds);
|
||||
else if (metric == METRIC_RSS)
|
||||
i = check_thresholds (procrss);
|
||||
i = get_status ((double)procrss, procs_thresholds);
|
||||
/* TODO? float thresholds for --metric=CPU */
|
||||
else if (metric == METRIC_CPU)
|
||||
i = check_thresholds ((int)procpcpu);
|
||||
i = get_status (procpcpu, procs_thresholds);
|
||||
else if (metric == METRIC_ELAPSED)
|
||||
i = check_thresholds (procseconds);
|
||||
i = get_status ((double)procseconds, procs_thresholds);
|
||||
|
||||
if (metric != METRIC_PROCS) {
|
||||
if (i == STATE_WARNING) {
|
||||
warn++;
|
||||
asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
|
||||
xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
|
||||
result = max_state (result, i);
|
||||
}
|
||||
if (i == STATE_CRITICAL) {
|
||||
crit++;
|
||||
asprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
|
||||
xasprintf (&fails, "%s%s%s", fails, (strcmp(fails,"") ? ", " : ""), procprog);
|
||||
result = max_state (result, i);
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +329,7 @@ main (int argc, char **argv)
|
|||
|
||||
/* Needed if procs found, but none match filter */
|
||||
if ( metric == METRIC_PROCS ) {
|
||||
result = max_state (result, check_thresholds (procs) );
|
||||
result = max_state (result, get_status ((double)procs, procs_thresholds) );
|
||||
}
|
||||
|
||||
if ( result == STATE_OK ) {
|
||||
|
@ -301,6 +354,13 @@ main (int argc, char **argv)
|
|||
if ( verbose >= 1 && strcmp(fails,"") )
|
||||
printf (" [%s]", fails);
|
||||
|
||||
if (metric == METRIC_PROCS)
|
||||
printf (" | procs=%d;%s;%s;0;", procs,
|
||||
warning_range ? warning_range : "",
|
||||
critical_range ? critical_range : "");
|
||||
else
|
||||
printf (" | procs=%d;;;0; procs_warn=%d;;;0; procs_crit=%d;;;0;", procs, warn, crit);
|
||||
|
||||
printf ("\n");
|
||||
return result;
|
||||
}
|
||||
|
@ -327,6 +387,7 @@ process_arguments (int argc, char **argv)
|
|||
{"timeout", required_argument, 0, 't'},
|
||||
{"status", required_argument, 0, 's'},
|
||||
{"ppid", required_argument, 0, 'p'},
|
||||
{"user", required_argument, 0, 'u'},
|
||||
{"command", required_argument, 0, 'C'},
|
||||
{"vsz", required_argument, 0, 'z'},
|
||||
{"rss", required_argument, 0, 'r'},
|
||||
|
@ -338,6 +399,8 @@ process_arguments (int argc, char **argv)
|
|||
{"verbose", no_argument, 0, 'v'},
|
||||
{"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
|
||||
{"input-file", required_argument, 0, CHAR_MAX+2},
|
||||
{"no-kthreads", required_argument, 0, 'k'},
|
||||
{"traditional-filter", no_argument, 0, 'T'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -346,7 +409,7 @@ process_arguments (int argc, char **argv)
|
|||
strcpy (argv[c], "-t");
|
||||
|
||||
while (1) {
|
||||
c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:",
|
||||
c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T",
|
||||
longopts, &option);
|
||||
|
||||
if (c == -1 || c == EOF)
|
||||
|
@ -368,32 +431,14 @@ process_arguments (int argc, char **argv)
|
|||
timeout_interval = atoi (optarg);
|
||||
break;
|
||||
case 'c': /* critical threshold */
|
||||
if (is_integer (optarg))
|
||||
cmax = atoi (optarg);
|
||||
else if (sscanf (optarg, ":%d", &cmax) == 1)
|
||||
break;
|
||||
else if (sscanf (optarg, "%d:%d", &cmin, &cmax) == 2)
|
||||
break;
|
||||
else if (sscanf (optarg, "%d:", &cmin) == 1)
|
||||
break;
|
||||
else
|
||||
usage4 (_("Critical Process Count must be an integer!"));
|
||||
critical_range = optarg;
|
||||
break;
|
||||
case 'w': /* warning threshold */
|
||||
if (is_integer (optarg))
|
||||
wmax = atoi (optarg);
|
||||
else if (sscanf (optarg, ":%d", &wmax) == 1)
|
||||
break;
|
||||
else if (sscanf (optarg, "%d:%d", &wmin, &wmax) == 2)
|
||||
break;
|
||||
else if (sscanf (optarg, "%d:", &wmin) == 1)
|
||||
break;
|
||||
else
|
||||
usage4 (_("Warning Process Count must be an integer!"));
|
||||
warning_range = optarg;
|
||||
break;
|
||||
case 'p': /* process id */
|
||||
if (sscanf (optarg, "%d%[^0-9]", &ppid, tmp) == 1) {
|
||||
asprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
|
||||
xasprintf (&fmt, "%s%sPPID = %d", (fmt ? fmt : "") , (options ? ", " : ""), ppid);
|
||||
options |= PPID;
|
||||
break;
|
||||
}
|
||||
|
@ -403,7 +448,7 @@ process_arguments (int argc, char **argv)
|
|||
break;
|
||||
else
|
||||
statopts = optarg;
|
||||
asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
|
||||
xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
|
||||
options |= STAT;
|
||||
break;
|
||||
case 'u': /* user or user id */
|
||||
|
@ -423,7 +468,7 @@ process_arguments (int argc, char **argv)
|
|||
uid = pw->pw_uid;
|
||||
}
|
||||
user = pw->pw_name;
|
||||
asprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""),
|
||||
xasprintf (&fmt, "%s%sUID = %d (%s)", (fmt ? fmt : ""), (options ? ", " : ""),
|
||||
uid, user);
|
||||
options |= USER;
|
||||
break;
|
||||
|
@ -433,7 +478,7 @@ process_arguments (int argc, char **argv)
|
|||
break;
|
||||
else
|
||||
prog = optarg;
|
||||
asprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
|
||||
xasprintf (&fmt, _("%s%scommand name '%s'"), (fmt ? fmt : ""), (options ? ", " : ""),
|
||||
prog);
|
||||
options |= PROG;
|
||||
break;
|
||||
|
@ -443,7 +488,7 @@ process_arguments (int argc, char **argv)
|
|||
break;
|
||||
else
|
||||
args = optarg;
|
||||
asprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
|
||||
xasprintf (&fmt, "%s%sargs '%s'", (fmt ? fmt : ""), (options ? ", " : ""), args);
|
||||
options |= ARGS;
|
||||
break;
|
||||
case CHAR_MAX+1:
|
||||
|
@ -459,19 +504,19 @@ process_arguments (int argc, char **argv)
|
|||
temp_string[i]=',';
|
||||
i++;
|
||||
}
|
||||
asprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string);
|
||||
xasprintf (&fmt, "%s%sregex args '%s'", (fmt ? fmt : ""), (options ? ", " : ""), temp_string);
|
||||
options |= EREG_ARGS;
|
||||
break;
|
||||
case 'r': /* RSS */
|
||||
if (sscanf (optarg, "%d%[^0-9]", &rss, tmp) == 1) {
|
||||
asprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
|
||||
xasprintf (&fmt, "%s%sRSS >= %d", (fmt ? fmt : ""), (options ? ", " : ""), rss);
|
||||
options |= RSS;
|
||||
break;
|
||||
}
|
||||
usage4 (_("RSS must be an integer!"));
|
||||
case 'z': /* VSZ */
|
||||
if (sscanf (optarg, "%d%[^0-9]", &vsz, tmp) == 1) {
|
||||
asprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
|
||||
xasprintf (&fmt, "%s%sVSZ >= %d", (fmt ? fmt : ""), (options ? ", " : ""), vsz);
|
||||
options |= VSZ;
|
||||
break;
|
||||
}
|
||||
|
@ -479,13 +524,13 @@ process_arguments (int argc, char **argv)
|
|||
case 'P': /* PCPU */
|
||||
/* TODO: -P 1.5.5 is accepted */
|
||||
if (sscanf (optarg, "%f%[^0-9.]", &pcpu, tmp) == 1) {
|
||||
asprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
|
||||
xasprintf (&fmt, "%s%sPCPU >= %.2f", (fmt ? fmt : ""), (options ? ", " : ""), pcpu);
|
||||
options |= PCPU;
|
||||
break;
|
||||
}
|
||||
usage4 (_("PCPU must be a float!"));
|
||||
case 'm':
|
||||
asprintf (&metric_name, "%s", optarg);
|
||||
xasprintf (&metric_name, "%s", optarg);
|
||||
if ( strcmp(optarg, "PROCS") == 0) {
|
||||
metric = METRIC_PROCS;
|
||||
break;
|
||||
|
@ -508,9 +553,15 @@ process_arguments (int argc, char **argv)
|
|||
}
|
||||
|
||||
usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!"));
|
||||
case 'k': /* linux kernel thread filter */
|
||||
kthread_filter = 1;
|
||||
break;
|
||||
case 'v': /* command */
|
||||
verbose++;
|
||||
break;
|
||||
case 'T':
|
||||
usepid = 1;
|
||||
break;
|
||||
case CHAR_MAX+2:
|
||||
input_filename = optarg;
|
||||
break;
|
||||
|
@ -518,16 +569,19 @@ process_arguments (int argc, char **argv)
|
|||
}
|
||||
|
||||
c = optind;
|
||||
if (wmax == -1 && argv[c])
|
||||
wmax = atoi (argv[c++]);
|
||||
if (cmax == -1 && argv[c])
|
||||
cmax = atoi (argv[c++]);
|
||||
if ((! warning_range) && argv[c])
|
||||
warning_range = argv[c++];
|
||||
if ((! critical_range) && argv[c])
|
||||
critical_range = argv[c++];
|
||||
if (statopts == NULL && argv[c]) {
|
||||
asprintf (&statopts, "%s", argv[c++]);
|
||||
asprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
|
||||
xasprintf (&statopts, "%s", argv[c++]);
|
||||
xasprintf (&fmt, _("%s%sSTATE = %s"), (fmt ? fmt : ""), (options ? ", " : ""), statopts);
|
||||
options |= STAT;
|
||||
}
|
||||
|
||||
/* this will abort in case of invalid ranges */
|
||||
set_thresholds (&procs_thresholds, warning_range, critical_range);
|
||||
|
||||
return validate_arguments ();
|
||||
}
|
||||
|
||||
|
@ -536,27 +590,6 @@ process_arguments (int argc, char **argv)
|
|||
int
|
||||
validate_arguments ()
|
||||
{
|
||||
|
||||
if (wmax >= 0 && wmin == -1)
|
||||
wmin = 0;
|
||||
if (cmax >= 0 && cmin == -1)
|
||||
cmin = 0;
|
||||
if (wmax >= wmin && cmax >= cmin) { /* standard ranges */
|
||||
if (wmax > cmax && cmax != -1) {
|
||||
printf (_("wmax (%d) cannot be greater than cmax (%d)\n"), wmax, cmax);
|
||||
return ERROR;
|
||||
}
|
||||
if (cmin > wmin && wmin != -1) {
|
||||
printf (_("wmin (%d) cannot be less than cmin (%d)\n"), wmin, cmin);
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) { */
|
||||
/* printf ("At least one threshold must be set\n"); */
|
||||
/* return ERROR; */
|
||||
/* } */
|
||||
|
||||
if (options == 0)
|
||||
options = ALL;
|
||||
|
||||
|
@ -579,40 +612,6 @@ validate_arguments ()
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* Check thresholds against value */
|
||||
int
|
||||
check_thresholds (int value)
|
||||
{
|
||||
if (wmax == -1 && cmax == -1 && wmin == -1 && cmin == -1) {
|
||||
return OK;
|
||||
}
|
||||
else if (cmax >= 0 && cmin >= 0 && cmax < cmin) {
|
||||
if (value > cmax && value < cmin)
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
else if (cmax >= 0 && value > cmax) {
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
else if (cmin >= 0 && value < cmin) {
|
||||
return STATE_CRITICAL;
|
||||
}
|
||||
|
||||
if (wmax >= 0 && wmin >= 0 && wmax < wmin) {
|
||||
if (value > wmax && value < wmin) {
|
||||
return STATE_WARNING;
|
||||
}
|
||||
}
|
||||
else if (wmax >= 0 && value > wmax) {
|
||||
return STATE_WARNING;
|
||||
}
|
||||
else if (wmin >= 0 && value < wmin) {
|
||||
return STATE_WARNING;
|
||||
}
|
||||
return STATE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* convert the elapsed time to seconds */
|
||||
int
|
||||
convert_to_seconds(char *etime) {
|
||||
|
@ -713,6 +712,9 @@ print_help (void)
|
|||
printf (" %s\n", "-v, --verbose");
|
||||
printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
|
||||
|
||||
printf (" %s\n", "-T, --traditional");
|
||||
printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
|
||||
|
||||
printf ("\n");
|
||||
printf ("%s\n", "Filters:");
|
||||
printf (" %s\n", "-s, --state=STATUSFLAGS");
|
||||
|
@ -735,6 +737,8 @@ print_help (void)
|
|||
printf (" %s\n", _("Only scan for processes with args that contain the regex STRING."));
|
||||
printf (" %s\n", "-C, --command=COMMAND");
|
||||
printf (" %s\n", _("Only scan for exact matches of COMMAND (without path)."));
|
||||
printf (" %s\n", "-k, --no-kthreads");
|
||||
printf (" %s\n", _("Only scan for non kernel threads (works on Linux only)."));
|
||||
|
||||
printf(_("\n\
|
||||
RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\
|
||||
|
@ -769,5 +773,5 @@ print_usage (void)
|
|||
printf ("%s\n", _("Usage:"));
|
||||
printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname);
|
||||
printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n");
|
||||
printf (" [-C command] [-t timeout] [-v]\n");
|
||||
printf (" [-C command] [-k] [-t timeout] [-v]\n");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue