Major fixes to check_disk. Now should return same data as df

git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1452 f882894a-f735-0410-b71e-b25c423dba1c
This commit is contained in:
Ton Voon 2006-07-13 23:58:00 +00:00
parent 548083b2ea
commit 5912398b97
8 changed files with 649 additions and 182 deletions

View file

@ -5,6 +5,8 @@ This file documents the major additions and syntax changes between releases.
New check_apt plugin
Notice: plugins in contrib/ will start to be removed from this distribution.
Please check at http://www.nagiosexchange.org for contributed plugins
Major bug fixes to check_disk where values were incorrectly calculated and alerted on.
Perf data for warn/crit/max/min have been removed, to be readded soon.
1.4.3
Setuid plugins (check_dhcp, check_icmp) separated into plugins-root/. Run make install as root to install

View file

@ -31,7 +31,7 @@ main (int argc, char **argv)
thresholds *thresholds = NULL;
int rc;
plan_tests(74);
plan_tests(82);
range = parse_range_string("6");
ok( range != NULL, "'6' is valid range");
@ -41,6 +41,14 @@ main (int argc, char **argv)
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("1:12%%");
ok( range != NULL, "'1:12%%' is valid - percentages are ignored");
ok( range->start == 1, "Start correct");
ok( range->start_infinity == FALSE, "Not using negative infinity");
ok( range->end == 12, "End correct");
ok( range->end_infinity == FALSE, "Not using infinity");
free(range);
range = parse_range_string("-7:23");
ok( range != NULL, "'-7:23' is valid range");
ok( range->start == -7, "Start correct");
@ -114,6 +122,11 @@ main (int argc, char **argv)
range = parse_range_string("2:1");
ok( range == NULL, "'2:1' rejected");
rc = _set_thresholds(&thresholds, NULL, NULL);
ok( rc == 0, "Thresholds (NULL, NULL) set");
ok( thresholds->warning == NULL, "Warning not set");
ok( thresholds->critical == NULL, "Critical not set");
rc = _set_thresholds(&thresholds, NULL, "80");
ok( rc == 0, "Thresholds (NULL, '80') set");
ok( thresholds->warning == NULL, "Warning not set");

225
lib/utils_base.c Normal file
View file

