diff options
Diffstat (limited to 'plugins/check_disk.c')
-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$"; const char *copyright = "1999-2004"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; + /* + * Additional inode code by Jorgen Lundman <lundman@lundman.net> + */ + + #include "common.h" #if HAVE_INTTYPES_H # include <inttypes.h> @@ -39,7 +44,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #endif /* If nonzero, show inode information. */ -/* static int inode_format; */ +static int inode_format; /* If nonzero, show even filesystems with zero size or uninteresting types. */ @@ -69,6 +74,8 @@ struct name_list uintmax_t c_df; double w_dfp; double c_dfp; + double w_idfp; + double c_idfp; struct name_list *name_next; }; @@ -114,8 +121,8 @@ enum int process_arguments (int, char **); void print_path (const char *mypath); -int validate_arguments (uintmax_t, uintmax_t, double, double, char *); -int check_disk (double usp, double free_disk); +int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); +int check_disk (double usp, uintmax_t free_disk, double uisp); int walk_name_list (struct name_list *list, const char *name); void print_help (void); void print_usage (void); @@ -124,6 +131,8 @@ uintmax_t w_df = 0; uintmax_t c_df = 0; double w_dfp = -1.0; double c_dfp = -1.0; +double w_idfp = -1.0; +double c_idfp = -1.0; char *path; char *exclude_device; char *units; @@ -140,7 +149,7 @@ static struct mount_entry *mount_list; int main (int argc, char **argv) { - double usp = -1.0; + double usp = -1.0, uisp = -1.0; int result = STATE_UNKNOWN; int disk_result = STATE_UNKNOWN; char file_system[MAX_INPUT_BUFFER]; @@ -148,7 +157,7 @@ main (int argc, char **argv) char *details; char *perf; uintmax_t psize; - float free_space, free_space_pct, total_space; + float free_space, free_space_pct, total_space, inode_space_pct; struct mount_entry *me; struct fs_usage fsp; @@ -220,15 +229,26 @@ main (int argc, char **argv) if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks; - disk_result = check_disk (usp, (double)(fsp.fsu_bavail * fsp.fsu_blocksize / mult)); + uisp = (double)(fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files; + disk_result = check_disk (usp, fsp.fsu_bavail, uisp); + + result = max_state (disk_result, result); psize = fsp.fsu_blocks*fsp.fsu_blocksize/mult; + + + /* Moved this computation up here so we can add it + * to perf */ + inode_space_pct = (float)fsp.fsu_ffree*100/fsp.fsu_files; + + asprintf (&perf, "%s %s", perf, perfdata ((!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir, psize-(fsp.fsu_bavail*fsp.fsu_blocksize/mult), units, TRUE, min ((uintmax_t)psize-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*psize)), TRUE, min ((uintmax_t)psize-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*psize)), - TRUE, 0, + TRUE, inode_space_pct, + TRUE, psize)); if (disk_result==STATE_OK && erronly && !verbose) continue; @@ -237,17 +257,20 @@ main (int argc, char **argv) free_space_pct = (float)fsp.fsu_bavail*100/fsp.fsu_blocks; total_space = (float)fsp.fsu_blocks*fsp.fsu_blocksize/mult; if (disk_result!=STATE_OK || verbose>=0) - asprintf (&output, ("%s %s %.0f %s (%.0f%%);"), + asprintf (&output, ("%s %s %.0f %s (%.0f%% inode=%.0f%%);"), output, (!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir, free_space, units, - free_space_pct); + free_space_pct, + inode_space_pct); + asprintf (&details, _("%s\n\ -%.0f of %.0f %s (%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"), - details, free_space, total_space, units, free_space_pct, +%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"), + details, free_space, total_space, units, free_space_pct, inode_space_pct, me->me_devname, me->me_type, me->me_mountdir, (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp); + } } @@ -292,6 +315,9 @@ process_arguments (int argc, char **argv) {"timeout", required_argument, 0, 't'}, {"warning", required_argument, 0, 'w'}, {"critical", required_argument, 0, 'c'}, + {"iwarning", required_argument, 0, 'W'}, + /* Dang, -C is taken. We might want to reshuffle this. */ + {"icritical", required_argument, 0, 'K'}, {"local", required_argument, 0, 'l'}, {"kilobytes", required_argument, 0, 'k'}, {"megabytes", required_argument, 0, 'm'}, @@ -326,7 +352,7 @@ process_arguments (int argc, char **argv) strcpy (argv[c], "-t"); while (1) { - c = getopt_long (argc, argv, "+?VqhveCt:c:w:u:p:x:X:mklM", longopts, &option); + c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklM", longopts, &option); if (c == -1 || c == EOF) break; @@ -374,6 +400,22 @@ process_arguments (int argc, char **argv) else { usage4 (_("Critical threshold must be integer or percentage!")); } + + + case 'W': /* warning inode threshold */ + if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &w_idfp) == 1) { + break; + } + else { + usage (_("Warning inode threshold must be percentage!\n")); + } + case 'K': /* kritical inode threshold */ + if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &c_idfp) == 1) { + break; + } + else { + usage (_("Critical inode threshold must be percentage!\n")); + } case 'u': if (units) free(units); @@ -430,10 +472,15 @@ process_arguments (int argc, char **argv) se = (struct name_list *) malloc (sizeof (struct name_list)); se->name = optarg; se->name_next = NULL; - se->w_df = 0; - se->c_df = 0; - se->w_dfp = -1.0; - se->c_dfp = -1.0; + + /* If you don't clear the w_fd etc values here, they + * get processed when you walk the list and assigned + * to the global w_df! + */ + se->w_df = 0; + se->c_df = 0; + se->w_dfp = 0; + se->c_dfp = 0; se->found = 0; se->found_len = 0; *dptail = se; @@ -443,10 +490,14 @@ process_arguments (int argc, char **argv) se = (struct name_list *) malloc (sizeof (struct name_list)); se->name = optarg; se->name_next = NULL; - se->w_df = 0; - se->c_df = 0; - se->w_dfp = -1.0; - se->c_dfp = -1.0; + /* If you don't clear the w_fd etc values here, they + * get processed when you walk the list and assigned + * to the global w_df! + */ + se->w_df = 0; + se->c_df = 0; + se->w_dfp = 0; + se->c_dfp = 0; se->found = 0; se->found_len = 0; *fstail = se; @@ -509,13 +560,15 @@ process_arguments (int argc, char **argv) temp_list->c_df, temp_list->w_dfp, temp_list->c_dfp, + temp_list->w_idfp, + temp_list->c_idfp, temp_list->name) == ERROR) result = ERROR; temp_list = temp_list->name_next; } return result; } else { - return validate_arguments (w_df, c_df, w_dfp, c_dfp, NULL); + return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); } } @@ -535,7 +588,7 @@ print_path (const char *mypath) int -validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, char *mypath) +validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath) { if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) { 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 print_path (mypath); return ERROR; } + else if ((iwp >= 0.0 || icp >= 0.0) && + (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) { + printf (_("\ +INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"), + icp, iwp); + print_path (mypath); + return ERROR; + } else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) { printf (_("\ 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 int -check_disk (double usp, double free_disk) + +check_disk (double usp, uintmax_t free_disk, double uisp) { - int result = STATE_UNKNOWN; - /* check the percent used space against thresholds */ - if (usp >= 0.0 && c_dfp >=0.0 && usp >= (100.0 - c_dfp)) - result = STATE_CRITICAL; - else if (c_df > 0 && free_disk <= c_df) - result = STATE_CRITICAL; - else if (usp >= 0.0 && w_dfp >=0.0 && usp >= (100.0 - w_dfp)) - result = STATE_WARNING; - else if (w_df > 0 && free_disk <= w_df) - result = STATE_WARNING; - else if (usp >= 0.0) + int result = STATE_UNKNOWN; + /* check the percent used space against thresholds */ + if (usp >= 0.0 && c_dfp >=0.0 && usp >= (100.0 - c_dfp)) + result = STATE_CRITICAL; + else if (uisp >= 0.0 && c_idfp >=0.0 && uisp >= (100.0 - c_idfp)) + result = STATE_CRITICAL; + else if (c_df > 0 && free_disk <= c_df) + result = STATE_CRITICAL; + else if (usp >= 0.0 && w_dfp >=0.0 && usp >= (100.0 - w_dfp)) + result = STATE_WARNING; + else if (uisp >= 0.0 && w_idfp >=0.0 && uisp >= (100.0 - w_idfp)) + result = STATE_WARNING; + else if (w_df > 0 && free_disk <= w_df) + result = STATE_WARNING; + else if (usp >= 0.0) result = STATE_OK; return result; } @@ -635,6 +701,10 @@ and generates an alert if free space is less than one of the threshold values.\n Exit with WARNING status if less than INTEGER --units of disk are free\n\ -w, --warning=PERCENT%%\n\ Exit with WARNING status if less than PERCENT of disk space is free\n\ + -W, --iwarning=PERCENT%%\n\ + Exit with WARNING status if less than PERCENT of inode space is free\n\ + -K, --icritical=PERCENT%%\n\ + Exit with CRITICAL status if less than PERCENT of inode space is free\n\ -c, --critical=INTEGER\n\ Exit with CRITICAL status if less than INTEGER --units of disk are free\n\ -c, --critical=PERCENT%%\n\ @@ -683,6 +753,6 @@ void print_usage (void) { printf ("\ -Usage: %s -w limit -c limit [-p path | -x device] [-t timeout] [-m] [-e]\n\ +Usage: %s -w limit -c limit [-p path | -x device] [-t timeout] [-m] [-e] [-W limit] [-K limit]\n\ [-v] [-q]\n", progname); } |