aboutsummaryrefslogtreecommitdiff
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$";
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);
}