@ -0,0 +1,225 @@
/*****************************************************************************
*
* utils_base.c
*
* Library of useful functions for plugins
* These functions are tested with libtap. See tests/ directory
*
* Copyright (c) 2006 Nagios Plugin Development Team
* License: GPL
*
* $Revision$
* $Date$
****************************************************************************/
#include "common.h"
#include "utils_base.h"
void
die (int result, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vprintf (fmt, ap);
va_end (ap);
exit (result);
}
void set_range_start (range *this, double value) {
this->start = value;
this->start_infinity = FALSE;
}
void set_range_end (range *this, double value) {
this->end = value;
this->end_infinity = FALSE;
}
range
*parse_range_string (char *str) {
range *temp_range;
double start;
double end;
char *end_str;
temp_range = (range *) malloc(sizeof(range));
/* Set defaults */
temp_range->start = 0;
temp_range->start_infinity = FALSE;
temp_range->end = 0;
temp_range->end_infinity = TRUE;
temp_range->alert_on = OUTSIDE;
if (str[0] == '@') {
temp_range->alert_on = INSIDE;
str++;
}
end_str = index(str, ':');
if (end_str != NULL) {
if (str[0] == '~') {
temp_range->start_infinity = TRUE;
} else {
start = strtod(str, NULL); /* Will stop at the ':' */
set_range_start(temp_range, start);
}
end_str++; /* Move past the ':' */
} else {
end_str = str;
}
end = strtod(end_str, NULL);
if (strcmp(end_str, "") != 0) {
set_range_end(temp_range, end);
}
if (temp_range->start_infinity == TRUE ||
temp_range->end_infinity == TRUE ||
temp_range->start <= temp_range->end) {
return temp_range;
}
free(temp_range);
return NULL;
}
/* returns 0 if okay, otherwise 1 */
int
_set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
{
thresholds *temp_thresholds = NULL;
temp_thresholds = malloc(sizeof(temp_thresholds));
temp_thresholds->warning = NULL;
temp_thresholds->critical = NULL;
if (warn_string != NULL) {
if ((temp_thresholds->warning = parse_range_string(warn_string)) == NULL) {
return 1;
}
}
if (critical_string != NULL) {
if ((temp_thresholds->critical = parse_range_string(critical_string)) == NULL) {
return 1;
}
}
if (*my_thresholds > 0) { /* Not sure why, but sometimes could be -1 */
/* printf("Freeing here: %d\n", *my_thresholds); */
free(*my_thresholds);
}
*my_thresholds = temp_thresholds;
return 0;
}
void
set_thresholds(thresholds **my_thresholds, char *warn_string, char *critical_string)
{
if (_set_thresholds(my_thresholds, warn_string, critical_string) == 0) {
return;
} else {
die(STATE_UNKNOWN, _("Range format incorrect"));
}
}
void print_thresholds(const char *threshold_name, thresholds *my_threshold) {
printf("%s - ", threshold_name);
if (! my_threshold) {
printf("Threshold not set");
} else {
if (my_threshold->warning) {
printf("Warning: start=%g end=%g; ", my_threshold->warning->start, my_threshold->warning->end);
} else {
printf("Warning not set; ");
}
if (my_threshold->critical) {
printf("Critical: start=%g end=%g", my_threshold->critical->start, my_threshold->critical->end);
} else {
printf("Critical not set");
}
}
printf("\n");
}
/* Returns TRUE if alert should be raised based on the range */
int
check_range(double value, range *my_range)
{
int false = FALSE;
int true = TRUE;
if (my_range->alert_on == INSIDE) {
false = TRUE;
true = FALSE;
}
if (my_range->end_infinity == FALSE && my_range->start_infinity == FALSE) {
if ((my_range->start <= value) && (value <= my_range->end)) {
return false;
} else {
return true;
}
} else if (my_range->start_infinity == FALSE && my_range->end_infinity == TRUE) {
if (my_range->start <= value) {
return false;
} else {
return true;
}
} else if (my_range->start_infinity == TRUE && my_range->end_infinity == FALSE) {
if (value <= my_range->end) {
return false;
} else {
return true;
}
} else {
return false;
}
}
/* Returns status */
int
get_status(double value, thresholds *my_thresholds)
{
if (my_thresholds->critical != NULL) {
if (check_range(value, my_thresholds->critical) == TRUE) {
return STATE_CRITICAL;
}
}
if (my_thresholds->warning != NULL) {
if (check_range(value, my_thresholds->warning) == TRUE) {
return STATE_WARNING;
}
}
return STATE_OK;
}
char *np_escaped_string (const char *string) {
char *data;
int i, j=0;
data = strdup(string);
for (i=0; data[i]; i++) {
if (data[i] == '\\') {
switch(data[++i]) {
case 'n':
data[j++] = '\n';
break;
case 'r':
data[j++] = '\r';
break;
case 't':
data[j++] = '\t';
break;
case '\\':
data[j++] = '\\';
break;
default:
data[j++] = data[i];
}
} else {
data[j++] = data[i];
}
}
data[j] = '\0';
return data;
}

37
lib/utils_base.h Normal file
View file

@ -0,0 +1,37 @@
/* Header file for nagios plugins utils_base.c */
/* This file holds header information for thresholds - use this in preference to
individual plugin logic */
/* This has not been merged with utils.h because of problems with
timeout_interval when other utils_*.h files use utils.h */
/* Long term, add new functions to utils_base.h for common routines
and utils_*.h for specific to plugin routines. If routines are
placed in utils_*.h, then these can be tested with libtap */
#define OUTSIDE 0
#define INSIDE 1
typedef struct range_struct {
double start;
int start_infinity; /* FALSE (default) or TRUE */
double end;
int end_infinity;
int alert_on; /* OUTSIDE (default) or INSIDE */
} range;
typedef struct thresholds_struct {
range *warning;
range *critical;
} thresholds;
range *parse_range_string (char *);
int _set_thresholds(thresholds **, char *, char *);
void set_thresholds(thresholds **, char *, char *);
int check_range(double, range *);
int get_status(double, thresholds *);
char *np_escaped_string (const char *);
void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)));

