diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 7bd044adf6dc046fe2dd460164bbd3ed3cb9abba..845c74585ebcb3fff03a99ccf9de6e1e71a85493 100644 (file)
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
#if HAVE_LIMITS_H
# include <limits.h>
#endif
+#include "regex.h"
/* If nonzero, show inode information. */
char *warn_freeinodes_percent = NULL;
char *crit_freeinodes_percent = NULL;
bool path_selected = false;
+char *group = NULL;
int
int temp_result;
struct mount_entry *me;
- struct fs_usage fsp;
+ struct fs_usage fsp, tmpfsp;
struct parameter_list *temp_list, *path;
struct name_list *seen = NULL;
+ struct stat *stat_buf;
preamble = strdup (" - free space:");
output = strdup ("");
path = np_add_parameter(&path_select_list, me->me_mountdir);
}
path->best_match = me;
+ path->group = group;
set_all_thresholds(path);
}
}
/* Error if no match found for specified paths */
temp_list = path_select_list;
+
+ stat_buf = malloc(sizeof *stat_buf);
while (temp_list) {
if (! temp_list->best_match) {
die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
}
+
+ /* Stat each entry to check that dir exists */
+ if (stat (temp_list->name, &stat_buf[0])) {
+ printf("DISK %s - ", _("CRITICAL"));
+ die (STATE_CRITICAL, _("%s %s: %s\n"), temp_list->name, _("is not accessible"), strerror(errno));
+ }
temp_list = temp_list->name_next;
}
+ free(stat_buf);
-
/* Process for every path in list */
for (path = path_select_list; path; path=path->name_next) {
printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end,
path->freespace_percent->critical->end);
+ if (verbose > 3 && path->group != NULL)
+ printf("Group of %s: %s\n",path->name,path->group);
+
/* reset disk result */
disk_result = STATE_UNKNOWN;
if (np_seen_name(seen, me->me_mountdir)) {
continue;
} else {
- np_add_name(&seen, me->me_mountdir);
- }
- /* Skip remote filesystems if we're not interested in them */
- if (me->me_remote && show_local_fs) {
- continue;
- /* Skip pseudo fs's if we haven't asked for all fs's */
- } else if (me->me_dummy && !show_all_fs) {
- continue;
- /* Skip excluded fstypes */
- } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
- continue;
- /* Skip excluded fs's */
- } else if (dp_exclude_list &&
- (np_find_name (dp_exclude_list, me->me_devname) ||
- np_find_name (dp_exclude_list, me->me_mountdir))) {
- continue;
+ if (path->group != NULL) {
+ /* find all group members */
+ fsp.fsu_blocksize = 0;
+ fsp.fsu_blocks = 0;
+ fsp.fsu_bfree = 0;
+ fsp.fsu_bavail = 0;
+ fsp.fsu_files = 0;
+ fsp.fsu_ffree = 0;
+
+
+ for (temp_list = path_select_list; temp_list; temp_list=temp_list->name_next) {
+ if (temp_list->group && ! (strcmp(temp_list->group, path->group))) {
+
+ get_fs_usage (temp_list->best_match->me_mountdir, temp_list->best_match->me_devname, &tmpfsp);
+
+ /* possibly differing blocksizes if disks are grouped. Calculating average */
+ fsp.fsu_blocksize = (fsp.fsu_blocksize * fsp.fsu_blocks + tmpfsp.fsu_blocksize * tmpfsp.fsu_blocks) / \
+ (fsp.fsu_blocks + tmpfsp.fsu_blocks); /* Size of a block. */
+ fsp.fsu_blocks += tmpfsp.fsu_blocks; /* Total blocks. */
+ fsp.fsu_bfree += tmpfsp.fsu_bfree; /* Free blocks available to superuser. */
+ fsp.fsu_bavail += tmpfsp.fsu_bavail; /* Free blocks available to non-superuser. */
+ fsp.fsu_files += tmpfsp.fsu_files; /* Total file nodes. */
+ fsp.fsu_ffree += tmpfsp.fsu_ffree; /* Free file nodes. */
+
+ if (verbose > 3)
+ printf("Group %s: add %llu blocks (%s) \n", path->group, tmpfsp.fsu_bavail, temp_list->name);
+ // printf("Group %s: add %u blocks (%s)\n", temp_list->name); // path->group, tmpfsp.fsu_bavail, temp_list->name);
+
+ np_add_name(&seen, temp_list->best_match->me_mountdir);
+ }
+ }
+ /* modify devname and mountdir for output */
+ me->me_mountdir = me->me_devname = path->group;
+ } else
+ np_add_name(&seen, me->me_mountdir);
}
- get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
+ if (path->group == NULL) {
+ /* Skip remote filesystems if we're not interested in them */
+ if (me->me_remote && show_local_fs) {
+ continue;
+ /* Skip pseudo fs's if we haven't asked for all fs's */
+ } else if (me->me_dummy && !show_all_fs) {
+ continue;
+ /* Skip excluded fstypes */
+ } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
+ continue;
+ /* Skip excluded fs's */
+ } else if (dp_exclude_list &&
+ (np_find_name (dp_exclude_list, me->me_devname) ||
+ np_find_name (dp_exclude_list, me->me_mountdir))) {
+ continue;
+ }
+
+ get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
+ }
if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
total = fsp.fsu_blocks;
int
process_arguments (int argc, char **argv)
{
- int c;
- struct parameter_list *se;
+ int c, err;
+ struct parameter_list *se, *se2;
struct parameter_list *temp_list;
+ struct parameter_list *temp_path_select_list = NULL;
+ struct mount_entry *me;
int result = OK;
- struct stat *stat_buf;
+ regex_t re;
+ int cflags = REG_NOSUB | REG_EXTENDED;
+ char errbuf[MAX_INPUT_BUFFER];
+ bool fnd = false;
int option = 0;
static struct option longopts[] = {
{"partition", required_argument, 0, 'p'},
{"exclude_device", required_argument, 0, 'x'},
{"exclude-type", required_argument, 0, 'X'},
+ {"group", required_argument, 0, 'g'},
+ {"eregi-path", required_argument, 0, 'R'},
+ {"eregi-partition", required_argument, 0, 'R'},
+ {"ereg-path", required_argument, 0, 'r'},
+ {"ereg-partition", required_argument, 0, 'r'},
{"mountpoint", no_argument, 0, 'M'},
{"errors-only", no_argument, 0, 'e'},
{"exact-match", no_argument, 0, 'E'},
strcpy (argv[c], "-t");
while (1) {
- c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
+ c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklg:R:r:ME", longopts, &option);
if (c == -1 || c == EOF)
break;
die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
}
+ /* get the real mountdir of the specified path. np_find_parameter won't find an entry if -p is not
+ * exactly the same string as the mountdir */
+ se2 = np_add_parameter(&temp_path_select_list, optarg);
+ np_set_best_match(se2, mount_list, FALSE);
+
+
/* add parameter if not found. overwrite thresholds if path has already been added */
if (! (se = np_find_parameter(path_select_list, optarg))) {
se = np_add_parameter(&path_select_list, optarg);
}
-
+ se->group = group;
set_all_thresholds(se);
path_selected = true;
break;
case 'E':
exact_match = TRUE;
break;
+ case 'g':
+ if (path_selected)
+ die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before using -p\n"));
+ group = optarg;
+ break;
+ case 'R':
+ cflags |= REG_ICASE;
+ case 'r':
+ 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 || warn_freeinodes_percent || crit_freeinodes_percent )) {
+ die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R\n"));
+ }
+
+ err = regcomp(&re, optarg, cflags);
+ if (err != 0) {
+ regerror (err, &re, errbuf, MAX_INPUT_BUFFER);
+ die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), _("Could not compile regular expression"), errbuf);
+ }
+
+ for (me = mount_list; me; me = me->me_next) {
+ if (np_regex_match_mount_entry(me, &re)) {
+ fnd = true;
+ if (verbose > 3)
+ printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg);
+
+ /* add parameter if not found. overwrite thresholds if path has already been added */
+ if (! (se = np_find_parameter(path_select_list, me->me_mountdir))) {
+ se = np_add_parameter(&path_select_list, me->me_mountdir);
+ }
+ se->group = group;
+ set_all_thresholds(se);
+ }
+ }
+
+ if (!fnd)
+ die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
+ _("Regular expression did not match any path or disk"), optarg);
+
+ fnd = false;
+ path_selected = true;
+ break;
case 'M': /* display mountpoint */
display_mntp = TRUE;
break;
if (! (path = np_find_parameter(path_select_list, me->me_mountdir)))
path = np_add_parameter(&path_select_list, me->me_mountdir);
path->best_match = me;
+ path->group = group;
set_all_thresholds(path);
}
}
crit_freeinodes_percent = NULL;
path_selected = false;
+ group = NULL;
break;
case 'V': /* version */
print_revision (progname, revision);
if (argc > c && path == NULL) {
se = np_add_parameter(&path_select_list, strdup(argv[c++]));
+ path_selected = true;
set_all_thresholds(se);
}
mult = (uintmax_t)1024 * 1024;
}
- if (path_select_list) {
- temp_list = path_select_list;
- stat_buf = malloc(sizeof *stat_buf);
- while (temp_list) {
- /* Stat each entry to check that dir exists */
- if (stat (temp_list->name, &stat_buf[0])) {
- printf("DISK %s - ", _("CRITICAL"));
- die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
- }
- /* if (validate_arguments (temp_list->w_df,
- 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;
- }
- free(stat_buf);
- return result;
- } else {
- return TRUE;
- /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
- }
+ return TRUE;
}
printf (" %s\n", _("Only check local filesystems"));
printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
printf (" %s\n", _("Path or partition (may be repeated)"));
+ printf (" %s\n", "-r, --ereg-path=PATH, --ereg-partition=PARTITION");
+ printf (" %s\n", _("Regular expression for path or partition (may be repeated)"));
+ printf (" %s\n", "-R, --eregi-path=PATH, --eregi-partition=PARTITION");
+ printf (" %s\n", _("Case insensitive regular expression for path/partition (may be repeated)"));
+ printf (" %s\n", "-g, --group=NAME");
+ printf (" %s\n", _("Group pathes. Thresholds apply to (free-)space of all partitions together"));
printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
printf (" %s\n", _("Ignore device (only works if -p unspecified)"));
printf (" %s\n", "-X, --exclude-type=TYPE <STRING>");
printf ("%s\n", _("Examples:"));
printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
+ printf (" %s\n", "check_disk -w 100M -c 50M -C -w 1000M -c 500M -g sidDATA -r '^/oracle/SID/data.*$'");
+ printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex"));
+ printf (" %s\n", _("are grouped which means the freespace thresholds are applied to all disks together"));
+ printf (" %s\n", "check_disk -w 100M -c 50M -C -w 1000M -c 500M -p /foo -C -w 5% -c 3% -p /bar");
+ printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M"));
printf (_(UT_SUPPORT));
}