From a46e358d68027289cffaffeb7a4b32ababb2105b Mon Sep 17 00:00:00 2001 From: Ton Voon Date: Wed, 12 Jul 2006 22:53:27 +0000 Subject: Added -E option for exact match of filesystem. Restructured main filesystem loop. Added extra tests for possible duplicate filesystems. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1449 f882894a-f735-0410-b71e-b25c423dba1c diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 8e9c1fc..1423448 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -119,7 +119,6 @@ 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); -int walk_parameter_list (struct parameter_list *list, const char *name); void print_help (void); void print_usage (void); @@ -136,7 +135,7 @@ uintmax_t mult = 1024 * 1024; int verbose = 0; int erronly = FALSE; int display_mntp = FALSE; - +int exact_match = FALSE; int @@ -154,7 +153,8 @@ main (int argc, char **argv) struct mount_entry *me; struct fs_usage fsp; - struct parameter_list *temp_list; + struct parameter_list *temp_list, *path; + struct name_list *seen = NULL; output = strdup (" - free space:"); details = strdup (""); @@ -169,57 +169,69 @@ main (int argc, char **argv) if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); - /* if a list of paths has been selected, preseed the list with - * the longest matching filesystem name by iterating across - * the mountlist once ahead of time. this will allow a query on - * "/var/log" to return information about "/var" if no "/var/log" - * filesystem exists, etc. this is the default behavior already - * with df-based checks, but for systems with their own space - * checking routines, this should make them more consistent. + /* If a list of paths has not been selected, find entire + mount list and create list of paths */ - if(path_select_list){ + if (! path_select_list) { for (me = mount_list; me; me = me->me_next) { - walk_parameter_list(path_select_list, me->me_mountdir); - walk_parameter_list(path_select_list, me->me_devname); + 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; } - /* now pretend we never saw anything, but keep found_len. - * thus future searches will only match the best match */ - for (temp_list = path_select_list; temp_list; temp_list=temp_list->name_next){ - temp_list->found=0; + } else { + np_set_best_match(path_select_list, mount_list, exact_match); + + /* Error if no match found for specified paths */ + temp_list = path_select_list; + while (temp_list) { + if (! temp_list->best_match) { + die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name); + } + temp_list = temp_list->name_next; } } - /* for every mount entry */ - for (me = mount_list; me; me = me->me_next) { - /* if there's a list of paths to select, the current mount - * entry matches in path or device name, get fs usage */ - if (path_select_list && - (walk_parameter_list (path_select_list, me->me_mountdir) || - walk_parameter_list (path_select_list, me->me_devname) ) ) { - get_fs_usage (me->me_mountdir, me->me_devname, &fsp); - /* else if there's a list of paths/devices to select (but - * we didn't match above) skip to the next mount entry */ - } else if (path_select_list) { + /* 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 */ + + /* Remove filesystems already seen */ + if (np_seen_name(seen, me->me_mountdir)) { continue; - /* skip remote filesystems if we're not interested in them */ - } else if (me->me_remote && show_local_fs) { + } 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 */ + /* 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 */ + /* Skip excluded fstypes */ } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) { continue; - /* skip excluded fs's */ + /* 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; - /* otherwise, get fs usage */ - } else { - get_fs_usage (me->me_mountdir, me->me_devname, &fsp); } + 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; @@ -271,15 +283,6 @@ main (int argc, char **argv) if (verbose > 2) asprintf (&output, "%s%s", output, details); - /* Override result if paths specified and not found */ - temp_list = path_select_list; - while (temp_list) { - if (!temp_list->found) { - asprintf (&output, _("%s [%s not found]"), output, temp_list->name); - result = STATE_CRITICAL; - } - temp_list = temp_list->name_next; - } printf ("DISK %s%s|%s\n", state_text (result), output, perf); return result; @@ -318,6 +321,7 @@ process_arguments (int argc, char **argv) {"exclude-type", required_argument, 0, 'X'}, {"mountpoint", no_argument, 0, 'M'}, {"errors-only", no_argument, 0, 'e'}, + {"exact-match", no_argument, 0, 'E'}, {"verbose", no_argument, 0, 'v'}, {"quiet", no_argument, 0, 'q'}, {"clear", no_argument, 0, 'C'}, @@ -336,7 +340,7 @@ process_arguments (int argc, char **argv) strcpy (argv[c], "-t"); while (1) { - c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklM", longopts, &option); + c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option); if (c == -1 || c == EOF) break; @@ -469,6 +473,9 @@ process_arguments (int argc, char **argv) case 'e': erronly = TRUE; break; + case 'E': + exact_match = TRUE; + break; case 'M': /* display mountpoint */ display_mntp = TRUE; break; @@ -621,30 +628,6 @@ check_disk (double usp, uintmax_t free_disk, double uisp) -int -walk_parameter_list (struct parameter_list *list, const char *name) -{ - int name_len; - name_len = strlen(name); - while (list) { - /* if the paths match up to the length of the mount path, - * AND if the mount path name is longer than the longest - * found match, we have a new winner */ - if (name_len >= list->found_len && - ! strncmp(list->name, name, name_len)) { - list->found = 1; - list->found_len = name_len; - /* if required for parameter_lists that have not saved w_df, etc (eg exclude lists) */ - if (list->w_df) w_df = list->w_df; - if (list->c_df) c_df = list->c_df; - if (list->w_dfp>=0.0) w_dfp = list->w_dfp; - if (list->c_dfp>=0.0) c_dfp = list->c_dfp; - return TRUE; - } - list = list->name_next; - } - return FALSE; -} @@ -695,6 +678,8 @@ print_help (void) printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); printf (" %s\n", "-m, --mountpoint"); printf (" %s\n", _("Display the mountpoint instead of the partition")); + printf (" %s\n", "-E, --exact-match"); + printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths")); printf (" %s\n", "-e, --errors-only"); printf (" %s\n", _("Display only devices/mountpoints with errors")); printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); @@ -713,5 +698,5 @@ print_usage (void) { printf (_("Usage:")); printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname); - printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q]\n"); + printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n"); } diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 14bc8de..70d8415 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -22,7 +22,7 @@ my $mountpoint2_valid = getTestParameter( "NP_MOUNTPOINT2_VALID", "Path to anoth if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { plan skip_all => "Need 2 mountpoints to test"; } else { - plan tests => 32; + plan tests => 35; } $result = NPTest->testCmd( @@ -103,6 +103,12 @@ $result = NPTest->testCmd( ); cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); +$result = NPTest->testCmd( + "./check_disk -w $avg_free% -c $avg_free% -p $less_free -w $avg_free% -c 0% -p $more_free" + ); +cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); + + $result = NPTest->testCmd( @@ -168,6 +174,12 @@ $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /etc" ); cmp_ok( $result->return_code, '==', 0, "Checking /etc - should return info for /" ); cmp_ok( $result->output, 'eq', $root_output, "check_disk /etc gives same as check_disk /"); +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /etc -E" ); +cmp_ok( $result->return_code, '==', 2, "... unless -E/--exact-match is specified"); + $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /bob" ); cmp_ok( $result->return_code, '==', 2, "Checking / and /bob gives critical"); unlike( $result->perf_output, '/\/bob/', "perf data does not have /bob in it"); + +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /" ); +unlike( $result->output, '/ \/ .* \/ /', "Should not show same filesystem twice"); diff --git a/plugins/utils_disk.c b/plugins/utils_disk.c index 0a71d79..31284d5 100644 --- a/plugins/utils_disk.c +++ b/plugins/utils_disk.c @@ -43,9 +43,11 @@ np_add_name (struct name_list **list, const char *name) *list = new_entry; } -void +/* 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; @@ -57,8 +59,17 @@ np_add_parameter(struct parameter_list **list, const char *name) new_path->c_dfp = -1.0; new_path->w_idfp = -1.0; new_path->c_idfp = -1.0; - new_path->name_next = *list; - *list = new_path; + new_path->best_match = 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 @@ -93,6 +104,8 @@ np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list if (best_match) { d->best_match = best_match; d->found = TRUE; + } else { + d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ } } } @@ -114,3 +127,15 @@ np_find_name (struct name_list *list, const char *name) 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; +} + diff --git a/plugins/utils_disk.h b/plugins/utils_disk.h index c1919fe..676ca09 100644 --- a/plugins/utils_disk.h +++ b/plugins/utils_disk.h @@ -25,5 +25,6 @@ struct parameter_list void np_add_name (struct name_list **list, const char *name); int np_find_name (struct name_list *list, const char *name); -void np_add_parameter(struct parameter_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); -- cgit v0.10-9-g596f