140
lib/utils_disk.c Normal file
View file

@ -0,0 +1,140 @@
/****************************************************************************
* Utils for check_disk
*
* License: GPL
* Copyright (c) 1999-2006 nagios-plugins team
*
* Last Modified: $Date$
*
* Description:
*
* This file contains utilities for check_disk. These are tested by libtap
*
* License Information:
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*
*****************************************************************************/
#include "common.h"
#include "utils_disk.h"
void
np_add_name (struct name_list **list, const char *name)
{
struct name_list *new_entry;
new_entry = (struct name_list *) malloc (sizeof *new_entry);
new_entry->name = (char *) name;
new_entry->next = *list;
*list = new_entry;
}
/* Initialises a new parameter at the end of list */
struct parameter_list *
np_add_parameter(struct parameter_list **list, const char *name)
{
struct parameter_list *current = *list;
struct parameter_list *new_path;
new_path = (struct parameter_list *) malloc (sizeof *new_path);
new_path->name = (char *) name;
new_path->best_match = NULL;
new_path->name_next = NULL;
new_path->freespace_bytes = NULL;
new_path->freespace_units = NULL;
new_path->freespace_percent = NULL;
new_path->usedspace_bytes = NULL;
new_path->usedspace_units = NULL;
new_path->usedspace_percent = NULL;
new_path->usedinodes_percent = NULL;
if (current == NULL) {
*list = new_path;
} else {
while (current->name_next) {
current = current->name_next;
}
current->name_next = new_path;
}
return new_path;
}
void
np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, int exact)
{
struct parameter_list *d;
for (d = desired; d; d= d->name_next) {
struct mount_entry *me;
size_t name_len = strlen(d->name);
size_t best_match_len = 0;
struct mount_entry *best_match = NULL;
for (me = mount_list; me; me = me->me_next) {
size_t len = strlen (me->me_mountdir);
if ((exact == FALSE && (best_match_len <= len && len <= name_len &&
(len == 1 || strncmp (me->me_mountdir, d->name, len) == 0)))
|| (exact == TRUE && strcmp(me->me_mountdir, d->name)==0))
{
best_match = me;
best_match_len = len;
} else {
len = strlen (me->me_devname);
if ((exact == FALSE && (best_match_len <= len && len <= name_len &&
(len == 1 || strncmp (me->me_devname, d->name, len) == 0)))
|| (exact == TRUE && strcmp(me->me_devname, d->name)==0))
{
best_match = me;
best_match_len = len;
}
}
}
if (best_match) {
d->best_match = best_match;
} else {
d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */
}
}
}
/* Returns TRUE if name is in list */
int
np_find_name (struct name_list *list, const char *name)
{
const struct name_list *n;
if (list == NULL || name == NULL) {
return FALSE;
}
for (n = list; n; n = n->next) {
if (!strcmp(name, n->name)) {
return TRUE;
}
}
return FALSE;
}
int
np_seen_name(struct name_list *list, const char *name)
{
const struct name_list *s;
for (s = list; s; s=s->next) {
if (!strcmp(s->name, name)) {
return TRUE;
}
}
return FALSE;
}

32
lib/utils_disk.h Normal file
View file

@ -0,0 +1,32 @@
/* Header file for utils_disk */
#include "mountlist.h"
#include "utils_base.h"
struct name_list
{
char *name;
struct name_list *next;
};
struct parameter_list
{
char *name;
int found;
thresholds *freespace_bytes;
thresholds *freespace_units;
thresholds *freespace_percent;
thresholds *usedspace_bytes;
thresholds *usedspace_units;
thresholds *usedspace_percent;
thresholds *usedinodes_percent;
struct mount_entry *best_match;
struct parameter_list *name_next;
};
void np_add_name (struct name_list **list, const char *name);
int np_find_name (struct name_list *list, const char *name);
int np_seen_name (struct name_list *list, const char *name);
struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
int search_parameter_list (struct parameter_list *list, const char *name);
void np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list, int exact);

