summaryrefslogtreecommitdiffstats
path: root/plugins/check_procs.c
diff options
context:
space:
mode:
authorSebastian Schmidt <sschmidt@interhyp.de>2012-11-07 17:56:02 (GMT)
committerHolger Weiss <holger@zedat.fu-berlin.de>2013-08-18 10:59:57 (GMT)
commitce7a99789ddb3c6047135eef87ebdb695673612d (patch)
tree74324c328ebe170414b0ebd9606ba08d6a6b054e /plugins/check_procs.c
parentf3dbc2ec871da22028969540424a63ff51404cfd (diff)
downloadmonitoring-plugins-ce7a99789ddb3c6047135eef87ebdb695673612d.tar.gz
check_procs: filter out self by /proc/pid/exe
Make check_procs filter out itself in the process list by comparing the file pointed to by /proc/pid/exe. On platforms where this is not available or when check_procs is passed the -T flag, the old behaviour (check whether PID equals getpid()) is retained. This fixes some false alarms when e.g. Nagios has, for whatever reasons, some backlog of checks to run and check_procs with -a is called more than once in a short time, matching its sister process.
Diffstat (limited to 'plugins/check_procs.c')
-rw-r--r--plugins/check_procs.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/plugins/check_procs.c b/plugins/check_procs.c
index 9de3cc2..467a1b4 100644
--- a/plugins/check_procs.c
+++ b/plugins/check_procs.c
@@ -43,6 +43,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
43 43
44#include <pwd.h> 44#include <pwd.h>
45 45
46#ifdef HAVE_SYS_STAT_H
47#include <sys/stat.h>
48typedef struct stat struct_stat_t;
49#else
50/* won't be used anyway */
51typedef struct { dev_t dev; ino_t ino; } struct_stat_t;
52#endif
53
46int process_arguments (int, char **); 54int process_arguments (int, char **);
47int validate_arguments (void); 55int validate_arguments (void);
48int convert_to_seconds (char *); 56int convert_to_seconds (char *);
@@ -95,9 +103,24 @@ char *fmt;
95char *fails; 103char *fails;
96char tmp[MAX_INPUT_BUFFER]; 104char tmp[MAX_INPUT_BUFFER];
97int kthread_filter = 0; 105int kthread_filter = 0;
106int usepid = 0; /* whether to test for pid or /proc/pid/exe */
98 107
99FILE *ps_input = NULL; 108FILE *ps_input = NULL;
100 109
110static int
111stat_exe (const pid_t pid, struct_stat_t *buf) {
112#if defined(HAVE_PROC_PID_EXE) && defined(HAVE_SYS_STAT_H)
113 char *path;
114 int ret;
115 xasprintf(&path, "/proc/%d/exe", pid);
116 ret = stat(path, buf);
117 free(path);
118 return ret;
119#else
120 return -1;
121#endif
122}
123
101 124
102int 125int
103main (int argc, char **argv) 126main (int argc, char **argv)
@@ -107,6 +130,9 @@ main (int argc, char **argv)
107 char *procprog; 130 char *procprog;
108 131
109 pid_t mypid = 0; 132 pid_t mypid = 0;
133 struct_stat_t statbuf;
134 dev_t mydev = 0;
135 ino_t myino = 0;
110 int procuid = 0; 136 int procuid = 0;
111 pid_t procpid = 0; 137 pid_t procpid = 0;
112 pid_t procppid = 0; 138 pid_t procppid = 0;
@@ -150,8 +176,16 @@ main (int argc, char **argv)
150 if (process_arguments (argc, argv) == ERROR) 176 if (process_arguments (argc, argv) == ERROR)
151 usage4 (_("Could not parse arguments")); 177 usage4 (_("Could not parse arguments"));
152 178
153 /* get our pid */ 179 /* find ourself */
154 mypid = getpid(); 180 mypid = getpid();
181 if (usepid || stat_exe(mypid, &statbuf) == -1) {
182 /* usepid might have been set by -T */
183 usepid = 1;
184 } else {
185 usepid = 0;
186 mydev = statbuf.st_dev;
187 myino = statbuf.st_ino;
188 }
155 189
156 /* Set signal handling and alarm timeout */ 190 /* Set signal handling and alarm timeout */
157 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) { 191 if (signal (SIGALRM, timeout_alarm_handler) == SIG_ERR) {
@@ -206,7 +240,12 @@ main (int argc, char **argv)
206 procetime, procprog, procargs); 240 procetime, procprog, procargs);
207 241
208 /* Ignore self */ 242 /* Ignore self */
209 if (mypid == procpid) continue; 243 if ((usepid && mypid == procpid) ||
244 (!usepid && stat_exe(procpid, &statbuf) != -1 && statbuf.st_dev == mydev && statbuf.st_ino == myino)) {
245 if (verbose >= 3)
246 printf("not considering - is myself\n");
247 continue;
248 }
210 249
211 /* filter kernel threads (childs of KTHREAD_PARENT)*/ 250 /* filter kernel threads (childs of KTHREAD_PARENT)*/
212 /* TODO adapt for other OSes than GNU/Linux 251 /* TODO adapt for other OSes than GNU/Linux
@@ -366,6 +405,7 @@ process_arguments (int argc, char **argv)
366 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1}, 405 {"ereg-argument-array", required_argument, 0, CHAR_MAX+1},
367 {"input-file", required_argument, 0, CHAR_MAX+2}, 406 {"input-file", required_argument, 0, CHAR_MAX+2},
368 {"no-kthreads", required_argument, 0, 'k'}, 407 {"no-kthreads", required_argument, 0, 'k'},
408 {"traditional-filter", no_argument, 0, 'T'},
369 {0, 0, 0, 0} 409 {0, 0, 0, 0}
370 }; 410 };
371 411
@@ -374,7 +414,7 @@ process_arguments (int argc, char **argv)
374 strcpy (argv[c], "-t"); 414 strcpy (argv[c], "-t");
375 415
376 while (1) { 416 while (1) {
377 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:", 417 c = getopt_long (argc, argv, "Vvhkt:c:w:p:s:u:C:a:z:r:m:P:T",
378 longopts, &option); 418 longopts, &option);
379 419
380 if (c == -1 || c == EOF) 420 if (c == -1 || c == EOF)
@@ -524,6 +564,9 @@ process_arguments (int argc, char **argv)
524 case 'v': /* command */ 564 case 'v': /* command */
525 verbose++; 565 verbose++;
526 break; 566 break;
567 case 'T':
568 usepid = 1;
569 break;
527 case CHAR_MAX+2: 570 case CHAR_MAX+2:
528 input_filename = optarg; 571 input_filename = optarg;
529 break; 572 break;
@@ -674,6 +717,9 @@ print_help (void)
674 printf (" %s\n", "-v, --verbose"); 717 printf (" %s\n", "-v, --verbose");
675 printf (" %s\n", _("Extra information. Up to 3 verbosity levels")); 718 printf (" %s\n", _("Extra information. Up to 3 verbosity levels"));
676 719
720 printf (" %s\n", "-T, --traditional");
721 printf (" %s\n", _("Filter own process the traditional way by PID instead of /proc/pid/exe"));
722
677 printf ("\n"); 723 printf ("\n");
678 printf ("%s\n", "Filters:"); 724 printf ("%s\n", "Filters:");
679 printf (" %s\n", "-s, --state=STATUSFLAGS"); 725 printf (" %s\n", "-s, --state=STATUSFLAGS");