summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_disk.c140
1 files changed, 105 insertions, 35 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 960902fc..81dd6c73 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -24,6 +24,11 @@ const char *revision = "$Revision$";
24const char *copyright = "1999-2004"; 24const char *copyright = "1999-2004";
25const char *email = "nagiosplug-devel@lists.sourceforge.net"; 25const char *email = "nagiosplug-devel@lists.sourceforge.net";
26 26
27 /*
28 * Additional inode code by Jorgen Lundman <lundman@lundman.net>
29 */
30
31
27#include "common.h" 32#include "common.h"
28#if HAVE_INTTYPES_H 33#if HAVE_INTTYPES_H
29# include <inttypes.h> 34# include <inttypes.h>
@@ -39,7 +44,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
39#endif 44#endif
40 45
41/* If nonzero, show inode information. */ 46/* If nonzero, show inode information. */
42/* static int inode_format; */ 47static int inode_format;
43 48
44/* If nonzero, show even filesystems with zero size or 49/* If nonzero, show even filesystems with zero size or
45 uninteresting types. */ 50 uninteresting types. */
@@ -69,6 +74,8 @@ struct name_list
69 uintmax_t c_df; 74 uintmax_t c_df;
70 double w_dfp; 75 double w_dfp;
71 double c_dfp; 76 double c_dfp;
77 double w_idfp;
78 double c_idfp;
72 struct name_list *name_next; 79 struct name_list *name_next;
73}; 80};
74 81
@@ -114,8 +121,8 @@ enum
114 121
115int process_arguments (int, char **); 122int process_arguments (int, char **);
116void print_path (const char *mypath); 123void print_path (const char *mypath);
117int validate_arguments (uintmax_t, uintmax_t, double, double, char *); 124int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
118int check_disk (double usp, double free_disk); 125int check_disk (double usp, uintmax_t free_disk, double uisp);
119int walk_name_list (struct name_list *list, const char *name); 126int walk_name_list (struct name_list *list, const char *name);
120void print_help (void); 127void print_help (void);
121void print_usage (void); 128void print_usage (void);
@@ -124,6 +131,8 @@ uintmax_t w_df = 0;
124uintmax_t c_df = 0; 131uintmax_t c_df = 0;
125double w_dfp = -1.0; 132double w_dfp = -1.0;
126double c_dfp = -1.0; 133double c_dfp = -1.0;
134double w_idfp = -1.0;
135double c_idfp = -1.0;
127char *path; 136char *path;
128char *exclude_device; 137char *exclude_device;
129char *units; 138char *units;
@@ -140,7 +149,7 @@ static struct mount_entry *mount_list;
140int 149int
141main (int argc, char **argv) 150main (int argc, char **argv)
142{ 151{
143 double usp = -1.0; 152 double usp = -1.0, uisp = -1.0;
144 int result = STATE_UNKNOWN; 153 int result = STATE_UNKNOWN;
145 int disk_result = STATE_UNKNOWN; 154 int disk_result = STATE_UNKNOWN;
146 char file_system[MAX_INPUT_BUFFER]; 155 char file_system[MAX_INPUT_BUFFER];
@@ -148,7 +157,7 @@ main (int argc, char **argv)
148 char *details; 157 char *details;
149 char *perf; 158 char *perf;
150 uintmax_t psize; 159 uintmax_t psize;
151 float free_space, free_space_pct, total_space; 160 float free_space, free_space_pct, total_space, inode_space_pct;
152 161
153 struct mount_entry *me; 162 struct mount_entry *me;
154 struct fs_usage fsp; 163 struct fs_usage fsp;
@@ -220,15 +229,26 @@ main (int argc, char **argv)
220 229
221 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { 230 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
222 usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks; 231 usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks;
223 disk_result = check_disk (usp, (double)(fsp.fsu_bavail * fsp.fsu_blocksize / mult)); 232 uisp = (double)(fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files;
233 disk_result = check_disk (usp, fsp.fsu_bavail, uisp);
234
235
224 result = max_state (disk_result, result); 236 result = max_state (disk_result, result);
225 psize = fsp.fsu_blocks*fsp.fsu_blocksize/mult; 237 psize = fsp.fsu_blocks*fsp.fsu_blocksize/mult;
238
239
240 /* Moved this computation up here so we can add it
241 * to perf */
242 inode_space_pct = (float)fsp.fsu_ffree*100/fsp.fsu_files;
243
244
226 asprintf (&perf, "%s %s", perf, 245 asprintf (&perf, "%s %s", perf,
227 perfdata ((!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 246 perfdata ((!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
228 psize-(fsp.fsu_bavail*fsp.fsu_blocksize/mult), units, 247 psize-(fsp.fsu_bavail*fsp.fsu_blocksize/mult), units,
229 TRUE, min ((uintmax_t)psize-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*psize)), 248 TRUE, min ((uintmax_t)psize-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*psize)),
230 TRUE, min ((uintmax_t)psize-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*psize)), 249 TRUE, min ((uintmax_t)psize-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*psize)),
231 TRUE, 0, 250 TRUE, inode_space_pct,
251
232 TRUE, psize)); 252 TRUE, psize));
233 if (disk_result==STATE_OK && erronly && !verbose) 253 if (disk_result==STATE_OK && erronly && !verbose)
234 continue; 254 continue;
@@ -237,17 +257,20 @@ main (int argc, char **argv)
237 free_space_pct = (float)fsp.fsu_bavail*100/fsp.fsu_blocks; 257 free_space_pct = (float)fsp.fsu_bavail*100/fsp.fsu_blocks;
238 total_space = (float)fsp.fsu_blocks*fsp.fsu_blocksize/mult; 258 total_space = (float)fsp.fsu_blocks*fsp.fsu_blocksize/mult;
239 if (disk_result!=STATE_OK || verbose>=0) 259 if (disk_result!=STATE_OK || verbose>=0)
240 asprintf (&output, ("%s %s %.0f %s (%.0f%%);"), 260 asprintf (&output, ("%s %s %.0f %s (%.0f%% inode=%.0f%%);"),
241 output, 261 output,
242 (!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 262 (!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
243 free_space, 263 free_space,
244 units, 264 units,
245 free_space_pct); 265 free_space_pct,
266 inode_space_pct);
267
246 asprintf (&details, _("%s\n\ 268 asprintf (&details, _("%s\n\
247%.0f of %.0f %s (%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"), 269%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
248 details, free_space, total_space, units, free_space_pct, 270 details, free_space, total_space, units, free_space_pct, inode_space_pct,
249 me->me_devname, me->me_type, me->me_mountdir, 271 me->me_devname, me->me_type, me->me_mountdir,
250 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp); 272 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
273
251 } 274 }
252 275
253 } 276 }
@@ -292,6 +315,9 @@ process_arguments (int argc, char **argv)
292 {"timeout", required_argument, 0, 't'}, 315 {"timeout", required_argument, 0, 't'},
293 {"warning", required_argument, 0, 'w'}, 316 {"warning", required_argument, 0, 'w'},
294 {"critical", required_argument, 0, 'c'}, 317 {"critical", required_argument, 0, 'c'},
318 {"iwarning", required_argument, 0, 'W'},
319 /* Dang, -C is taken. We might want to reshuffle this. */
320 {"icritical", required_argument, 0, 'K'},
295 {"local", required_argument, 0, 'l'}, 321 {"local", required_argument, 0, 'l'},
296 {"kilobytes", required_argument, 0, 'k'}, 322 {"kilobytes", required_argument, 0, 'k'},
297 {"megabytes", required_argument, 0, 'm'}, 323 {"megabytes", required_argument, 0, 'm'},
@@ -326,7 +352,7 @@ process_arguments (int argc, char **argv)
326 strcpy (argv[c], "-t"); 352 strcpy (argv[c], "-t");
327 353
328 while (1) { 354 while (1) {
329 c = getopt_long (argc, argv, "+?VqhveCt:c:w:u:p:x:X:mklM", longopts, &option); 355 c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklM", longopts, &option);
330 356
331 if (c == -1 || c == EOF) 357 if (c == -1 || c == EOF)
332 break; 358 break;
@@ -374,6 +400,22 @@ process_arguments (int argc, char **argv)
374 else { 400 else {
375 usage4 (_("Critical threshold must be integer or percentage!")); 401 usage4 (_("Critical threshold must be integer or percentage!"));
376 } 402 }
403
404
405 case 'W': /* warning inode threshold */
406 if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &w_idfp) == 1) {
407 break;
408 }
409 else {
410 usage (_("Warning inode threshold must be percentage!\n"));
411 }
412 case 'K': /* kritical inode threshold */
413 if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &c_idfp) == 1) {
414 break;
415 }
416 else {
417 usage (_("Critical inode threshold must be percentage!\n"));
418 }
377 case 'u': 419 case 'u':
378 if (units) 420 if (units)
379 free(units); 421 free(units);
@@ -430,10 +472,15 @@ process_arguments (int argc, char **argv)
430 se = (struct name_list *) malloc (sizeof (struct name_list)); 472 se = (struct name_list *) malloc (sizeof (struct name_list));
431 se->name = optarg; 473 se->name = optarg;
432 se->name_next = NULL; 474 se->name_next = NULL;
433 se->w_df = 0; 475
434 se->c_df = 0; 476 /* If you don't clear the w_fd etc values here, they
435 se->w_dfp = -1.0; 477 * get processed when you walk the list and assigned
436 se->c_dfp = -1.0; 478 * to the global w_df!
479 */
480 se->w_df = 0;
481 se->c_df = 0;
482 se->w_dfp = 0;
483 se->c_dfp = 0;
437 se->found = 0; 484 se->found = 0;
438 se->found_len = 0; 485 se->found_len = 0;
439 *dptail = se; 486 *dptail = se;
@@ -443,10 +490,14 @@ process_arguments (int argc, char **argv)
443 se = (struct name_list *) malloc (sizeof (struct name_list)); 490 se = (struct name_list *) malloc (sizeof (struct name_list));
444 se->name = optarg; 491 se->name = optarg;
445 se->name_next = NULL; 492 se->name_next = NULL;
446 se->w_df = 0; 493 /* If you don't clear the w_fd etc values here, they
447 se->c_df = 0; 494 * get processed when you walk the list and assigned
448 se->w_dfp = -1.0; 495 * to the global w_df!
449 se->c_dfp = -1.0; 496 */
497 se->w_df = 0;
498 se->c_df = 0;
499 se->w_dfp = 0;
500 se->c_dfp = 0;
450 se->found = 0; 501 se->found = 0;
451 se->found_len = 0; 502 se->found_len = 0;
452 *fstail = se; 503 *fstail = se;
@@ -509,13 +560,15 @@ process_arguments (int argc, char **argv)
509 temp_list->c_df, 560 temp_list->c_df,
510 temp_list->w_dfp, 561 temp_list->w_dfp,
511 temp_list->c_dfp, 562 temp_list->c_dfp,
563 temp_list->w_idfp,
564 temp_list->c_idfp,
512 temp_list->name) == ERROR) 565 temp_list->name) == ERROR)
513 result = ERROR; 566 result = ERROR;
514 temp_list = temp_list->name_next; 567 temp_list = temp_list->name_next;
515 } 568 }
516 return result; 569 return result;
517 } else { 570 } else {
518 return validate_arguments (w_df, c_df, w_dfp, c_dfp, NULL); 571 return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL);
519 } 572 }
520} 573}
521 574
@@ -535,7 +588,7 @@ print_path (const char *mypath)
535 588
536 589
537int 590int
538validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, char *mypath) 591validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
539{ 592{
540 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) { 593 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
541 printf (_("INPUT ERROR: No thresholds specified")); 594 printf (_("INPUT ERROR: No thresholds specified"));
@@ -550,6 +603,14 @@ INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be betw
550 print_path (mypath); 603 print_path (mypath);
551 return ERROR; 604 return ERROR;
552 } 605 }
606 else if ((iwp >= 0.0 || icp >= 0.0) &&
607 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
608 printf (_("\
609INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
610 icp, iwp);
611 print_path (mypath);
612 return ERROR;
613 }
553 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) { 614 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
554 printf (_("\ 615 printf (_("\
555INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"), 616INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
@@ -568,19 +629,24 @@ INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greate
568 629
569 630
570int 631int
571check_disk (double usp, double free_disk) 632
633check_disk (double usp, uintmax_t free_disk, double uisp)
572{ 634{
573 int result = STATE_UNKNOWN; 635 int result = STATE_UNKNOWN;
574 /* check the percent used space against thresholds */ 636 /* check the percent used space against thresholds */
575 if (usp >= 0.0 && c_dfp >=0.0 && usp >= (100.0 - c_dfp)) 637 if (usp >= 0.0 && c_dfp >=0.0 && usp >= (100.0 - c_dfp))
576 result = STATE_CRITICAL; 638 result = STATE_CRITICAL;
577 else if (c_df > 0 && free_disk <= c_df) 639 else if (uisp >= 0.0 && c_idfp >=0.0 && uisp >= (100.0 - c_idfp))
578 result = STATE_CRITICAL; 640 result = STATE_CRITICAL;
579 else if (usp >= 0.0 && w_dfp >=0.0 && usp >= (100.0 - w_dfp)) 641 else if (c_df > 0 && free_disk <= c_df)
580 result = STATE_WARNING; 642 result = STATE_CRITICAL;
581 else if (w_df > 0 && free_disk <= w_df) 643 else if (usp >= 0.0 && w_dfp >=0.0 && usp >= (100.0 - w_dfp))
582 result = STATE_WARNING; 644 result = STATE_WARNING;
583 else if (usp >= 0.0) 645 else if (uisp >= 0.0 && w_idfp >=0.0 && uisp >= (100.0 - w_idfp))
646 result = STATE_WARNING;
647 else if (w_df > 0 && free_disk <= w_df)
648 result = STATE_WARNING;
649 else if (usp >= 0.0)
584 result = STATE_OK; 650 result = STATE_OK;
585 return result; 651 return result;
586} 652}
@@ -635,6 +701,10 @@ and generates an alert if free space is less than one of the threshold values.\n
635 Exit with WARNING status if less than INTEGER --units of disk are free\n\ 701 Exit with WARNING status if less than INTEGER --units of disk are free\n\
636 -w, --warning=PERCENT%%\n\ 702 -w, --warning=PERCENT%%\n\
637 Exit with WARNING status if less than PERCENT of disk space is free\n\ 703 Exit with WARNING status if less than PERCENT of disk space is free\n\
704 -W, --iwarning=PERCENT%%\n\
705 Exit with WARNING status if less than PERCENT of inode space is free\n\
706 -K, --icritical=PERCENT%%\n\
707 Exit with CRITICAL status if less than PERCENT of inode space is free\n\
638 -c, --critical=INTEGER\n\ 708 -c, --critical=INTEGER\n\
639 Exit with CRITICAL status if less than INTEGER --units of disk are free\n\ 709 Exit with CRITICAL status if less than INTEGER --units of disk are free\n\
640 -c, --critical=PERCENT%%\n\ 710 -c, --critical=PERCENT%%\n\
@@ -683,6 +753,6 @@ void
683print_usage (void) 753print_usage (void)
684{ 754{
685 printf ("\ 755 printf ("\
686Usage: %s -w limit -c limit [-p path | -x device] [-t timeout] [-m] [-e]\n\ 756Usage: %s -w limit -c limit [-p path | -x device] [-t timeout] [-m] [-e] [-W limit] [-K limit]\n\
687 [-v] [-q]\n", progname); 757 [-v] [-q]\n", progname);
688} 758}