View file

@ -49,13 +49,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
#include <stdarg.h>
#include "fsusage.h"
#include "mountlist.h"
#include "intprops.h" /* necessary for TYPE_MAXIMUM */
#if HAVE_LIMITS_H
# include <limits.h>
#endif
/* If nonzero, show inode information. */
static int inode_format;
static int inode_format = 1;
/* If nonzero, show even filesystems with zero size or
uninteresting types. */
@ -118,16 +119,11 @@ static struct mount_entry *mount_list;
int process_arguments (int, char **);
void print_path (const char *mypath);
int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
int check_disk (double usp, uintmax_t free_disk, double uisp);
void print_help (void);
void print_usage (void);
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;
@ -136,20 +132,32 @@ int verbose = 0;
int erronly = FALSE;
int display_mntp = FALSE;
int exact_match = FALSE;
char *warn_freespace_units = NULL;
char *crit_freespace_units = NULL;
char *warn_freespace_percent = NULL;
char *crit_freespace_percent = NULL;
char *warn_usedspace_units = NULL;
char *crit_usedspace_units = NULL;
char *warn_usedspace_percent = NULL;
char *crit_usedspace_percent = NULL;
char *warn_usedinodes_percent = NULL;
char *crit_usedinodes_percent = NULL;
int
main (int argc, char **argv)
{
double usp = -1.0, uisp = -1.0;
int result = STATE_UNKNOWN;
int disk_result = STATE_UNKNOWN;
char file_system[MAX_INPUT_BUFFER];
char *output;
char *details;
char *perf;
uintmax_t psize;
float free_space, free_space_pct, total_space, inode_space_pct;
float inode_space_pct;
uintmax_t total, available, available_to_root, used;
double dfree_pct = -1, dused_pct = -1;
double dused_units, dfree_units, dtotal_units;
double dused_inodes_percent;
int temp_result;
struct mount_entry *me;
struct fs_usage fsp;
@ -175,13 +183,12 @@ main (int argc, char **argv)
if (! path_select_list) {
for (me = mount_list; me; me = me->me_next) {
path = np_add_parameter(&path_select_list, me->me_mountdir);
path->w_df = w_df;
path->c_df = c_df;
path->w_dfp = w_dfp;
path->c_dfp = c_dfp;
path->w_idfp = w_idfp;
path->c_idfp = c_idfp;
path->best_match = me;
set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
}
} else {
np_set_best_match(path_select_list, mount_list, exact_match);
@ -199,12 +206,6 @@ main (int argc, char **argv)
/* Process for every path in list */
for (path = path_select_list; path; path=path->name_next) {
me = path->best_match;
w_df = path->w_df;
c_df = path->c_df;
w_dfp = path->w_dfp;
c_dfp = path->c_dfp;
w_idfp = path->w_idfp;
c_idfp = path->c_idfp;
/* Filters */
@ -233,13 +234,67 @@ main (int argc, char **argv)
get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks;
uisp = (double)(fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files;
disk_result = check_disk (usp, fsp.fsu_bavail, uisp);
total = fsp.fsu_blocks;
available = fsp.fsu_bavail;
available_to_root = fsp.fsu_bfree;
used = total - available_to_root;
/* I don't understand the below, but it is taken from coreutils' df */
/* Is setting dused_pct, in the best possible way */
if (used <= TYPE_MAXIMUM(uintmax_t) / 100) {
uintmax_t u100 = used * 100;
uintmax_t nonroot_total = used + available;
dused_pct = u100 / nonroot_total + (u100 % nonroot_total != 0);
} else {
/* Possible rounding errors - see coreutils' df for more explanation */
double u = used;
double a = available;
double nonroot_total = u + a;
if (nonroot_total) {
long int lipct = dused_pct = u * 100 / nonroot_total;
double ipct = lipct;
/* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
if (ipct - 1 < dused_pct && dused_pct <= ipct + 1)
dused_pct = ipct + (ipct < dused_pct);
}
}
dfree_pct = 100 - dused_pct;
dused_units = used*fsp.fsu_blocksize/mult;
dfree_units = available*fsp.fsu_blocksize/mult;
dtotal_units = total*fsp.fsu_blocksize/mult;
dused_inodes_percent = (fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files;
if (verbose >= 3) {
printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n",
me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
}
/* Threshold comparisons */
temp_result = get_status(dfree_units, path->freespace_units);
if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
result = max_state( result, temp_result );
temp_result = get_status(dfree_pct, path->freespace_percent);
if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
result = max_state( result, temp_result );
temp_result = get_status(dused_units, path->usedspace_units);
if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
result = max_state( result, temp_result );
temp_result = get_status(dused_pct, path->usedspace_percent);
if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
result = max_state( result, temp_result );
temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
result = max_state( result, temp_result );
result = max_state (disk_result, result);
psize = fsp.fsu_blocks*fsp.fsu_blocksize/mult;
/* Moved this computation up here so we can add it
@ -248,33 +303,33 @@ main (int argc, char **argv)
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, inode_space_pct,
perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
dused_units, units,
FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*dtotal_units)), */
FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*dtotal_units)), */
FALSE, 0, /* inode_space_pct, */
FALSE, 0));; /* dtotal_units)); */
TRUE, psize));
if (disk_result==STATE_OK && erronly && !verbose)
continue;
free_space = (float)fsp.fsu_bavail*fsp.fsu_blocksize/mult;
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)
if (disk_result!=STATE_OK || verbose>=0) {
asprintf (&output, ("%s %s %.0f %s (%.0f%% inode=%.0f%%);"),
output,
(!strcmp(file_system, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
free_space,
(!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
dfree_units,
units,
free_space_pct,
dfree_pct,
inode_space_pct);
}
/* Need to do a similar one
asprintf (&details, _("%s\n\
%.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,
details, dfree_units, dtotal_units, units, dfree_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);
*/
}
@ -299,14 +354,6 @@ process_arguments (int argc, char **argv)
struct parameter_list *temp_list;
int result = OK;
struct stat *stat_buf;
char *warn_freespace = NULL;
char *crit_freespace = NULL;
char *warn_freespace_percent = NULL;
char *crit_freespace_percent = NULL;
char temp_string[MAX_INPUT_BUFFER];
unsigned long l;
double f;
int option = 0;
static struct option longopts[] = {
@ -359,65 +406,51 @@ process_arguments (int argc, char **argv)
else {
usage2 (_("Timeout interval must be a positive integer"), optarg);
}
/* See comments for 'c' */
case 'w': /* warning threshold */
/*
if (strstr(optarg, "%")) {
printf("Got percent with optarg=%s\n", optarg);
warn_freespace_percent = optarg;
if (*optarg == '@') {
warn_freespace_percent = optarg;
} else {
asprintf(&warn_freespace_percent, "@%s", optarg);
}
} else {
warn_freespace = optarg;
if (*optarg == '@') {
warn_freespace_units = optarg;
} else {
asprintf(&warn_freespace_units, "@%s", optarg);
}
}
break;
*/
if (is_intnonneg (optarg)) {
w_df = atoi (optarg);
break;
}
else if (strpbrk (optarg, ",:") &&
strstr (optarg, "%") &&
sscanf (optarg, "%lu%*[:,]%lf%%", &l, &w_dfp) == 2) {
w_df = (uintmax_t)l;
break;
}
else if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &w_dfp) == 1) {
break;
}
else {
usage4 (_("Warning threshold must be integer or percentage!"));
}
/* Awful mistake where the range values do not make sense. Normally,
you alert if the value is within the range, but since we are using
freespace, we have to alert if outside the range. Thus we artifically
force @ at the beginning of the range, so that it is backwards compatible
*/
case 'c': /* critical threshold */
if (is_intnonneg (optarg)) {
c_df = atoi (optarg);
break;
}
else if (strpbrk (optarg, ",:") &&
strstr (optarg, "%") &&
sscanf (optarg, "%lu%*[,:]%lf%%", &l, &c_dfp) == 2) {
c_df = (uintmax_t)l;
break;
}
else if (strstr (optarg, "%") && sscanf (optarg, "%lf%%", &c_dfp) == 1) {
break;
}
else {
usage4 (_("Critical threshold must be integer or percentage!"));
if (strstr(optarg, "%")) {
if (*optarg == '@') {
crit_freespace_percent = optarg;
} else {
asprintf(&crit_freespace_percent, "@%s", optarg);
}
} else {
if (*optarg == '@') {
crit_freespace_units = optarg;
} else {
asprintf(&crit_freespace_units, "@%s", optarg);
}
}
break;
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 'W': /* warning inode threshold */
warn_usedinodes_percent = optarg;
break;
case 'K': /* critical inode threshold */
crit_usedinodes_percent = optarg;
break;
case 'u':
if (units)
free(units);
@ -458,13 +491,18 @@ process_arguments (int argc, char **argv)
show_local_fs = 1;
break;
case 'p': /* select path */
if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
crit_usedinodes_percent)) {
die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
}
se = np_add_parameter(&path_select_list, optarg);
se->w_df = w_df;
se->c_df = c_df;
se->w_dfp = w_dfp;
se->c_dfp = c_dfp;
se->w_idfp = w_idfp;
se->c_idfp = c_idfp;
set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
break;
case 'x': /* exclude path or partition */
np_add_name(&dp_exclude_list, optarg);
@ -488,12 +526,16 @@ process_arguments (int argc, char **argv)
display_mntp = TRUE;
break;
case 'C':
w_df = 0;
c_df = 0;
w_dfp = -1.0;
c_dfp = -1.0;
w_idfp = -1.0;
c_idfp = -1.0;
warn_freespace_units = NULL;
crit_freespace_units = NULL;
warn_usedspace_units = NULL;
crit_usedspace_units = NULL;
warn_freespace_percent = NULL;
crit_freespace_percent = NULL;
warn_usedspace_percent = NULL;
crit_usedspace_percent = NULL;
warn_usedinodes_percent = NULL;
crit_usedinodes_percent = NULL;
break;
case 'V': /* version */
print_revision (progname, revision);
@ -506,22 +548,26 @@ process_arguments (int argc, char **argv)
}
}
/* Support for "check_disk warn crit [fs]" with thresholds at used level */
/* Support for "check_disk warn crit [fs]" with thresholds at used% level */
c = optind;
if (w_dfp < 0 && argc > c && is_intnonneg (argv[c]))
w_dfp = (100.0 - atof (argv[c++]));
if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
warn_usedspace_percent = argv[c++];
if (c_dfp < 0 && argc > c && is_intnonneg (argv[c]))
c_dfp = (100.0 - atof (argv[c++]));
if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
crit_usedspace_percent = argv[c++];
if (argc > c && path == NULL) {
se = np_add_parameter(&path_select_list, strdup(argv[c++]));
se->w_df = w_df;
se->c_df = c_df;
se->w_dfp = w_dfp;
se->c_dfp = c_dfp;
se->w_idfp = w_idfp;
se->c_idfp = c_idfp;
set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
}
if (units == NULL) {
units = strdup ("MB");
mult = (uintmax_t)1024 * 1024;
}
if (path_select_list) {
@ -533,7 +579,7 @@ process_arguments (int argc, char **argv)
printf("DISK %s - ", _("CRITICAL"));
die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
}
if (validate_arguments (temp_list->w_df,
/* if (validate_arguments (temp_list->w_df,
temp_list->c_df,
temp_list->w_dfp,
temp_list->c_dfp,
@ -541,12 +587,14 @@ process_arguments (int argc, char **argv)
temp_list->c_idfp,
temp_list->name) == ERROR)
result = ERROR;
*/
temp_list = temp_list->name_next;
}
free(stat_buf);
return result;
} else {
return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL);
return TRUE;
/* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
}
}
@ -560,11 +608,13 @@ print_path (const char *mypath)
else
printf (_(" for %s\n"), mypath);
return;
//return;
}
/* TODO: Remove?
int
validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
{
@ -597,37 +647,12 @@ INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greate
return ERROR;
}
if (units == NULL) {
units = strdup ("MB");
mult = (uintmax_t)1024 * 1024;
}
return OK;
}
*/
int
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 (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;
}

