diff options
-rw-r--r-- | plugins/check_disk.c | 140 |
1 files changed, 105 insertions, 35 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 960902f..81dd6c7 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c | |||
@@ -24,6 +24,11 @@ const char *revision = "$Revision$"; | |||
24 | const char *copyright = "1999-2004"; | 24 | const char *copyright = "1999-2004"; |
25 | const char *email = "nagiosplug-devel@lists.sourceforge.net"; | 25 | const 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; */ | 47 | static 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 | ||
115 | int process_arguments (int, char **); | 122 | int process_arguments (int, char **); |
116 | void print_path (const char *mypath); | 123 | void print_path (const char *mypath); |
117 | int validate_arguments (uintmax_t, uintmax_t, double, double, char *); | 124 | int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); |
118 | int check_disk (double usp, double free_disk); | 125 | int check_disk (double usp, uintmax_t free_disk, double uisp); |
119 | int walk_name_list (struct name_list *list, const char *name); | 126 | int walk_name_list (struct name_list *list, const char *name); |
120 | void print_help (void); | 127 | void print_help (void); |
121 | void print_usage (void); | 128 | void print_usage (void); |
@@ -124,6 +131,8 @@ uintmax_t w_df = 0; | |||
124 | uintmax_t c_df = 0; | 131 | uintmax_t c_df = 0; |
125 | double w_dfp = -1.0; | 132 | double w_dfp = -1.0; |
126 | double c_dfp = -1.0; | 133 | double c_dfp = -1.0; |
134 | double w_idfp = -1.0; | ||
135 | double c_idfp = -1.0; | ||
127 | char *path; | 136 | char *path; |
128 | char *exclude_device; | 137 | char *exclude_device; |
129 | char *units; | 138 | char *units; |
@@ -140,7 +149,7 @@ static struct mount_entry *mount_list; | |||
140 | int | 149 | int |
141 | main (int argc, char **argv) | 150 | main (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 | ||
537 | int | 590 | int |
538 | validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, char *mypath) | 591 | validate_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 (_("\ | ||
609 | INPUT 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 (_("\ |
555 | INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"), | 616 | INPUT 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 | ||
570 | int | 631 | int |
571 | check_disk (double usp, double free_disk) | 632 | |
633 | check_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 | |||
683 | print_usage (void) | 753 | print_usage (void) |
684 | { | 754 | { |
685 | printf ("\ | 755 | printf ("\ |
686 | Usage: %s -w limit -c limit [-p path | -x device] [-t timeout] [-m] [-e]\n\ | 756 | Usage: %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 | } |