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 960902fc..81dd6c73 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 | } |
