diff options
-rw-r--r-- | plugins/check_disk.c | 127 | ||||
-rw-r--r-- | plugins/t/check_disk.t | 14 | ||||
-rw-r--r-- | plugins/utils_disk.c | 31 | ||||
-rw-r--r-- | plugins/utils_disk.h | 3 |
4 files changed, 99 insertions, 76 deletions
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 **); | |||
119 | void print_path (const char *mypath); | 119 | void print_path (const char *mypath); |
120 | int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); | 120 | int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); |
121 | int check_disk (double usp, uintmax_t free_disk, double uisp); | 121 | int check_disk (double usp, uintmax_t free_disk, double uisp); |
122 | int walk_parameter_list (struct parameter_list *list, const char *name); | ||
123 | void print_help (void); | 122 | void print_help (void); |
124 | void print_usage (void); | 123 | void print_usage (void); |
125 | 124 | ||
@@ -136,7 +135,7 @@ uintmax_t mult = 1024 * 1024; | |||
136 | int verbose = 0; | 135 | int verbose = 0; |
137 | int erronly = FALSE; | 136 | int erronly = FALSE; |
138 | int display_mntp = FALSE; | 137 | int display_mntp = FALSE; |
139 | 138 | int exact_match = FALSE; | |
140 | 139 | ||
141 | 140 | ||
142 | int | 141 | int |
@@ -154,7 +153,8 @@ main (int argc, char **argv) | |||
154 | 153 | ||
155 | struct mount_entry *me; | 154 | struct mount_entry *me; |
156 | struct fs_usage fsp; | 155 | struct fs_usage fsp; |
157 | struct parameter_list *temp_list; | 156 | struct parameter_list *temp_list, *path; |
157 | struct name_list *seen = NULL; | ||
158 | 158 | ||
159 | output = strdup (" - free space:"); | 159 | output = strdup (" - free space:"); |
160 | details = strdup (""); | 160 | details = strdup (""); |
@@ -169,57 +169,69 @@ main (int argc, char **argv) | |||
169 | if (process_arguments (argc, argv) == ERROR) | 169 | if (process_arguments (argc, argv) == ERROR) |
170 | usage4 (_("Could not parse arguments")); | 170 | usage4 (_("Could not parse arguments")); |
171 | 171 | ||
172 | /* if a list of paths has been selected, preseed the list with | 172 | /* If a list of paths has not been selected, find entire |
173 | * the longest matching filesystem name by iterating across | 173 | mount list and create list of paths |
174 | * the mountlist once ahead of time. this will allow a query on | ||
175 | * "/var/log" to return information about "/var" if no "/var/log" | ||
176 | * filesystem exists, etc. this is the default behavior already | ||
177 | * with df-based checks, but for systems with their own space | ||
178 | * checking routines, this should make them more consistent. | ||
179 | */ | 174 | */ |
180 | if(path_select_list){ | 175 | if (! path_select_list) { |
181 | for (me = mount_list; me; me = me->me_next) { | 176 | for (me = mount_list; me; me = me->me_next) { |
182 | walk_parameter_list(path_select_list, me->me_mountdir); | 177 | path = np_add_parameter(&path_select_list, me->me_mountdir); |
183 | walk_parameter_list(path_select_list, me->me_devname); | 178 | path->w_df = w_df; |
179 | path->c_df = c_df; | ||
180 | path->w_dfp = w_dfp; | ||
181 | path->c_dfp = c_dfp; | ||
182 | path->w_idfp = w_idfp; | ||
183 | path->c_idfp = c_idfp; | ||
184 | path->best_match = me; | ||
184 | } | 185 | } |
185 | /* now pretend we never saw anything, but keep found_len. | 186 | } else { |
186 | * thus future searches will only match the best match */ | 187 | np_set_best_match(path_select_list, mount_list, exact_match); |
187 | for (temp_list = path_select_list; temp_list; temp_list=temp_list->name_next){ | 188 | |
188 | temp_list->found=0; | 189 | /* Error if no match found for specified paths */ |
190 | temp_list = path_select_list; | ||
191 | while (temp_list) { | ||
192 | if (! temp_list->best_match) { | ||
193 | die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name); | ||
194 | } | ||
195 | temp_list = temp_list->name_next; | ||
189 | } | 196 | } |
190 | } | 197 | } |
191 | 198 | ||
192 | /* for every mount entry */ | 199 | /* Process for every path in list */ |
193 | for (me = mount_list; me; me = me->me_next) { | 200 | for (path = path_select_list; path; path=path->name_next) { |
194 | /* if there's a list of paths to select, the current mount | 201 | me = path->best_match; |
195 | * entry matches in path or device name, get fs usage */ | 202 | w_df = path->w_df; |
196 | if (path_select_list && | 203 | c_df = path->c_df; |
197 | (walk_parameter_list (path_select_list, me->me_mountdir) || | 204 | w_dfp = path->w_dfp; |
198 | walk_parameter_list (path_select_list, me->me_devname) ) ) { | 205 | c_dfp = path->c_dfp; |
199 | get_fs_usage (me->me_mountdir, me->me_devname, &fsp); | 206 | w_idfp = path->w_idfp; |
200 | /* else if there's a list of paths/devices to select (but | 207 | c_idfp = path->c_idfp; |
201 | * we didn't match above) skip to the next mount entry */ | 208 | |
202 | } else if (path_select_list) { | 209 | /* Filters */ |
210 | |||
211 | /* Remove filesystems already seen */ | ||
212 | if (np_seen_name(seen, me->me_mountdir)) { | ||
203 | continue; | 213 | continue; |
204 | /* skip remote filesystems if we're not interested in them */ | 214 | } else { |
205 | } else if (me->me_remote && show_local_fs) { | 215 | np_add_name(&seen, me->me_mountdir); |
216 | } | ||
217 | /* Skip remote filesystems if we're not interested in them */ | ||
218 | if (me->me_remote && show_local_fs) { | ||
206 | continue; | 219 | continue; |
207 | /* skip pseudo fs's if we haven't asked for all fs's */ | 220 | /* Skip pseudo fs's if we haven't asked for all fs's */ |
208 | } else if (me->me_dummy && !show_all_fs) { | 221 | } else if (me->me_dummy && !show_all_fs) { |
209 | continue; | 222 | continue; |
210 | /* skip excluded fstypes */ | 223 | /* Skip excluded fstypes */ |
211 | } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) { | 224 | } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) { |
212 | continue; | 225 | continue; |
213 | /* skip excluded fs's */ | 226 | /* Skip excluded fs's */ |
214 | } else if (dp_exclude_list && | 227 | } else if (dp_exclude_list && |
215 | (np_find_name (dp_exclude_list, me->me_devname) || | 228 | (np_find_name (dp_exclude_list, me->me_devname) || |
216 | np_find_name (dp_exclude_list, me->me_mountdir))) { | 229 | np_find_name (dp_exclude_list, me->me_mountdir))) { |
217 | continue; | 230 | continue; |
218 | /* otherwise, get fs usage */ | ||
219 | } else { | ||
220 | get_fs_usage (me->me_mountdir, me->me_devname, &fsp); | ||
221 | } | 231 | } |
222 | 232 | ||
233 | get_fs_usage (me->me_mountdir, me->me_devname, &fsp); | ||
234 | |||
223 | if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { | 235 | if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { |
224 | usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks; | 236 | usp = (double)(fsp.fsu_blocks - fsp.fsu_bavail) * 100 / fsp.fsu_blocks; |
225 | uisp = (double)(fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files; | 237 | uisp = (double)(fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files; |
@@ -271,15 +283,6 @@ main (int argc, char **argv) | |||
271 | if (verbose > 2) | 283 | if (verbose > 2) |
272 | asprintf (&output, "%s%s", output, details); | 284 | asprintf (&output, "%s%s", output, details); |
273 | 285 | ||
274 | /* Override result if paths specified and not found */ | ||
275 | temp_list = path_select_list; | ||
276 | while (temp_list) { | ||
277 | if (!temp_list->found) { | ||
278 | asprintf (&output, _("%s [%s not found]"), output, temp_list->name); | ||
279 | result = STATE_CRITICAL; | ||
280 | } | ||
281 | temp_list = temp_list->name_next; | ||
282 | } | ||
283 | 286 | ||
284 | printf ("DISK %s%s|%s\n", state_text (result), output, perf); | 287 | printf ("DISK %s%s|%s\n", state_text (result), output, perf); |
285 | return result; | 288 | return result; |
@@ -318,6 +321,7 @@ process_arguments (int argc, char **argv) | |||
318 | {"exclude-type", required_argument, 0, 'X'}, | 321 | {"exclude-type", required_argument, 0, 'X'}, |
319 | {"mountpoint", no_argument, 0, 'M'}, | 322 | {"mountpoint", no_argument, 0, 'M'}, |
320 | {"errors-only", no_argument, 0, 'e'}, | 323 | {"errors-only", no_argument, 0, 'e'}, |
324 | {"exact-match", no_argument, 0, 'E'}, | ||
321 | {"verbose", no_argument, 0, 'v'}, | 325 | {"verbose", no_argument, 0, 'v'}, |
322 | {"quiet", no_argument, 0, 'q'}, | 326 | {"quiet", no_argument, 0, 'q'}, |
323 | {"clear", no_argument, 0, 'C'}, | 327 | {"clear", no_argument, 0, 'C'}, |
@@ -336,7 +340,7 @@ process_arguments (int argc, char **argv) | |||
336 | strcpy (argv[c], "-t"); | 340 | strcpy (argv[c], "-t"); |
337 | 341 | ||
338 | while (1) { | 342 | while (1) { |
339 | c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklM", longopts, &option); | 343 | c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option); |
340 | 344 | ||
341 | if (c == -1 || c == EOF) | 345 | if (c == -1 || c == EOF) |
342 | break; | 346 | break; |
@@ -469,6 +473,9 @@ process_arguments (int argc, char **argv) | |||
469 | case 'e': | 473 | case 'e': |
470 | erronly = TRUE; | 474 | erronly = TRUE; |
471 | break; | 475 | break; |
476 | case 'E': | ||
477 | exact_match = TRUE; | ||
478 | break; | ||
472 | case 'M': /* display mountpoint */ | 479 | case 'M': /* display mountpoint */ |
473 | display_mntp = TRUE; | 480 | display_mntp = TRUE; |
474 | break; | 481 | break; |
@@ -621,30 +628,6 @@ check_disk (double usp, uintmax_t free_disk, double uisp) | |||
621 | 628 | ||
622 | 629 | ||
623 | 630 | ||
624 | int | ||
625 | walk_parameter_list (struct parameter_list *list, const char *name) | ||
626 | { | ||
627 | int name_len; | ||
628 | name_len = strlen(name); | ||
629 | while (list) { | ||
630 | /* if the paths match up to the length of the mount path, | ||
631 | * AND if the mount path name is longer than the longest | ||
632 | * found match, we have a new winner */ | ||
633 | if (name_len >= list->found_len && | ||
634 | ! strncmp(list->name, name, name_len)) { | ||
635 | list->found = 1; | ||
636 | list->found_len = name_len; | ||
637 | /* if required for parameter_lists that have not saved w_df, etc (eg exclude lists) */ | ||
638 | if (list->w_df) w_df = list->w_df; | ||
639 | if (list->c_df) c_df = list->c_df; | ||
640 | if (list->w_dfp>=0.0) w_dfp = list->w_dfp; | ||
641 | if (list->c_dfp>=0.0) c_dfp = list->c_dfp; | ||
642 | return TRUE; | ||
643 | } | ||
644 | list = list->name_next; | ||
645 | } | ||
646 | return FALSE; | ||
647 | } | ||
648 | 631 | ||
649 | 632 | ||
650 | 633 | ||
@@ -695,6 +678,8 @@ print_help (void) | |||
695 | printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); | 678 | printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); |
696 | printf (" %s\n", "-m, --mountpoint"); | 679 | printf (" %s\n", "-m, --mountpoint"); |
697 | printf (" %s\n", _("Display the mountpoint instead of the partition")); | 680 | printf (" %s\n", _("Display the mountpoint instead of the partition")); |
681 | printf (" %s\n", "-E, --exact-match"); | ||
682 | printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths")); | ||
698 | printf (" %s\n", "-e, --errors-only"); | 683 | printf (" %s\n", "-e, --errors-only"); |
699 | printf (" %s\n", _("Display only devices/mountpoints with errors")); | 684 | printf (" %s\n", _("Display only devices/mountpoints with errors")); |
700 | printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); | 685 | printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); |
@@ -713,5 +698,5 @@ print_usage (void) | |||
713 | { | 698 | { |
714 | printf (_("Usage:")); | 699 | printf (_("Usage:")); |
715 | printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname); | 700 | printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname); |
716 | printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q]\n"); | 701 | printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n"); |
717 | } | 702 | } |
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 | |||
22 | if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { | 22 | if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { |
23 | plan skip_all => "Need 2 mountpoints to test"; | 23 | plan skip_all => "Need 2 mountpoints to test"; |
24 | } else { | 24 | } else { |
25 | plan tests => 32; | 25 | plan tests => 35; |
26 | } | 26 | } |
27 | 27 | ||
28 | $result = NPTest->testCmd( | 28 | $result = NPTest->testCmd( |
@@ -103,6 +103,12 @@ $result = NPTest->testCmd( | |||
103 | ); | 103 | ); |
104 | cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); | 104 | cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); |
105 | 105 | ||
106 | $result = NPTest->testCmd( | ||
107 | "./check_disk -w $avg_free% -c $avg_free% -p $less_free -w $avg_free% -c 0% -p $more_free" | ||
108 | ); | ||
109 | cmp_ok( $result->return_code, '==', 2, "And reversing arguments should not make a difference"); | ||
110 | |||
111 | |||
106 | 112 | ||
107 | 113 | ||
108 | $result = NPTest->testCmd( | 114 | $result = NPTest->testCmd( |
@@ -168,6 +174,12 @@ $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /etc" ); | |||
168 | cmp_ok( $result->return_code, '==', 0, "Checking /etc - should return info for /" ); | 174 | cmp_ok( $result->return_code, '==', 0, "Checking /etc - should return info for /" ); |
169 | cmp_ok( $result->output, 'eq', $root_output, "check_disk /etc gives same as check_disk /"); | 175 | cmp_ok( $result->output, 'eq', $root_output, "check_disk /etc gives same as check_disk /"); |
170 | 176 | ||
177 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p /etc -E" ); | ||
178 | cmp_ok( $result->return_code, '==', 2, "... unless -E/--exact-match is specified"); | ||
179 | |||
171 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /bob" ); | 180 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /bob" ); |
172 | cmp_ok( $result->return_code, '==', 2, "Checking / and /bob gives critical"); | 181 | cmp_ok( $result->return_code, '==', 2, "Checking / and /bob gives critical"); |
173 | unlike( $result->perf_output, '/\/bob/', "perf data does not have /bob in it"); | 182 | unlike( $result->perf_output, '/\/bob/', "perf data does not have /bob in it"); |
183 | |||
184 | $result = NPTest->testCmd( "./check_disk -w 0% -c 0% -p / -p /" ); | ||
185 | 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) | |||
43 | *list = new_entry; | 43 | *list = new_entry; |
44 | } | 44 | } |
45 | 45 | ||
46 | void | 46 | /* Initialises a new parameter at the end of list */ |
47 | struct parameter_list * | ||
47 | np_add_parameter(struct parameter_list **list, const char *name) | 48 | np_add_parameter(struct parameter_list **list, const char *name) |
48 | { | 49 | { |
50 | struct parameter_list *current = *list; | ||
49 | struct parameter_list *new_path; | 51 | struct parameter_list *new_path; |
50 | new_path = (struct parameter_list *) malloc (sizeof *new_path); | 52 | new_path = (struct parameter_list *) malloc (sizeof *new_path); |
51 | new_path->name = (char *) name; | 53 | new_path->name = (char *) name; |
@@ -57,8 +59,17 @@ np_add_parameter(struct parameter_list **list, const char *name) | |||
57 | new_path->c_dfp = -1.0; | 59 | new_path->c_dfp = -1.0; |
58 | new_path->w_idfp = -1.0; | 60 | new_path->w_idfp = -1.0; |
59 | new_path->c_idfp = -1.0; | 61 | new_path->c_idfp = -1.0; |
60 | new_path->name_next = *list; | 62 | new_path->best_match = NULL; |
61 | *list = new_path; | 63 | |
64 | if (current == NULL) { | ||
65 | *list = new_path; | ||
66 | } else { | ||
67 | while (current->name_next) { | ||
68 | current = current->name_next; | ||
69 | } | ||
70 | current->name_next = new_path; | ||
71 | } | ||
72 | return new_path; | ||
62 | } | 73 | } |
63 | 74 | ||
64 | void | 75 | void |
@@ -93,6 +104,8 @@ np_set_best_match(struct parameter_list *desired, struct mount_entry *mount_list | |||
93 | if (best_match) { | 104 | if (best_match) { |
94 | d->best_match = best_match; | 105 | d->best_match = best_match; |
95 | d->found = TRUE; | 106 | d->found = TRUE; |
107 | } else { | ||
108 | d->best_match = NULL; /* Not sure why this is needed as it should be null on initialisation */ | ||
96 | } | 109 | } |
97 | } | 110 | } |
98 | } | 111 | } |
@@ -114,3 +127,15 @@ np_find_name (struct name_list *list, const char *name) | |||
114 | return FALSE; | 127 | return FALSE; |
115 | } | 128 | } |
116 | 129 | ||
130 | int | ||
131 | np_seen_name(struct name_list *list, const char *name) | ||
132 | { | ||
133 | const struct name_list *s; | ||
134 | for (s = list; s; s=s->next) { | ||
135 | if (!strcmp(s->name, name)) { | ||
136 | return TRUE; | ||
137 | } | ||
138 | } | ||
139 | return FALSE; | ||
140 | } | ||
141 | |||
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 | |||
25 | 25 | ||
26 | void np_add_name (struct name_list **list, const char *name); | 26 | void np_add_name (struct name_list **list, const char *name); |
27 | int np_find_name (struct name_list *list, const char *name); | 27 | int np_find_name (struct name_list *list, const char *name); |
28 | void np_add_parameter(struct parameter_list **list, const char *name); | 28 | int np_seen_name (struct name_list *list, const char *name); |
29 | struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); | ||
29 | int search_parameter_list (struct parameter_list *list, const char *name); | 30 | int search_parameter_list (struct parameter_list *list, const char *name); |