From d23b17e6567d8eb983956b36b31a383f3cc639d2 Mon Sep 17 00:00:00 2001 From: Matthias Eble Date: Sat, 22 Sep 2007 17:40:35 +0000 Subject: [PATCH] Added -i/-I to ignore pathes/partitions based on regular expressions Added check_disk -A selecting all filesystems -E option must now be passed before -p or -r/-R Passing -E after -p or -r results in UNKNOWN state Fixed bug when mixing case sensitive and insensitive regexes git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1786 f882894a-f735-0410-b71e-b25c423dba1c --- NEWS | 6 ++++ lib/tests/test_disk.c | 45 +++++++++++++++++++++-- lib/utils_disk.c | 21 +++++++++++ lib/utils_disk.h | 2 ++ plugins/check_disk.c | 81 ++++++++++++++++++++++++++++++++++-------- plugins/t/check_disk.t | 31 ++++++++++++++-- 6 files changed, 168 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index 7572b59..2ef3915 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,12 @@ This file documents the major additions and syntax changes between releases. - stop evaluating command line options through shell twice - enforce a full path for the command to run The "negate" utility can now remap custom states + New check_disk -i/-I option to ignore pathes/partitions based on regular expressions + New check_disk -A option to select all filesystems explicitly + WARNING: check_disk's -E option must now be passed before -p or -r/-R arguments + Passing -E after -p or -r results in UNKNOWN state, now + This is needed due to the new ignore feature + Fix bug when mixing case sensitive and case insensitive regex arguments 1.4.9 4th June 2006 Inclusion of contrib/check_cluster2 as check_cluster with some improvements diff --git a/lib/tests/test_disk.c b/lib/tests/test_disk.c index ac9db00..fcde4f8 100644 --- a/lib/tests/test_disk.c +++ b/lib/tests/test_disk.c @@ -36,14 +36,15 @@ main (int argc, char **argv) struct name_list *dummy_mountlist = NULL; struct name_list *temp_name; struct parameter_list *paths = NULL; - struct parameter_list *p; + struct parameter_list *p, *prev, *last; struct mount_entry *dummy_mount_list; struct mount_entry *me; struct mount_entry **mtail = &dummy_mount_list; int cflags = REG_NOSUB | REG_EXTENDED; + int found = 0, count = 0; - plan_tests(29); + plan_tests(33); ok( np_find_name(exclude_filesystem, "/var/log") == FALSE, "/var/log not in list"); np_add_name(&exclude_filesystem, "/var/log"); @@ -160,6 +161,46 @@ main (int argc, char **argv) } } + /* test deleting first element in paths */ + paths = np_del_parameter(paths, NULL); + for (p = paths; p; p = p->name_next) { + if (! strcmp(p->name, "/home/groups")) + found = 1; + } + ok(found == 0, "first element successfully deleted"); + found = 0; + + p=paths; + while (p) { + if (! strcmp(p->name, "/tmp")) + p = np_del_parameter(p, prev); + else { + prev = p; + p = p->name_next; + } + } + + for (p = paths; p; p = p->name_next) { + if (! strcmp(p->name, "/tmp")) + found = 1; + if (p->name_next) + prev = p; + else + last = p; + } + ok(found == 0, "/tmp element successfully deleted"); + + p = np_del_parameter(last, prev); + for (p = paths; p; p = p->name_next) { + if (! strcmp(p->name, "/home")) + found = 1; + last = p; + count++; + } + ok(found == 0, "last (/home) element successfully deleted"); + ok(count == 2, "two elements remaining"); + + return exit_status(); } diff --git a/lib/utils_disk.c b/lib/utils_disk.c index 96f5a30..3f9c8a9 100644 --- a/lib/utils_disk.c +++ b/lib/utils_disk.c @@ -74,6 +74,26 @@ np_add_parameter(struct parameter_list **list, const char *name) return new_path; } +/* Delete a given parameter from list and return pointer to next element*/ +struct parameter_list * +np_del_parameter(struct parameter_list *item, struct parameter_list *prev) +{ + struct parameter_list *next; + if (item->name_next) + next = item->name_next; + else + next = NULL; + + + free(item); + if (prev) + prev->name_next = next; + + return next; + +} + + /* returns a pointer to the struct found in the list */ struct parameter_list * np_find_parameter(struct parameter_list *list, const char *name) @@ -166,3 +186,4 @@ np_regex_match_mount_entry (struct mount_entry* me, regex_t* re) return false; } } + diff --git a/lib/utils_disk.h b/lib/utils_disk.h index 6263339..f99b905 100644 --- a/lib/utils_disk.h +++ b/lib/utils_disk.h @@ -31,6 +31,8 @@ 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); struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); +struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); + 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); int np_regex_match_mount_entry (struct mount_entry* me, regex_t* re); diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 90b2248..d267409 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -447,15 +447,16 @@ int process_arguments (int argc, char **argv) { int c, err; - struct parameter_list *se, *se2; - struct parameter_list *temp_list; + struct parameter_list *se; + struct parameter_list *temp_list = NULL, *previous = NULL; struct parameter_list *temp_path_select_list = NULL; - struct mount_entry *me; + struct mount_entry *me, *temp_me; int result = OK; regex_t re; int cflags = REG_NOSUB | REG_EXTENDED; + int default_cflags = cflags; char errbuf[MAX_INPUT_BUFFER]; - bool fnd = false; + int fnd = 0; int option = 0; static struct option longopts[] = { @@ -478,9 +479,14 @@ process_arguments (int argc, char **argv) {"eregi-partition", required_argument, 0, 'R'}, {"ereg-path", required_argument, 0, 'r'}, {"ereg-partition", required_argument, 0, 'r'}, + {"ignore-ereg-path", required_argument, 0, 'i'}, + {"ignore-ereg-partition", required_argument, 0, 'i'}, + {"ignore-eregi-path", required_argument, 0, 'I'}, + {"ignore-eregi-partition", required_argument, 0, 'I'}, {"mountpoint", no_argument, 0, 'M'}, {"errors-only", no_argument, 0, 'e'}, {"exact-match", no_argument, 0, 'E'}, + {"all", no_argument, 0, 'A'}, {"verbose", no_argument, 0, 'v'}, {"quiet", no_argument, 0, 'q'}, {"clear", no_argument, 0, 'C'}, @@ -499,7 +505,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:mklg:R:r:ME", longopts, &option); + c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklg:R:r:i:I:MEA", longopts, &option); if (c == -1 || c == EOF) break; @@ -613,18 +619,13 @@ process_arguments (int argc, char **argv) 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); + np_set_best_match(se, mount_list, exact_match); path_selected = true; break; case 'x': /* exclude path or partition */ @@ -644,13 +645,56 @@ process_arguments (int argc, char **argv) erronly = TRUE; break; case 'E': + if (path_selected) + die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set -E before selecting pathes\n")); exact_match = TRUE; break; case 'g': if (path_selected) - die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before using -p\n")); + die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set group value before selecting pathes \n")); group = optarg; break; + case 'I': + cflags |= REG_ICASE; + case 'i': + if (!path_selected) + die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Pathes need to be selected before using -i/-I. Use -A to select all pathes explicitly")); + 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); + } + + temp_list = path_select_list; + + previous = NULL; + while (temp_list) { + if (temp_list->best_match) { + if (np_regex_match_mount_entry(temp_list->best_match, &re)) { + + if (verbose >=3) + printf("ignoring %s matching regex\n", temp_list->name); + + temp_list = np_del_parameter(temp_list, previous); + /* pointer to first element needs to be uüdated if first item gets deleted */ + if (previous == NULL) + path_select_list = temp_list; + } else { + previous = temp_list; + temp_list = temp_list->name_next; + } + } else { + previous = temp_list; + temp_list = temp_list->name_next; + } + } + + + cflags = default_cflags; + break; + + case 'A': + optarg = strdup(".*"); case 'R': cflags |= REG_ICASE; case 'r': @@ -669,9 +713,9 @@ process_arguments (int argc, char **argv) for (me = mount_list; me; me = me->me_next) { if (np_regex_match_mount_entry(me, &re)) { - fnd = true; + fnd = true; if (verbose > 3) - printf("%s %s matching expression %s\n", me->me_devname, me->me_mountdir, optarg); + 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))) { @@ -688,6 +732,9 @@ process_arguments (int argc, char **argv) fnd = false; path_selected = true; + np_set_best_match(path_select_list, mount_list, exact_match); + cflags = default_cflags; + break; case 'M': /* display mountpoint */ display_mntp = TRUE; @@ -871,10 +918,16 @@ print_help (void) printf (" %s\n", _("Display the mountpoint instead of the partition")); printf (" %s\n", "-m, --megabytes"); printf (" %s\n", _("Same as '--units MB'")); + printf (" %s\n", "-A, --all"); + printf (" %s\n", _("Explicitly select all pathes. This is equivalent to -R '.*'")); 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", "-r, --ereg-path=PATH, --ereg-partition=PARTITION"); printf (" %s\n", _("Regular expression for path or partition (may be repeated)")); + printf (" %s\n", "-I, --ignore-eregi-path=PATH, --ignore-eregi-partition=PARTITION"); + printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); + printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); + printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); printf (" %s\n", "-u, --units=STRING"); printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); diff --git a/plugins/t/check_disk.t b/plugins/t/check_disk.t index 4f5c4bc..99c434a 100644 --- a/plugins/t/check_disk.t +++ b/plugins/t/check_disk.t @@ -24,7 +24,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 => 69; + plan tests => 78; } $result = NPTest->testCmd( @@ -284,9 +284,15 @@ $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" ); +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -E -p /etc " ); cmp_ok( $result->return_code, '==', 2, "... unless -E/--exact-match is specified"); +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /etc -E " ); +cmp_ok( $result->return_code, '==', 3, "-E/--exact-match must be specified before -p"); + +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -r /etc -E " ); +cmp_ok( $result->return_code, '==', 3, "-E/--exact-match must be specified before -r"); + $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"); @@ -318,3 +324,24 @@ cmp_ok( $result->return_code, '==', 3, "Invalid options: -p must come after grou $result = NPTest->testCmd( "./check_disk -w 1 -c 1 -r '('" ); cmp_ok( $result->return_code, '==', 3, "Exit UNKNOWN if regex is not compileable"); +# ignore: exit unknown, if all pathes are deselected using -i +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '$mountpoint_valid' -i '$mountpoint2_valid'" ); +cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case sensitive)"); + +# ignore: exit unknown, if all pathes are deselected using -I +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -I '".uc($mountpoint_valid)."' -I '".uc($mountpoint2_valid)."'" ); +cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored (case insensitive)"); + +# ignore: exit unknown, if all pathes are deselected using -i +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '.*'" ); +cmp_ok( $result->return_code, '==', 3, "ignore-ereg: Unknown if all fs are ignored using -i '.*'"); + +# ignore: test if ignored path is actually ignored +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^$mountpoint2_valid\$'"); +like( $result->output, qr/$mountpoint_valid/, "output data does have $mountpoint_valid in it"); +unlike( $result->output, qr/$mountpoint2_valid/, "output data does not have $mountpoint2_valid in it"); + +# ignore: test if all pathes are listed when ignore regex doesn't match +$result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p $mountpoint_valid -p $mountpoint2_valid -i '^barbazJodsf\$'"); +like( $result->output, qr/$mountpoint_valid/, "ignore: output data does have $mountpoint_valid when regex doesn't match"); +like( $result->output, qr/$mountpoint2_valid/,"ignore: output data does have $mountpoint2_valid when regex doesn't match"); -- 2.30.2