diff options
Diffstat (limited to 'plugins/check_procs.c')
-rw-r--r-- | plugins/check_procs.c | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/plugins/check_procs.c b/plugins/check_procs.c index 6acedc7..d09bd8b 100644 --- a/plugins/check_procs.c +++ b/plugins/check_procs.c | |||
@@ -42,6 +42,11 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
42 | #include "regex.h" | 42 | #include "regex.h" |
43 | 43 | ||
44 | #include <pwd.h> | 44 | #include <pwd.h> |
45 | #include <errno.h> | ||
46 | |||
47 | #ifdef HAVE_SYS_STAT_H | ||
48 | #include <sys/stat.h> | ||
49 | #endif | ||
45 | 50 | ||
46 | int process_arguments (int, char **); | 51 | int process_arguments (int, char **); |
47 | int validate_arguments (void); | 52 | int validate_arguments (void); |
@@ -65,6 +70,10 @@ int options = 0; /* bitmask of filter criteria to test against */ | |||
65 | #define PCPU 256 | 70 | #define PCPU 256 |
66 | #define ELAPSED 512 | 71 | #define ELAPSED 512 |
67 | #define EREG_ARGS 1024 | 72 | #define EREG_ARGS 1024 |
73 | |||
74 | #define KTHREAD_PARENT "kthreadd" /* the parent process of kernel threads: | ||
75 | ppid of procs are compared to pid of this proc*/ | ||
76 | |||
68 | /* Different metrics */ | 77 | /* Different metrics */ |
69 | char *metric_name; | 78 | char *metric_name; |
70 | enum metric { | 79 | enum metric { |
@@ -90,9 +99,21 @@ regex_t re_args; | |||
90 | char *fmt; | 99 | char *fmt; |
91 | char *fails; | 100 | char *fails; |
92 | char tmp[MAX_INPUT_BUFFER]; | 101 | char tmp[MAX_INPUT_BUFFER]; |
102 | int kthread_filter = 0; | ||
103 | int usepid = 0; /* whether to test for pid or /proc/pid/exe */ | ||
93 | 104 | ||
94 | FILE *ps_input = NULL; | 105 | FILE *ps_input = NULL; |
95 | 106 | ||
107 | static int | ||
108 | stat_exe (const pid_t pid, struct stat *buf) { | ||
109 | char *path; | ||
110 | int ret; | ||
111 | xasprintf(&path, "/proc/%d/exe", pid); | ||
112 | ret = stat(path, buf); | ||
113 | free(path); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
96 | 117 | ||
97 | int | 118 | int |
98 | main (int argc, char **argv) | 119 | main (int argc, char **argv) |
@@ -102,9 +123,13 @@ main (int argc, char **argv) | |||
102 | char *procprog; | 123 | char *procprog; |
103 | 124 | ||
104 | pid_t mypid = 0; | 125 | pid_t mypid = 0; |
126 | struct stat statbuf; | ||
127 | dev_t mydev = 0; | ||
128 | ino_t myino = 0; | ||
105 | int procuid = 0; | 129 | int procuid = 0; |
106 | pid_t procpid = 0; | 130 | pid_t procpid = 0; |
107 | pid_t procppid = 0; | 131 | pid_t procppid = 0; |
132 | pid_t kthread_ppid = 0; | ||
108 | int procvsz = 0; | 133 | int procvsz = 0; |
109 | int procrss = 0; | 134 | int procrss = 0; |
110 | int procseconds = 0; | 135 | int procseconds = 0; |
@@ -125,6 +150,7 @@ main (int argc, char **argv) | |||
125 | int crit = 0; /* number of processes in crit state */ | 150 | int crit = 0; /* number of processes in crit state */ |
126 | int i = 0, j = 0; | 151 | int i = 0, j = 0; |
127 | int result = STATE_UNKNOWN; | 152 | int result = STATE_UNKNOWN; |
153 | int ret; | ||
128 | output chld_out, chld_err; | 154 | output chld_out, chld_err; |
129 | 155 | ||
130 | setlocale (LC_ALL, ""); | 156 | setlocale (LC_ALL, ""); |
@@ -144,8 +170,16 @@ main (int argc, char **argv) | |||
144 | if (process_arguments (argc, argv) == ERROR) | 170 | if (process_arguments (argc, argv) == ERROR) |
145 | usage4 (_("Could not parse arguments")); | 171 | usage4 (_("Could not parse arguments")); |
146 | 172 | ||
147 | /* get our pid */ | 173 | /* find ourself */ |
148 | mypid = getpid(); | 174 | mypid = getpid(); |
175 | if (usepid || stat_exe(mypid, &statbuf) == -1) { | ||
176 | /* usepid might have been set by -T */ | ||
177 | usepid = 1; | ||
178 | } else { | ||
179 | usepid = 0; | ||
180 | mydev = statbuf.st_dev; | ||
181 | myino = statbuf.st_ino; | ||
182 | } | ||
149 | 183 | ||
150 | /* Set signal handling and alarm timeout */ | 184 | /* Set signal handling and alarm timeout */ |
151 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { | 185 | if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { |
@@ -200,7 +234,28 @@ main (int argc, char **argv) | |||
200 | procetime, procprog, procargs); | 234 | procetime, procprog, procargs); |
201 | 235 | ||
202 | /* Ignore self */ | 236 | /* Ignore self */ |
203 | if (mypid == procpid) continue; | 237 | if ((usepid && mypid == procpid) || |
238 | (!usepid && ((ret = stat_exe(procpid, &statbuf) != -1) && statbuf.st_dev == mydev && statbuf.st_ino == myino) || | ||
239 | (ret == -1 && errno == ENOENT))) { | ||
240 | if (verbose >= 3) | ||
241 | printf("not considering - is myself or gone\n"); | ||
242 | continue; | ||
243 | } | ||
244 | |||
245 | /* filter kernel threads (childs of KTHREAD_PARENT)*/ | ||
246 | /* TODO adapt for other OSes than GNU/Linux | ||
247 | sorry for not doing that, but I've no other OSes to test :-( */ | ||
248 | if (kthread_filter == 1) { | ||
249 | /* get pid KTHREAD_PARENT */ | ||
250 | if (kthread_ppid == 0 && !strcmp(procprog, KTHREAD_PARENT) ) | ||
251 | kthread_ppid = procpid; | ||
252 | |||
253 | if (kthread_ppid == procppid) { | ||
254 | if (verbose >= 2) | ||
255 | printf ("Ignore kernel thread: pid=%d ppid=%d prog=%s args=%s\n", procpid, procppid, procprog, procargs); | ||
256 | continue; | ||
257 | } | ||
258 | } | ||
204 | 259 | ||
205 | if ((options & STAT) && (strstr (statopts, procstat))) | 260 | if ((options & STAT) && (strstr (statopts, procstat))) |
206 | resultsum |= STAT; | 261 | resultsum |= STAT; |
@@ -344,6 +399,8 @@ process_arguments (int argc, char **argv) | |||
344 | {"verbose", no_argument, 0, 'v'}, | 399 | {"verbose", no_argument, 0, 'v'}, |
345 | {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, | 400 | {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, |
346 | {"input-file", required_argument, 0, CHAR_MAX+2}, | 401 | {"input-file", required_argument, 0, CHAR_MAX+2}, |
402 | {"no-kthreads", required_argument, 0, 'k'}, | ||
403 | {"traditional-filter", no_argument, 0, 'T'}, | ||
347 | {0, 0, 0, 0} | 404 | {0, 0, 0, 0} |
348 | }; | 405 | }; |
349 | 406 | ||
@@ -352,7 +409,7 @@ process_arguments (int argc, char **argv) | |||
352 | strcpy (argv[c], "-t"); | 409 | strcpy (argv[c], "-t"); |
353 | 410 | ||
354 | while (1) { | 411 | while (1) { |
355 | c = getopt_long (argc, argv, "Vvht:c:w:p:s:u:C:a:z:r:m:P:", | 412 | c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T", |
356 | longopts, &option); | 413 | longopts, &option); |
357 | 414 | ||
358 | if (c == -1 || c == EOF) | 415 | if (c == -1 || c == EOF) |
@@ -496,9 +553,15 @@ process_arguments (int argc, char **argv) | |||
496 | } | 553 | } |
497 | 554 | ||
498 | usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); | 555 | usage4 (_("Metric must be one of PROCS, VSZ, RSS, CPU, ELAPSED!")); |
556 | case 'k': /* linux kernel thread filter */ | ||
557 | kthread_filter = 1; | ||
558 | break; | ||
499 | case 'v': /* command */ | 559 | case 'v': /* command */ |
500 | verbose++; | 560 | verbose++; |
501 | break; | 561 | break; |
562 | case 'T': | ||
563 | usepid = 1; | ||
564 | break; | ||
502 | case CHAR_MAX+2: | 565 | case CHAR_MAX+2: |
503 | input_filename = optarg; | 566 | input_filename = optarg; |
504 | break; | 567 | break; |
@@ -649,6 +712,9 @@ print_help (void) | |||
649 | printf (" %s\n", "-v, --verbose"); | 712 | printf (" %s\n", "-v, --verbose"); |
650 | printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); | 713 | printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); |
651 | 714 | ||
715 | printf (" %s\n", "-T, --traditional"); | ||
716 | printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe")); | ||
717 | |||
652 | printf ("\n"); | 718 | printf ("\n"); |
653 | printf ("%s\n", "Filters:"); | 719 | printf ("%s\n", "Filters:"); |
654 | printf (" %s\n", "-s, --state=STATUSFLAGS"); | 720 | printf (" %s\n", "-s, --state=STATUSFLAGS"); |
@@ -671,6 +737,8 @@ print_help (void) | |||
671 | printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); | 737 | printf (" %s\n", _("Only scan for processes with args that contain the regex STRING.")); |
672 | printf (" %s\n", "-C, --command=COMMAND"); | 738 | printf (" %s\n", "-C, --command=COMMAND"); |
673 | printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); | 739 | printf (" %s\n", _("Only scan for exact matches of COMMAND (without path).")); |
740 | printf (" %s\n", "-k, --no-kthreads"); | ||
741 | printf (" %s\n", _("Only scan for non kernel threads (works on Linux only).")); | ||
674 | 742 | ||
675 | printf(_("\n\ | 743 | printf(_("\n\ |
676 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ | 744 | RANGEs are specified 'min:max' or 'min:' or ':max' (or 'max'). If\n\ |
@@ -705,5 +773,5 @@ print_usage (void) | |||
705 | printf ("%s\n", _("Usage:")); | 773 | printf ("%s\n", _("Usage:")); |
706 | printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); | 774 | printf ("%s -w <range> -c <range> [-m metric] [-s state] [-p ppid]\n", progname); |
707 | printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); | 775 | printf (" [-u user] [-r rss] [-z vsz] [-P %%cpu] [-a argument-array]\n"); |
708 | printf (" [-C command] [-t timeout] [-v]\n"); | 776 | printf (" [-C command] [-k] [-t timeout] [-v]\n"); |
709 | } | 777 | } |