View file

@ -52,8 +52,8 @@ if ($free_on_mp1 > $free_on_mp2) {
}
$result = NPTest->testCmd( "./check_disk -w 100 -c 100 -p $more_free" );
cmp_ok( $result->return_code, '==', 0, "At least 100 bytes available on $more_free");
$result = NPTest->testCmd( "./check_disk -w 1 -c 1 -p $more_free" );
cmp_ok( $result->return_code, '==', 0, "At least 1 MB available on $more_free");
like ( $result->output, $successOutput, "OK output" );
$result = NPTest->testCmd( "./check_disk 100 100 $more_free" );
@ -110,35 +110,28 @@ cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make
$result = NPTest->testCmd(
"./check_disk -w 10% -c 15% -p $mountpoint_valid"
);
cmp_ok( $result->return_code, '==', 3, "Invalid command line options" );
TODO: {
local $TODO = "-p must come after -w and -c";
$result = NPTest->testCmd(
local $TODO = "Invalid percent figures";
$result = NPTest->testCmd(
"./check_disk -w 10% -c 15% -p $mountpoint_valid"
);
cmp_ok( $result->return_code, '==', 3, "Invalid command line options" );
}
$result = NPTest->testCmd(
"./check_disk -p $mountpoint_valid -w 10% -c 15%"
);
cmp_ok( $result->return_code, "==", 3, "Invalid options - order unimportant" );
}
cmp_ok( $result->return_code, "==", 3, "Invalid options: -p must come after thresholds" );
$result = NPTest->testCmd( "./check_disk -w 100% -c 100% ".${mountpoint_valid} ); # 100% empty
cmp_ok( $result->return_code, "==", 2, "100% empty" );
like( $result->output, $failureOutput, "Right output" );
TODO: {
local $TODO = "Requesting 100GB free is should be critical";
$result = NPTest->testCmd( "./check_disk -w 100000 -c 100000 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 2, "Check for 100GB free" );
}
$result = NPTest->testCmd( "./check_disk -w 100000 -c 100000 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 2, "Check for 100GB free" );
TODO: {
local $TODO = "-u GB does not work";
$result = NPTest->testCmd( "./check_disk -w 100 -c 100 -u GB ".${mountpoint_valid} ); # 100 GB empty
cmp_ok( $result->return_code, "==", 2, "100 GB empty" );
}
$result = NPTest->testCmd( "./check_disk -w 100 -c 100 -u GB ".${mountpoint_valid} ); # 100 GB empty
cmp_ok( $result->return_code, "==", 2, "100 GB empty" );
# Checking old syntax of check_disk warn crit [fs], with warn/crit at USED% thresholds
@ -151,17 +144,17 @@ cmp_ok( $result->return_code, '==', 0, "Old syntax: 100% used" );
$result = NPTest->testCmd( "./check_disk 0 100 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 1, "Old syntax: warn 0% used" );
$result = NPTest->testCmd( "./check_disk 0 200 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 3, "Old syntax: Error with values outside percent range" );
TODO: {
local $TODO = "Need to properly check input";
local $TODO = "Invalid values";
$result = NPTest->testCmd( "./check_disk 0 200 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 3, "Old syntax: Error with values outside percent range" );
$result = NPTest->testCmd( "./check_disk 200 200 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 3, "Old syntax: Error with values outside percent range" );
}
$result = NPTest->testCmd( "./check_disk 200 0 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 3, "Old syntax: Error with values outside percent range" );
$result = NPTest->testCmd( "./check_disk 200 0 $mountpoint_valid" );
cmp_ok( $result->return_code, '==', 3, "Old syntax: Error with values outside percent range" );
}
$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /bob" );
cmp_ok( $result->return_code, '==', 2, "Checking /bob - return error because /bob does not exist" );