summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/check_disk.c127
-rw-r--r--plugins/t/check_disk.t14
-rw-r--r--plugins/utils_disk.c31
-rw-r--r--plugins/utils_disk.h3
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 **);
119void print_path (const char *mypath); 119void print_path (const char *mypath);
120int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *); 120int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
121int check_disk (double usp, uintmax_t free_disk, double uisp); 121int check_disk (double usp, uintmax_t free_disk, double uisp);
122int walk_parameter_list (struct parameter_list *list, const char *name);
123void print_help (void); 122void print_help (void);
124void print_usage (void); 123void print_usage (void);
125 124
@@ -136,7 +135,7 @@ uintmax_t mult = 1024 * 1024;
136int verbose = 0; 135int verbose = 0;
137int erronly = FALSE; 136int erronly = FALSE;
138int display_mntp = FALSE; 137int display_mntp = FALSE;
139 138int exact_match = FALSE;
140 139
141 140
142int 141int
@@ -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
624int
625walk_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
22if ($mountpoint_valid eq "" or $mountpoint2_valid eq "") { 22if ($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 );
104cmp_ok( $result->return_code, '==', 2, "Combining above two tests, get critical"); 104cmp_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 );
109cmp_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" );
168cmp_ok( $result->return_code, '==', 0, "Checking /etc - should return info for /" ); 174cmp_ok( $result->return_code, '==', 0, "Checking /etc - should return info for /" );
169cmp_ok( $result->output, 'eq', $root_output, "check_disk /etc gives same as check_disk /"); 175cmp_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" );
178cmp_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" );
172cmp_ok( $result->return_code, '==', 2, "Checking / and /bob gives critical"); 181cmp_ok( $result->return_code, '==', 2, "Checking / and /bob gives critical");
173unlike( $result->perf_output, '/\/bob/', "perf data does not have /bob in it"); 182unlike( $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 /" );
185unlike( $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
46void 46/* Initialises a new parameter at the end of list */
47struct parameter_list *
47np_add_parameter(struct parameter_list **list, const char *name) 48np_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
64void 75void
@@ -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
130int
131np_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
26void np_add_name (struct name_list **list, const char *name); 26void np_add_name (struct name_list **list, const char *name);
27int np_find_name (struct name_list *list, const char *name); 27int np_find_name (struct name_list *list, const char *name);
28void np_add_parameter(struct parameter_list **list, const char *name); 28int np_seen_name (struct name_list *list, const char *name);
29struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
29int search_parameter_list (struct parameter_list *list, const char *name); 30int search_parameter_list (struct parameter_list *list, const char *name);