diff options
Diffstat (limited to 'plugins/check_disk.c')
-rw-r--r-- | plugins/check_disk.c | 243 |
1 files changed, 140 insertions, 103 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c index c526d05..05e5502 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c | |||
@@ -112,11 +112,12 @@ enum | |||
112 | { | 112 | { |
113 | SYNC_OPTION = CHAR_MAX + 1, | 113 | SYNC_OPTION = CHAR_MAX + 1, |
114 | NO_SYNC_OPTION, | 114 | NO_SYNC_OPTION, |
115 | BLOCK_SIZE_OPTION | 115 | BLOCK_SIZE_OPTION, |
116 | IGNORE_MISSING | ||
116 | }; | 117 | }; |
117 | 118 | ||
118 | #ifdef _AIX | 119 | #ifdef _AIX |
119 | #pragma alloca | 120 | #pragma alloca |
120 | #endif | 121 | #endif |
121 | 122 | ||
122 | int process_arguments (int, char **); | 123 | int process_arguments (int, char **); |
@@ -126,13 +127,10 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch | |||
126 | void print_help (void); | 127 | void print_help (void); |
127 | void print_usage (void); | 128 | void print_usage (void); |
128 | double calculate_percent(uintmax_t, uintmax_t); | 129 | double calculate_percent(uintmax_t, uintmax_t); |
129 | void stat_path (struct parameter_list *p); | 130 | bool stat_path (struct parameter_list *p); |
130 | void get_stats (struct parameter_list *p, struct fs_usage *fsp); | 131 | void get_stats (struct parameter_list *p, struct fs_usage *fsp); |
131 | void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); | 132 | void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); |
132 | 133 | ||
133 | double w_dfp = -1.0; | ||
134 | double c_dfp = -1.0; | ||
135 | char *path; | ||
136 | char *exclude_device; | 134 | char *exclude_device; |
137 | char *units; | 135 | char *units; |
138 | uintmax_t mult = 1024 * 1024; | 136 | uintmax_t mult = 1024 * 1024; |
@@ -140,6 +138,7 @@ int verbose = 0; | |||
140 | int erronly = FALSE; | 138 | int erronly = FALSE; |
141 | int display_mntp = FALSE; | 139 | int display_mntp = FALSE; |
142 | int exact_match = FALSE; | 140 | int exact_match = FALSE; |
141 | bool ignore_missing = false; | ||
143 | int freespace_ignore_reserved = FALSE; | 142 | int freespace_ignore_reserved = FALSE; |
144 | int display_inodes_perfdata = FALSE; | 143 | int display_inodes_perfdata = FALSE; |
145 | char *warn_freespace_units = NULL; | 144 | char *warn_freespace_units = NULL; |
@@ -155,6 +154,7 @@ char *crit_usedinodes_percent = NULL; | |||
155 | char *warn_freeinodes_percent = NULL; | 154 | char *warn_freeinodes_percent = NULL; |
156 | char *crit_freeinodes_percent = NULL; | 155 | char *crit_freeinodes_percent = NULL; |
157 | int path_selected = FALSE; | 156 | int path_selected = FALSE; |
157 | bool path_ignored = false; | ||
158 | char *group = NULL; | 158 | char *group = NULL; |
159 | struct stat *stat_buf; | 159 | struct stat *stat_buf; |
160 | struct name_list *seen = NULL; | 160 | struct name_list *seen = NULL; |
@@ -166,12 +166,13 @@ main (int argc, char **argv) | |||
166 | int result = STATE_UNKNOWN; | 166 | int result = STATE_UNKNOWN; |
167 | int disk_result = STATE_UNKNOWN; | 167 | int disk_result = STATE_UNKNOWN; |
168 | char *output; | 168 | char *output; |
169 | char *ignored; | ||
169 | char *details; | 170 | char *details; |
170 | char *perf; | 171 | char *perf; |
171 | char *perf_ilabel; | 172 | char *perf_ilabel; |
172 | char *preamble; | 173 | char *preamble = " - free space:"; |
174 | char *ignored_preamble = " - ignored paths:"; | ||
173 | char *flag_header; | 175 | char *flag_header; |
174 | double inode_space_pct; | ||
175 | int temp_result; | 176 | int temp_result; |
176 | 177 | ||
177 | struct mount_entry *me; | 178 | struct mount_entry *me; |
@@ -182,8 +183,8 @@ main (int argc, char **argv) | |||
182 | char mountdir[32]; | 183 | char mountdir[32]; |
183 | #endif | 184 | #endif |
184 | 185 | ||
185 | preamble = strdup (" - free space:"); | ||
186 | output = strdup (""); | 186 | output = strdup (""); |
187 | ignored = strdup (""); | ||
187 | details = strdup (""); | 188 | details = strdup (""); |
188 | perf = strdup (""); | 189 | perf = strdup (""); |
189 | perf_ilabel = strdup (""); | 190 | perf_ilabel = strdup (""); |
@@ -204,7 +205,7 @@ main (int argc, char **argv) | |||
204 | /* If a list of paths has not been selected, find entire | 205 | /* If a list of paths has not been selected, find entire |
205 | mount list and create list of paths | 206 | mount list and create list of paths |
206 | */ | 207 | */ |
207 | if (path_selected == FALSE) { | 208 | if (path_selected == FALSE && path_ignored == false) { |
208 | for (me = mount_list; me; me = me->me_next) { | 209 | for (me = mount_list; me; me = me->me_next) { |
209 | if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { | 210 | if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { |
210 | path = np_add_parameter(&path_select_list, me->me_mountdir); | 211 | path = np_add_parameter(&path_select_list, me->me_mountdir); |
@@ -214,24 +215,49 @@ main (int argc, char **argv) | |||
214 | set_all_thresholds(path); | 215 | set_all_thresholds(path); |
215 | } | 216 | } |
216 | } | 217 | } |
217 | np_set_best_match(path_select_list, mount_list, exact_match); | 218 | |
219 | if (path_ignored == false) { | ||
220 | np_set_best_match(path_select_list, mount_list, exact_match); | ||
221 | } | ||
218 | 222 | ||
219 | /* Error if no match found for specified paths */ | 223 | /* Error if no match found for specified paths */ |
220 | temp_list = path_select_list; | 224 | temp_list = path_select_list; |
221 | 225 | ||
222 | while (temp_list) { | 226 | while (path_select_list) { |
223 | if (! temp_list->best_match) { | 227 | if (! path_select_list->best_match && ignore_missing == true) { |
224 | die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name); | 228 | /* If the first element will be deleted, the temp_list must be updated with the new start address as well */ |
229 | if (path_select_list == temp_list) { | ||
230 | temp_list = path_select_list->name_next; | ||
231 | } | ||
232 | /* Add path argument to list of ignored paths to inform about missing paths being ignored and not alerted */ | ||
233 | xasprintf (&ignored, "%s %s;", ignored, path_select_list->name); | ||
234 | /* Delete the path from the list so that it is not stat-checked later in the code. */ | ||
235 | path_select_list = np_del_parameter(path_select_list, path_select_list->name_prev); | ||
236 | } else if (! path_select_list->best_match) { | ||
237 | /* Without --ignore-missing option, exit with Critical state. */ | ||
238 | die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), path_select_list->name); | ||
239 | } else { | ||
240 | /* Continue jumping through the list */ | ||
241 | path_select_list = path_select_list->name_next; | ||
225 | } | 242 | } |
243 | } | ||
226 | 244 | ||
227 | temp_list = temp_list->name_next; | 245 | path_select_list = temp_list; |
246 | |||
247 | if (! path_select_list && ignore_missing == true) { | ||
248 | result = STATE_OK; | ||
249 | if (verbose >= 2) { | ||
250 | printf ("None of the provided paths were found\n"); | ||
251 | } | ||
228 | } | 252 | } |
229 | 253 | ||
230 | /* Process for every path in list */ | 254 | /* Process for every path in list */ |
231 | for (path = path_select_list; path; path=path->name_next) { | 255 | for (path = path_select_list; path; path=path->name_next) { |
232 | if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) | 256 | if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL) |
233 | printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end, | 257 | printf("Thresholds(pct) for %s warn: %f crit %f\n", |
234 | path->freespace_percent->critical->end); | 258 | path->name, |
259 | path->freespace_percent->warning->end, | ||
260 | path->freespace_percent->critical->end); | ||
235 | 261 | ||
236 | if (verbose >= 3 && path->group != NULL) | 262 | if (verbose >= 3 && path->group != NULL) |
237 | printf("Group of %s: %s\n",path->name,path->group); | 263 | printf("Group of %s: %s\n",path->name,path->group); |
@@ -241,6 +267,10 @@ main (int argc, char **argv) | |||
241 | 267 | ||
242 | me = path->best_match; | 268 | me = path->best_match; |
243 | 269 | ||
270 | if (!me) { | ||
271 | continue; | ||
272 | } | ||
273 | |||
244 | #ifdef __CYGWIN__ | 274 | #ifdef __CYGWIN__ |
245 | if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) | 275 | if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) |
246 | continue; | 276 | continue; |
@@ -259,8 +289,12 @@ main (int argc, char **argv) | |||
259 | if (path->group == NULL) { | 289 | if (path->group == NULL) { |
260 | /* Skip remote filesystems if we're not interested in them */ | 290 | /* Skip remote filesystems if we're not interested in them */ |
261 | if (me->me_remote && show_local_fs) { | 291 | if (me->me_remote && show_local_fs) { |
262 | if (stat_remote_fs) | 292 | if (stat_remote_fs) { |
263 | stat_path(path); | 293 | if (!stat_path(path) && ignore_missing == true) { |
294 | result = STATE_OK; | ||
295 | xasprintf (&ignored, "%s %s;", ignored, path->name); | ||
296 | } | ||
297 | } | ||
264 | continue; | 298 | continue; |
265 | /* Skip pseudo fs's if we haven't asked for all fs's */ | 299 | /* Skip pseudo fs's if we haven't asked for all fs's */ |
266 | } else if (me->me_dummy && !show_all_fs) { | 300 | } else if (me->me_dummy && !show_all_fs) { |
@@ -279,14 +313,20 @@ main (int argc, char **argv) | |||
279 | } | 313 | } |
280 | } | 314 | } |
281 | 315 | ||
282 | stat_path(path); | 316 | if (!stat_path(path)) { |
317 | if (ignore_missing == true) { | ||
318 | result = STATE_OK; | ||
319 | xasprintf (&ignored, "%s %s;", ignored, path->name); | ||
320 | } | ||
321 | continue; | ||
322 | } | ||
283 | get_fs_usage (me->me_mountdir, me->me_devname, &fsp); | 323 | get_fs_usage (me->me_mountdir, me->me_devname, &fsp); |
284 | 324 | ||
285 | if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { | 325 | if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { |
286 | get_stats (path, &fsp); | 326 | get_stats (path, &fsp); |
287 | 327 | ||
288 | if (verbose >= 3) { | 328 | if (verbose >= 3) { |
289 | printf ("For %s, used_pct=%g free_pct=%g used_units=%llu free_units=%llu total_units=%llu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n", | 329 | printf ("For %s, used_pct=%g free_pct=%g used_units=%lu free_units=%lu total_units=%lu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%lu mult=%lu\n", |
290 | me->me_mountdir, | 330 | me->me_mountdir, |
291 | path->dused_pct, | 331 | path->dused_pct, |
292 | path->dfree_pct, | 332 | path->dfree_pct, |
@@ -367,10 +407,10 @@ main (int argc, char **argv) | |||
367 | critical_high_tide = UINT64_MAX; | 407 | critical_high_tide = UINT64_MAX; |
368 | 408 | ||
369 | if (path->freeinodes_percent->warning != NULL) { | 409 | if (path->freeinodes_percent->warning != NULL) { |
370 | warning_high_tide = llabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total )); | 410 | warning_high_tide = (uint64_t) fabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total )); |
371 | } | 411 | } |
372 | if (path->freeinodes_percent->critical != NULL) { | 412 | if (path->freeinodes_percent->critical != NULL) { |
373 | critical_high_tide = llabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total )); | 413 | critical_high_tide = (uint64_t) fabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total )); |
374 | } | 414 | } |
375 | 415 | ||
376 | xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); | 416 | xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir); |
@@ -404,22 +444,18 @@ main (int argc, char **argv) | |||
404 | xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); | 444 | xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); |
405 | } | 445 | } |
406 | free(flag_header); | 446 | free(flag_header); |
407 | /* TODO: Need to do a similar debug line | ||
408 | xasprintf (&details, _("%s\n\%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"), | ||
409 | details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct, | ||
410 | me->me_devname, me->me_type, me->me_mountdir, | ||
411 | (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp); | ||
412 | */ | ||
413 | |||
414 | } | 447 | } |
415 | |||
416 | } | 448 | } |
417 | 449 | ||
418 | if (verbose >= 2) | 450 | if (verbose >= 2) |
419 | xasprintf (&output, "%s%s", output, details); | 451 | xasprintf (&output, "%s%s", output, details); |
420 | 452 | ||
453 | if (strcmp(output, "") == 0 && ! erronly) { | ||
454 | preamble = ""; | ||
455 | xasprintf (&output, " - No disks were found for provided parameters;"); | ||
456 | } | ||
421 | 457 | ||
422 | printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf); | 458 | printf ("DISK %s%s%s%s%s|%s\n", state_text (result), ((erronly && result==STATE_OK)) ? "" : preamble, output, (strcmp(ignored, "") == 0) ? "" : ignored_preamble, ignored, perf); |
423 | return result; | 459 | return result; |
424 | } | 460 | } |
425 | 461 | ||
@@ -488,6 +524,7 @@ process_arguments (int argc, char **argv) | |||
488 | {"ignore-ereg-partition", required_argument, 0, 'i'}, | 524 | {"ignore-ereg-partition", required_argument, 0, 'i'}, |
489 | {"ignore-eregi-path", required_argument, 0, 'I'}, | 525 | {"ignore-eregi-path", required_argument, 0, 'I'}, |
490 | {"ignore-eregi-partition", required_argument, 0, 'I'}, | 526 | {"ignore-eregi-partition", required_argument, 0, 'I'}, |
527 | {"ignore-missing", no_argument, 0, IGNORE_MISSING}, | ||
491 | {"local", no_argument, 0, 'l'}, | 528 | {"local", no_argument, 0, 'l'}, |
492 | {"stat-remote-fs", no_argument, 0, 'L'}, | 529 | {"stat-remote-fs", no_argument, 0, 'L'}, |
493 | {"iperfdata", no_argument, 0, 'P'}, | 530 | {"iperfdata", no_argument, 0, 'P'}, |
@@ -547,7 +584,7 @@ process_arguments (int argc, char **argv) | |||
547 | 584 | ||
548 | /* Awful mistake where the range values do not make sense. Normally, | 585 | /* Awful mistake where the range values do not make sense. Normally, |
549 | you alert if the value is within the range, but since we are using | 586 | you alert if the value is within the range, but since we are using |
550 | freespace, we have to alert if outside the range. Thus we artifically | 587 | freespace, we have to alert if outside the range. Thus we artificially |
551 | force @ at the beginning of the range, so that it is backwards compatible | 588 | force @ at the beginning of the range, so that it is backwards compatible |
552 | */ | 589 | */ |
553 | case 'c': /* critical threshold */ | 590 | case 'c': /* critical threshold */ |
@@ -586,21 +623,36 @@ process_arguments (int argc, char **argv) | |||
586 | if (! strcasecmp (optarg, "bytes")) { | 623 | if (! strcasecmp (optarg, "bytes")) { |
587 | mult = (uintmax_t)1; | 624 | mult = (uintmax_t)1; |
588 | units = strdup ("B"); | 625 | units = strdup ("B"); |
589 | } else if ( (! strcmp (optarg, "kB")) || (!strcmp(optarg, "KiB")) ) { | 626 | } else if (!strcmp(optarg, "KiB")) { |
590 | mult = (uintmax_t)1024; | 627 | mult = (uintmax_t)1024; |
591 | units = strdup ("kiB"); | 628 | units = strdup ("KiB"); |
592 | } else if ( (! strcmp (optarg, "MB")) || (!strcmp(optarg, "MiB")) ) { | 629 | } else if (! strcmp (optarg, "kB")) { |
630 | mult = (uintmax_t)1000; | ||
631 | units = strdup ("kB"); | ||
632 | } else if (!strcmp(optarg, "MiB")) { | ||
593 | mult = (uintmax_t)1024 * 1024; | 633 | mult = (uintmax_t)1024 * 1024; |
594 | units = strdup ("MiB"); | 634 | units = strdup ("MiB"); |
595 | } else if ( (! strcmp (optarg, "GB")) || (!strcmp(optarg, "GiB")) ) { | 635 | } else if (! strcmp (optarg, "MB")) { |
636 | mult = (uintmax_t)1000 * 1000; | ||
637 | units = strdup ("MB"); | ||
638 | } else if (!strcmp(optarg, "GiB")) { | ||
596 | mult = (uintmax_t)1024 * 1024 * 1024; | 639 | mult = (uintmax_t)1024 * 1024 * 1024; |
597 | units = strdup ("GiB"); | 640 | units = strdup ("GiB"); |
598 | } else if ( (! strcmp (optarg, "TB")) || (!strcmp(optarg, "TiB")) ) { | 641 | } else if (! strcmp (optarg, "GB")){ |
642 | mult = (uintmax_t)1000 * 1000 * 1000; | ||
643 | units = strdup ("GB"); | ||
644 | } else if (!strcmp(optarg, "TiB")) { | ||
599 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024; | 645 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024; |
600 | units = strdup ("TiB"); | 646 | units = strdup ("TiB"); |
601 | } else if ( (! strcmp (optarg, "PB")) || (!strcmp(optarg, "PiB")) ) { | 647 | } else if (! strcmp (optarg, "TB")) { |
648 | mult = (uintmax_t)1000 * 1000 * 1000 * 1000; | ||
649 | units = strdup ("TB"); | ||
650 | } else if (!strcmp(optarg, "PiB")) { | ||
602 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; | 651 | mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024; |
603 | units = strdup ("PiB"); | 652 | units = strdup ("PiB"); |
653 | } else if (! strcmp (optarg, "PB")){ | ||
654 | mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000; | ||
655 | units = strdup ("PB"); | ||
604 | } else { | 656 | } else { |
605 | die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); | 657 | die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); |
606 | } | 658 | } |
@@ -639,12 +691,19 @@ process_arguments (int argc, char **argv) | |||
639 | /* add parameter if not found. overwrite thresholds if path has already been added */ | 691 | /* add parameter if not found. overwrite thresholds if path has already been added */ |
640 | if (! (se = np_find_parameter(path_select_list, optarg))) { | 692 | if (! (se = np_find_parameter(path_select_list, optarg))) { |
641 | se = np_add_parameter(&path_select_list, optarg); | 693 | se = np_add_parameter(&path_select_list, optarg); |
694 | |||
695 | if (stat(optarg, &stat_buf[0]) && ignore_missing == true) { | ||
696 | path_ignored = true; | ||
697 | break; | ||
698 | } | ||
642 | } | 699 | } |
643 | se->group = group; | 700 | se->group = group; |
644 | set_all_thresholds(se); | 701 | set_all_thresholds(se); |
645 | 702 | ||
646 | /* With autofs, it is required to stat() the path before re-populating the mount_list */ | 703 | /* With autofs, it is required to stat() the path before re-populating the mount_list */ |
647 | stat_path(se); | 704 | if (!stat_path(se)) { |
705 | break; | ||
706 | } | ||
648 | /* NB: We can't free the old mount_list "just like that": both list pointers and struct | 707 | /* NB: We can't free the old mount_list "just like that": both list pointers and struct |
649 | * pointers are copied around. One of the reason it wasn't done yet is that other parts | 708 | * pointers are copied around. One of the reason it wasn't done yet is that other parts |
650 | * of check_disk need the same kind of cleanup so it'd better be done as a whole */ | 709 | * of check_disk need the same kind of cleanup so it'd better be done as a whole */ |
@@ -687,6 +746,7 @@ process_arguments (int argc, char **argv) | |||
687 | break; | 746 | break; |
688 | case 'I': | 747 | case 'I': |
689 | cflags |= REG_ICASE; | 748 | cflags |= REG_ICASE; |
749 | // Intentional fallthrough | ||
690 | case 'i': | 750 | case 'i': |
691 | if (!path_selected) | 751 | if (!path_selected) |
692 | die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); | 752 | die (STATE_UNKNOWN, "DISK %s: %s\n", _("UNKNOWN"), _("Paths need to be selected before using -i/-I. Use -A to select all paths explicitly")); |
@@ -724,10 +784,15 @@ process_arguments (int argc, char **argv) | |||
724 | cflags = default_cflags; | 784 | cflags = default_cflags; |
725 | break; | 785 | break; |
726 | 786 | ||
787 | case IGNORE_MISSING: | ||
788 | ignore_missing = true; | ||
789 | break; | ||
727 | case 'A': | 790 | case 'A': |
728 | optarg = strdup(".*"); | 791 | optarg = strdup(".*"); |
792 | // Intentional fallthrough | ||
729 | case 'R': | 793 | case 'R': |
730 | cflags |= REG_ICASE; | 794 | cflags |= REG_ICASE; |
795 | // Intentional fallthrough | ||
731 | case 'r': | 796 | case 'r': |
732 | if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || | 797 | if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || |
733 | crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || | 798 | crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || |
@@ -757,7 +822,11 @@ process_arguments (int argc, char **argv) | |||
757 | } | 822 | } |
758 | } | 823 | } |
759 | 824 | ||
760 | if (!fnd) | 825 | if (!fnd && ignore_missing == true) { |
826 | path_ignored = true; | ||
827 | /* path_selected = TRUE;*/ | ||
828 | break; | ||
829 | } else if (!fnd) | ||
761 | die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), | 830 | die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), |
762 | _("Regular expression did not match any path or disk"), optarg); | 831 | _("Regular expression did not match any path or disk"), optarg); |
763 | 832 | ||
@@ -817,7 +886,7 @@ process_arguments (int argc, char **argv) | |||
817 | if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c])) | 886 | if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c])) |
818 | crit_usedspace_percent = argv[c++]; | 887 | crit_usedspace_percent = argv[c++]; |
819 | 888 | ||
820 | if (argc > c && path == NULL) { | 889 | if (argc > c) { |
821 | se = np_add_parameter(&path_select_list, strdup(argv[c++])); | 890 | se = np_add_parameter(&path_select_list, strdup(argv[c++])); |
822 | path_selected = TRUE; | 891 | path_selected = TRUE; |
823 | set_all_thresholds(se); | 892 | set_all_thresholds(se); |
@@ -860,51 +929,6 @@ set_all_thresholds (struct parameter_list *path) | |||
860 | set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); | 929 | set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); |
861 | } | 930 | } |
862 | 931 | ||
863 | /* TODO: Remove? | ||
864 | |||
865 | int | ||
866 | validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath) | ||
867 | { | ||
868 | if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) { | ||
869 | printf (_("INPUT ERROR: No thresholds specified")); | ||
870 | print_path (mypath); | ||
871 | return ERROR; | ||
872 | } | ||
873 | else if ((wp >= 0.0 || cp >= 0.0) && | ||
874 | (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) { | ||
875 | printf (_("\ | ||
876 | INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"), | ||
877 | cp, wp); | ||
878 | print_path (mypath); | ||
879 | return ERROR; | ||
880 | } | ||
881 | else if ((iwp >= 0.0 || icp >= 0.0) && | ||
882 | (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) { | ||
883 | printf (_("\ | ||
884 | INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"), | ||
885 | icp, iwp); | ||
886 | print_path (mypath); | ||
887 | return ERROR; | ||
888 | } | ||
889 | else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) { | ||
890 | printf (_("\ | ||
891 | INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"), | ||
892 | (unsigned long)c, (unsigned long)w); | ||
893 | print_path (mypath); | ||
894 | return ERROR; | ||
895 | } | ||
896 | |||
897 | return OK; | ||
898 | } | ||
899 | |||
900 | */ | ||
901 | |||
902 | |||
903 | |||
904 | |||
905 | |||
906 | |||
907 | |||
908 | void | 932 | void |
909 | print_help (void) | 933 | print_help (void) |
910 | { | 934 | { |
@@ -959,7 +983,7 @@ print_help (void) | |||
959 | printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); | 983 | printf (" %s\n", _("Only check local filesystems against thresholds. Yet call stat on remote filesystems")); |
960 | printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); | 984 | printf (" %s\n", _("to test if they are accessible (e.g. to detect Stale NFS Handles)")); |
961 | printf (" %s\n", "-M, --mountpoint"); | 985 | printf (" %s\n", "-M, --mountpoint"); |
962 | printf (" %s\n", _("Display the mountpoint instead of the partition")); | 986 | printf (" %s\n", _("Display the (block) device instead of the mount point")); |
963 | printf (" %s\n", "-m, --megabytes"); | 987 | printf (" %s\n", "-m, --megabytes"); |
964 | printf (" %s\n", _("Same as '--units MB'")); | 988 | printf (" %s\n", _("Same as '--units MB'")); |
965 | printf (" %s\n", "-A, --all"); | 989 | printf (" %s\n", "-A, --all"); |
@@ -972,6 +996,9 @@ print_help (void) | |||
972 | printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); | 996 | printf (" %s\n", _("Regular expression to ignore selected path/partition (case insensitive) (may be repeated)")); |
973 | printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); | 997 | printf (" %s\n", "-i, --ignore-ereg-path=PATH, --ignore-ereg-partition=PARTITION"); |
974 | printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); | 998 | printf (" %s\n", _("Regular expression to ignore selected path or partition (may be repeated)")); |
999 | printf (" %s\n", "--ignore-missing"); | ||
1000 | printf (" %s\n", _("Return OK if no filesystem matches, filesystem does not exist or is inaccessible.")); | ||
1001 | printf (" %s\n", _("(Provide this option before -p / -r / --ereg-path if used)")); | ||
975 | printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 1002 | printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
976 | printf (" %s\n", "-u, --units=STRING"); | 1003 | printf (" %s\n", "-u, --units=STRING"); |
977 | printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); | 1004 | printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); |
@@ -1000,12 +1027,12 @@ void | |||
1000 | print_usage (void) | 1027 | print_usage (void) |
1001 | { | 1028 | { |
1002 | printf ("%s\n", _("Usage:")); | 1029 | printf ("%s\n", _("Usage:")); |
1003 | printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); | 1030 | printf (" %s {-w absolute_limit |-w percentage_limit% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit% | -K inode_percentage_limit } {-p path | -x device}\n", progname); |
1004 | printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); | 1031 | printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); |
1005 | printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); | 1032 | printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); |
1006 | } | 1033 | } |
1007 | 1034 | ||
1008 | void | 1035 | bool |
1009 | stat_path (struct parameter_list *p) | 1036 | stat_path (struct parameter_list *p) |
1010 | { | 1037 | { |
1011 | /* Stat entry to check that dir exists and is accessible */ | 1038 | /* Stat entry to check that dir exists and is accessible */ |
@@ -1014,9 +1041,14 @@ stat_path (struct parameter_list *p) | |||
1014 | if (stat (p->name, &stat_buf[0])) { | 1041 | if (stat (p->name, &stat_buf[0])) { |
1015 | if (verbose >= 3) | 1042 | if (verbose >= 3) |
1016 | printf("stat failed on %s\n", p->name); | 1043 | printf("stat failed on %s\n", p->name); |
1017 | printf("DISK %s - ", _("CRITICAL")); | 1044 | if (ignore_missing == true) { |
1018 | die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); | 1045 | return false; |
1046 | } else { | ||
1047 | printf("DISK %s - ", _("CRITICAL")); | ||
1048 | die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); | ||
1049 | } | ||
1019 | } | 1050 | } |
1051 | return true; | ||
1020 | } | 1052 | } |
1021 | 1053 | ||
1022 | 1054 | ||
@@ -1036,13 +1068,20 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) { | |||
1036 | continue; | 1068 | continue; |
1037 | #endif | 1069 | #endif |
1038 | if (p_list->group && ! (strcmp(p_list->group, p->group))) { | 1070 | if (p_list->group && ! (strcmp(p_list->group, p->group))) { |
1039 | stat_path(p_list); | 1071 | if (! stat_path(p_list)) |
1072 | continue; | ||
1040 | get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); | 1073 | get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); |
1041 | get_path_stats(p_list, &tmpfsp); | 1074 | get_path_stats(p_list, &tmpfsp); |
1042 | if (verbose >= 3) | 1075 | if (verbose >= 3) |
1043 | printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", | 1076 | printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n", |
1044 | p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units, | 1077 | p_list->group, |
1045 | p_list->dtotal_units, mult); | 1078 | tmpfsp.fsu_blocks, |
1079 | tmpfsp.fsu_blocksize, | ||
1080 | p_list->best_match->me_mountdir, | ||
1081 | p_list->dused_units, | ||
1082 | p_list->dfree_units, | ||
1083 | p_list->dtotal_units, | ||
1084 | mult); | ||
1046 | 1085 | ||
1047 | /* prevent counting the first FS of a group twice since its parameter_list entry | 1086 | /* prevent counting the first FS of a group twice since its parameter_list entry |
1048 | * is used to carry the information of all file systems of the entire group */ | 1087 | * is used to carry the information of all file systems of the entire group */ |
@@ -1063,14 +1102,12 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) { | |||
1063 | first = 0; | 1102 | first = 0; |
1064 | } | 1103 | } |
1065 | if (verbose >= 3) | 1104 | if (verbose >= 3) |
1066 | printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", | 1105 | printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n", |
1067 | p->group, | 1106 | p->group, |
1068 | tmpfsp.fsu_bavail, | ||
1069 | tmpfsp.fsu_blocksize, | ||
1070 | p->best_match->me_mountdir, | ||
1071 | p->dused_units, | 1107 | p->dused_units, |
1072 | p->dfree_units, | 1108 | p->dfree_units, |
1073 | p->dtotal_units, | 1109 | p->dtotal_units, |
1110 | tmpfsp.fsu_blocksize, | ||
1074 | mult); | 1111 | mult); |
1075 | } | 1112 | } |
1076 | /* modify devname and mountdir for output */ | 1113 | /* modify devname and mountdir for output */ |
@@ -1090,7 +1127,7 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { | |||
1090 | p->available_to_root = fsp->fsu_bfree; | 1127 | p->available_to_root = fsp->fsu_bfree; |
1091 | p->used = fsp->fsu_blocks - fsp->fsu_bfree; | 1128 | p->used = fsp->fsu_blocks - fsp->fsu_bfree; |
1092 | if (freespace_ignore_reserved) { | 1129 | if (freespace_ignore_reserved) { |
1093 | /* option activated : we substract the root-reserved space from the total */ | 1130 | /* option activated : we subtract the root-reserved space from the total */ |
1094 | p->total = fsp->fsu_blocks - p->available_to_root + p->available; | 1131 | p->total = fsp->fsu_blocks - p->available_to_root + p->available; |
1095 | } else { | 1132 | } else { |
1096 | /* default behaviour : take all the blocks into account */ | 1133 | /* default behaviour : take all the blocks into account */ |
@@ -1101,11 +1138,11 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { | |||
1101 | p->dfree_units = p->available*fsp->fsu_blocksize/mult; | 1138 | p->dfree_units = p->available*fsp->fsu_blocksize/mult; |
1102 | p->dtotal_units = p->total*fsp->fsu_blocksize/mult; | 1139 | p->dtotal_units = p->total*fsp->fsu_blocksize/mult; |
1103 | /* Free file nodes. Not sure the workaround is required, but in case...*/ | 1140 | /* Free file nodes. Not sure the workaround is required, but in case...*/ |
1104 | p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail; | 1141 | p->inodes_free = fsp->fsu_ffree; |
1105 | p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ | 1142 | p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */ |
1106 | p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; | 1143 | p->inodes_used = fsp->fsu_files - fsp->fsu_ffree; |
1107 | if (freespace_ignore_reserved) { | 1144 | if (freespace_ignore_reserved) { |
1108 | /* option activated : we substract the root-reserved inodes from the total */ | 1145 | /* option activated : we subtract the root-reserved inodes from the total */ |
1109 | /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ | 1146 | /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */ |
1110 | /* for others, fsp->fsu_ffree == fsp->fsu_favail */ | 1147 | /* for others, fsp->fsu_ffree == fsp->fsu_favail */ |
1111 | p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; | 1148 | p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free; |