summaryrefslogtreecommitdiffstats
path: root/plugins/check_disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_disk.c')
-rw-r--r--plugins/check_disk.c440
1 files changed, 273 insertions, 167 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index e73a008..7dc1c4b 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -1,29 +1,29 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2*
3* Monitoring check_disk plugin 3* Monitoring check_disk plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 1999-2008 Monitoring Plugins Development Team 6* Copyright (c) 1999-2008 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
10* This file contains the check_disk plugin 10* This file contains the check_disk plugin
11* 11*
12* 12*
13* This program is free software: you can redistribute it and/or modify 13* This program is free software: you can redistribute it and/or modify
14* it under the terms of the GNU General Public License as published by 14* it under the terms of the GNU General Public License as published by
15* the Free Software Foundation, either version 3 of the License, or 15* the Free Software Foundation, either version 3 of the License, or
16* (at your option) any later version. 16* (at your option) any later version.
17* 17*
18* This program is distributed in the hope that it will be useful, 18* This program is distributed in the hope that it will be useful,
19* but WITHOUT ANY WARRANTY; without even the implied warranty of 19* but WITHOUT ANY WARRANTY; without even the implied warranty of
20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21* GNU General Public License for more details. 21* GNU General Public License for more details.
22* 22*
23* You should have received a copy of the GNU General Public License 23* You should have received a copy of the GNU General Public License
24* along with this program. If not, see <http://www.gnu.org/licenses/>. 24* along with this program. If not, see <http://www.gnu.org/licenses/>.
25* 25*
26* 26*
27*****************************************************************************/ 27*****************************************************************************/
28 28
29const char *progname = "check_disk"; 29const char *progname = "check_disk";
@@ -46,7 +46,7 @@ const char *email = "devel@monitoring-plugins.org";
46#include <stdarg.h> 46#include <stdarg.h>
47#include "fsusage.h" 47#include "fsusage.h"
48#include "mountlist.h" 48#include "mountlist.h"
49#include "intprops.h" /* necessary for TYPE_MAXIMUM */ 49#include "intprops.h" /* necessary for TYPE_MAXIMUM */
50#if HAVE_LIMITS_H 50#if HAVE_LIMITS_H
51# include <limits.h> 51# include <limits.h>
52#endif 52#endif
@@ -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
122int process_arguments (int, char **); 123int process_arguments (int, char **);
@@ -126,13 +127,10 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch
126void print_help (void); 127void print_help (void);
127void print_usage (void); 128void print_usage (void);
128double calculate_percent(uintmax_t, uintmax_t); 129double calculate_percent(uintmax_t, uintmax_t);
129void stat_path (struct parameter_list *p); 130bool stat_path (struct parameter_list *p);
130void get_stats (struct parameter_list *p, struct fs_usage *fsp); 131void get_stats (struct parameter_list *p, struct fs_usage *fsp);
131void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); 132void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
132 133
133double w_dfp = -1.0;
134double c_dfp = -1.0;
135char *path;
136char *exclude_device; 134char *exclude_device;
137char *units; 135char *units;
138uintmax_t mult = 1024 * 1024; 136uintmax_t mult = 1024 * 1024;
@@ -140,7 +138,9 @@ int verbose = 0;
140int erronly = FALSE; 138int erronly = FALSE;
141int display_mntp = FALSE; 139int display_mntp = FALSE;
142int exact_match = FALSE; 140int exact_match = FALSE;
141bool ignore_missing = false;
143int freespace_ignore_reserved = FALSE; 142int freespace_ignore_reserved = FALSE;
143int display_inodes_perfdata = FALSE;
144char *warn_freespace_units = NULL; 144char *warn_freespace_units = NULL;
145char *crit_freespace_units = NULL; 145char *crit_freespace_units = NULL;
146char *warn_freespace_percent = NULL; 146char *warn_freespace_percent = NULL;
@@ -154,6 +154,7 @@ char *crit_usedinodes_percent = NULL;
154char *warn_freeinodes_percent = NULL; 154char *warn_freeinodes_percent = NULL;
155char *crit_freeinodes_percent = NULL; 155char *crit_freeinodes_percent = NULL;
156int path_selected = FALSE; 156int path_selected = FALSE;
157bool path_ignored = false;
157char *group = NULL; 158char *group = NULL;
158struct stat *stat_buf; 159struct stat *stat_buf;
159struct name_list *seen = NULL; 160struct name_list *seen = NULL;
@@ -165,13 +166,13 @@ main (int argc, char **argv)
165 int result = STATE_UNKNOWN; 166 int result = STATE_UNKNOWN;
166 int disk_result = STATE_UNKNOWN; 167 int disk_result = STATE_UNKNOWN;
167 char *output; 168 char *output;
169 char *ignored;
168 char *details; 170 char *details;
169 char *perf; 171 char *perf;
170 char *preamble; 172 char *perf_ilabel;
173 char *preamble = " - free space:";
174 char *ignored_preamble = " - ignored paths:";
171 char *flag_header; 175 char *flag_header;
172 double inode_space_pct;
173 double warning_high_tide;
174 double critical_high_tide;
175 int temp_result; 176 int temp_result;
176 177
177 struct mount_entry *me; 178 struct mount_entry *me;
@@ -182,10 +183,11 @@ 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 ("");
190 perf_ilabel = strdup ("");
189 stat_buf = malloc(sizeof *stat_buf); 191 stat_buf = malloc(sizeof *stat_buf);
190 192
191 setlocale (LC_ALL, ""); 193 setlocale (LC_ALL, "");
@@ -203,7 +205,7 @@ main (int argc, char **argv)
203 /* If a list of paths has not been selected, find entire 205 /* If a list of paths has not been selected, find entire
204 mount list and create list of paths 206 mount list and create list of paths
205 */ 207 */
206 if (path_selected == FALSE) { 208 if (path_selected == FALSE && path_ignored == false) {
207 for (me = mount_list; me; me = me->me_next) { 209 for (me = mount_list; me; me = me->me_next) {
208 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { 210 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
209 path = np_add_parameter(&path_select_list, me->me_mountdir); 211 path = np_add_parameter(&path_select_list, me->me_mountdir);
@@ -213,24 +215,49 @@ main (int argc, char **argv)
213 set_all_thresholds(path); 215 set_all_thresholds(path);
214 } 216 }
215 } 217 }
216 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 }
217 222
218 /* Error if no match found for specified paths */ 223 /* Error if no match found for specified paths */
219 temp_list = path_select_list; 224 temp_list = path_select_list;
220 225
221 while (temp_list) { 226 while (path_select_list) {
222 if (! temp_list->best_match) { 227 if (! path_select_list->best_match && ignore_missing == true) {
223 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;
224 } 242 }
243 }
244
245 path_select_list = temp_list;
225 246
226 temp_list = temp_list->name_next; 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 }
227 } 252 }
228 253
229 /* Process for every path in list */ 254 /* Process for every path in list */
230 for (path = path_select_list; path; path=path->name_next) { 255 for (path = path_select_list; path; path=path->name_next) {
231 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)
232 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",
233 path->freespace_percent->critical->end); 258 path->name,
259 path->freespace_percent->warning->end,
260 path->freespace_percent->critical->end);
234 261
235 if (verbose >= 3 && path->group != NULL) 262 if (verbose >= 3 && path->group != NULL)
236 printf("Group of %s: %s\n",path->name,path->group); 263 printf("Group of %s: %s\n",path->name,path->group);
@@ -240,26 +267,34 @@ main (int argc, char **argv)
240 267
241 me = path->best_match; 268 me = path->best_match;
242 269
270 if (!me) {
271 continue;
272 }
273
243#ifdef __CYGWIN__ 274#ifdef __CYGWIN__
244 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 275 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
245 continue; 276 continue;
246 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); 277 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10);
247 if (GetDriveType(mountdir) != DRIVE_FIXED) 278 if (GetDriveType(mountdir) != DRIVE_FIXED)
248 me->me_remote = 1; 279 me->me_remote = 1;
249#endif 280#endif
250 /* Filters */ 281 /* Filters */
251 282
252 /* Remove filesystems already seen */ 283 /* Remove filesystems already seen */
253 if (np_seen_name(seen, me->me_mountdir)) { 284 if (np_seen_name(seen, me->me_mountdir)) {
254 continue; 285 continue;
255 } 286 }
256 np_add_name(&seen, me->me_mountdir); 287 np_add_name(&seen, me->me_mountdir);
257 288
258 if (path->group == NULL) { 289 if (path->group == NULL) {
259 /* Skip remote filesystems if we're not interested in them */ 290 /* Skip remote filesystems if we're not interested in them */
260 if (me->me_remote && show_local_fs) { 291 if (me->me_remote && show_local_fs) {
261 if (stat_remote_fs) 292 if (stat_remote_fs) {
262 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 }
263 continue; 298 continue;
264 /* 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 */
265 } else if (me->me_dummy && !show_all_fs) { 300 } else if (me->me_dummy && !show_all_fs) {
@@ -278,15 +313,30 @@ main (int argc, char **argv)
278 } 313 }
279 } 314 }
280 315
281 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 }
282 get_fs_usage (me->me_mountdir, me->me_devname, &fsp); 323 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
283 324
284 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { 325 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
285 get_stats (path, &fsp); 326 get_stats (path, &fsp);
286 327
287 if (verbose >= 3) { 328 if (verbose >= 3) {
288 printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g 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",
289 me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult); 330 me->me_mountdir,
331 path->dused_pct,
332 path->dfree_pct,
333 path->dused_units,
334 path->dfree_units,
335 path->dtotal_units,
336 path->dused_inodes_percent,
337 path->dfree_inodes_percent,
338 fsp.fsu_blocksize,
339 mult);
290 } 340 }
291 341
292 /* Threshold comparisons */ 342 /* Threshold comparisons */
@@ -323,68 +373,89 @@ main (int argc, char **argv)
323 */ 373 */
324 374
325 /* *_high_tide must be reinitialized at each run */ 375 /* *_high_tide must be reinitialized at each run */
326 warning_high_tide = UINT_MAX; 376 uint64_t warning_high_tide = UINT64_MAX;
327 critical_high_tide = UINT_MAX;
328 377
329 if (path->freespace_units->warning != NULL) { 378 if (path->freespace_units->warning != NULL) {
330 warning_high_tide = path->dtotal_units - path->freespace_units->warning->end; 379 warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult;
331 } 380 }
332 if (path->freespace_percent->warning != NULL) { 381 if (path->freespace_percent->warning != NULL) {
333 warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freespace_percent->warning->end/100)*path->dtotal_units )); 382 warning_high_tide = min( warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end/100) * (path->dtotal_units * mult)) );
334 } 383 }
384
385 uint64_t critical_high_tide = UINT64_MAX;
386
335 if (path->freespace_units->critical != NULL) { 387 if (path->freespace_units->critical != NULL) {
336 critical_high_tide = path->dtotal_units - path->freespace_units->critical->end; 388 critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult;
337 } 389 }
338 if (path->freespace_percent->critical != NULL) { 390 if (path->freespace_percent->critical != NULL) {
339 critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freespace_percent->critical->end/100)*path->dtotal_units )); 391 critical_high_tide = min( critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end/100) * (path->dtotal_units * mult)) );
340 } 392 }
341 393
342 /* Nb: *_high_tide are unset when == UINT_MAX */ 394 /* Nb: *_high_tide are unset when == UINT64_MAX */
343 xasprintf (&perf, "%s %s", perf, 395 xasprintf (&perf, "%s %s", perf,
344 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 396 perfdata_uint64 (
345 path->dused_units, units, 397 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
346 (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide, 398 path->dused_units * mult, "B",
347 (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide, 399 (warning_high_tide == UINT64_MAX ? FALSE : TRUE), warning_high_tide,
348 TRUE, 0, 400 (critical_high_tide == UINT64_MAX ? FALSE : TRUE), critical_high_tide,
349 TRUE, path->dtotal_units)); 401 TRUE, 0,
402 TRUE, path->dtotal_units * mult));
403
404 if (display_inodes_perfdata) {
405 /* *_high_tide must be reinitialized at each run */
406 warning_high_tide = UINT64_MAX;
407 critical_high_tide = UINT64_MAX;
408
409 if (path->freeinodes_percent->warning != NULL) {
410 warning_high_tide = (uint64_t) fabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total ));
411 }
412 if (path->freeinodes_percent->critical != NULL) {
413 critical_high_tide = (uint64_t) fabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total ));
414 }
415
416 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir);
417 /* Nb: *_high_tide are unset when == UINT64_MAX */
418 xasprintf (&perf, "%s %s", perf,
419 perfdata_uint64 (perf_ilabel,
420 path->inodes_used, "",
421 (warning_high_tide != UINT64_MAX ? TRUE : FALSE), warning_high_tide,
422 (critical_high_tide != UINT64_MAX ? TRUE : FALSE), critical_high_tide,
423 TRUE, 0,
424 TRUE, path->inodes_total));
425 }
350 426
351 if (disk_result==STATE_OK && erronly && !verbose) 427 if (disk_result==STATE_OK && erronly && !verbose)
352 continue; 428 continue;
353 429
354 if(disk_result && verbose >= 1) { 430 if(disk_result && verbose >= 1) {
355 xasprintf(&flag_header, " %s [", state_text (disk_result)); 431 xasprintf(&flag_header, " %s [", state_text (disk_result));
356 } else { 432 } else {
357 xasprintf(&flag_header, ""); 433 xasprintf(&flag_header, "");
358 } 434 }
359 xasprintf (&output, "%s%s %s %.0f %s (%.0f%%", 435 xasprintf (&output, "%s%s %s %llu%s (%.0f%%",
360 output, flag_header, 436 output, flag_header,
361 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 437 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
362 path->dfree_units, 438 path->dfree_units,
363 units, 439 units,
364 path->dfree_pct); 440 path->dfree_pct);
365 if (path->dused_inodes_percent < 0) { 441 if (path->dused_inodes_percent < 0) {
366 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); 442 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : ""));
367 } else { 443 } else {
368 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) ? "]" : ""));
369 } 445 }
370 free(flag_header); 446 free(flag_header);
371 /* TODO: Need to do a similar debug line
372 xasprintf (&details, _("%s\n\
373%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
374 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
375 me->me_devname, me->me_type, me->me_mountdir,
376 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
377 */
378
379 } 447 }
380
381 } 448 }
382 449
383 if (verbose >= 2) 450 if (verbose >= 2)
384 xasprintf (&output, "%s%s", output, details); 451 xasprintf (&output, "%s%s", output, details);
385 452
453 if (strcmp(output, "") == 0 && ! erronly) {
454 preamble = "";
455 xasprintf (&output, " - No disks were found for provided parameters;");
456 }
386 457
387 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);
388 return result; 459 return result;
389} 460}
390 461
@@ -453,8 +524,10 @@ process_arguments (int argc, char **argv)
453 {"ignore-ereg-partition", required_argument, 0, 'i'}, 524 {"ignore-ereg-partition", required_argument, 0, 'i'},
454 {"ignore-eregi-path", required_argument, 0, 'I'}, 525 {"ignore-eregi-path", required_argument, 0, 'I'},
455 {"ignore-eregi-partition", required_argument, 0, 'I'}, 526 {"ignore-eregi-partition", required_argument, 0, 'I'},
527 {"ignore-missing", no_argument, 0, IGNORE_MISSING},
456 {"local", no_argument, 0, 'l'}, 528 {"local", no_argument, 0, 'l'},
457 {"stat-remote-fs", no_argument, 0, 'L'}, 529 {"stat-remote-fs", no_argument, 0, 'L'},
530 {"iperfdata", no_argument, 0, 'P'},
458 {"mountpoint", no_argument, 0, 'M'}, 531 {"mountpoint", no_argument, 0, 'M'},
459 {"errors-only", no_argument, 0, 'e'}, 532 {"errors-only", no_argument, 0, 'e'},
460 {"exact-match", no_argument, 0, 'E'}, 533 {"exact-match", no_argument, 0, 'E'},
@@ -477,7 +550,7 @@ process_arguments (int argc, char **argv)
477 strcpy (argv[c], "-t"); 550 strcpy (argv[c], "-t");
478 551
479 while (1) { 552 while (1) {
480 c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLg:R:r:i:I:MEA", longopts, &option); 553 c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEA", longopts, &option);
481 554
482 if (c == -1 || c == EOF) 555 if (c == -1 || c == EOF)
483 break; 556 break;
@@ -511,7 +584,7 @@ process_arguments (int argc, char **argv)
511 584
512 /* Awful mistake where the range values do not make sense. Normally, 585 /* Awful mistake where the range values do not make sense. Normally,
513 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
514 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
515 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
516 */ 589 */
517 case 'c': /* critical threshold */ 590 case 'c': /* critical threshold */
@@ -530,14 +603,14 @@ process_arguments (int argc, char **argv)
530 } 603 }
531 break; 604 break;
532 605
533 case 'W': /* warning inode threshold */ 606 case 'W': /* warning inode threshold */
534 if (*optarg == '@') { 607 if (*optarg == '@') {
535 warn_freeinodes_percent = optarg; 608 warn_freeinodes_percent = optarg;
536 } else { 609 } else {
537 xasprintf(&warn_freeinodes_percent, "@%s", optarg); 610 xasprintf(&warn_freeinodes_percent, "@%s", optarg);
538 } 611 }
539 break; 612 break;
540 case 'K': /* critical inode threshold */ 613 case 'K': /* critical inode threshold */
541 if (*optarg == '@') { 614 if (*optarg == '@') {
542 crit_freeinodes_percent = optarg; 615 crit_freeinodes_percent = optarg;
543 } else { 616 } else {
@@ -547,21 +620,39 @@ process_arguments (int argc, char **argv)
547 case 'u': 620 case 'u':
548 if (units) 621 if (units)
549 free(units); 622 free(units);
550 if (! strcmp (optarg, "bytes")) { 623 if (! strcasecmp (optarg, "bytes")) {
551 mult = (uintmax_t)1; 624 mult = (uintmax_t)1;
552 units = strdup ("B"); 625 units = strdup ("B");
553 } else if (! strcmp (optarg, "kB")) { 626 } else if (!strcmp(optarg, "KiB")) {
554 mult = (uintmax_t)1024; 627 mult = (uintmax_t)1024;
628 units = strdup ("KiB");
629 } else if (! strcmp (optarg, "kB")) {
630 mult = (uintmax_t)1000;
555 units = strdup ("kB"); 631 units = strdup ("kB");
556 } else if (! strcmp (optarg, "MB")) { 632 } else if (!strcmp(optarg, "MiB")) {
557 mult = (uintmax_t)1024 * 1024; 633 mult = (uintmax_t)1024 * 1024;
634 units = strdup ("MiB");
635 } else if (! strcmp (optarg, "MB")) {
636 mult = (uintmax_t)1000 * 1000;
558 units = strdup ("MB"); 637 units = strdup ("MB");
559 } else if (! strcmp (optarg, "GB")) { 638 } else if (!strcmp(optarg, "GiB")) {
560 mult = (uintmax_t)1024 * 1024 * 1024; 639 mult = (uintmax_t)1024 * 1024 * 1024;
640 units = strdup ("GiB");
641 } else if (! strcmp (optarg, "GB")){
642 mult = (uintmax_t)1000 * 1000 * 1000;
561 units = strdup ("GB"); 643 units = strdup ("GB");
562 } else if (! strcmp (optarg, "TB")) { 644 } else if (!strcmp(optarg, "TiB")) {
563 mult = (uintmax_t)1024 * 1024 * 1024 * 1024; 645 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
646 units = strdup ("TiB");
647 } else if (! strcmp (optarg, "TB")) {
648 mult = (uintmax_t)1000 * 1000 * 1000 * 1000;
564 units = strdup ("TB"); 649 units = strdup ("TB");
650 } else if (!strcmp(optarg, "PiB")) {
651 mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024;
652 units = strdup ("PiB");
653 } else if (! strcmp (optarg, "PB")){
654 mult = (uintmax_t)1000 * 1000 * 1000 * 1000 * 1000;
655 units = strdup ("PB");
565 } else { 656 } else {
566 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); 657 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
567 } 658 }
@@ -572,19 +663,23 @@ process_arguments (int argc, char **argv)
572 mult = 1024; 663 mult = 1024;
573 if (units) 664 if (units)
574 free(units); 665 free(units);
575 units = strdup ("kB"); 666 units = strdup ("kiB");
576 break; 667 break;
577 case 'm': /* display mountpoint */ 668 case 'm': /* display mountpoint */
578 mult = 1024 * 1024; 669 mult = 1024 * 1024;
579 if (units) 670 if (units)
580 free(units); 671 free(units);
581 units = strdup ("MB"); 672 units = strdup ("MiB");
582 break; 673 break;
583 case 'L': 674 case 'L':
584 stat_remote_fs = 1; 675 stat_remote_fs = 1;
676 /* fallthrough */
585 case 'l': 677 case 'l':
586 show_local_fs = 1; 678 show_local_fs = 1;
587 break; 679 break;
680 case 'P':
681 display_inodes_perfdata = 1;
682 break;
588 case 'p': /* select path */ 683 case 'p': /* select path */
589 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 684 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
590 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 685 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
@@ -596,12 +691,19 @@ process_arguments (int argc, char **argv)
596 /* 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 */
597 if (! (se = np_find_parameter(path_select_list, optarg))) { 692 if (! (se = np_find_parameter(path_select_list, optarg))) {
598 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 }
599 } 699 }
600 se->group = group; 700 se->group = group;
601 set_all_thresholds(se); 701 set_all_thresholds(se);
602 702
603 /* 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 */
604 stat_path(se); 704 if (!stat_path(se)) {
705 break;
706 }
605 /* 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
606 * 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
607 * 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 */
@@ -644,6 +746,7 @@ process_arguments (int argc, char **argv)
644 break; 746 break;
645 case 'I': 747 case 'I':
646 cflags |= REG_ICASE; 748 cflags |= REG_ICASE;
749 // Intentional fallthrough
647 case 'i': 750 case 'i':
648 if (!path_selected) 751 if (!path_selected)
649 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"));
@@ -681,16 +784,21 @@ process_arguments (int argc, char **argv)
681 cflags = default_cflags; 784 cflags = default_cflags;
682 break; 785 break;
683 786
787 case IGNORE_MISSING:
788 ignore_missing = true;
789 break;
684 case 'A': 790 case 'A':
685 optarg = strdup(".*"); 791 optarg = strdup(".*");
792 // Intentional fallthrough
686 case 'R': 793 case 'R':
687 cflags |= REG_ICASE; 794 cflags |= REG_ICASE;
795 // Intentional fallthrough
688 case 'r': 796 case 'r':
689 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 797 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
690 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 798 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
691 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent || 799 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
692 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) { 800 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) {
693 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R\n")); 801 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n"));
694 } 802 }
695 803
696 err = regcomp(&re, optarg, cflags); 804 err = regcomp(&re, optarg, cflags);
@@ -714,7 +822,11 @@ process_arguments (int argc, char **argv)
714 } 822 }
715 } 823 }
716 824
717 if (!fnd) 825 if (!fnd && ignore_missing == true) {
826 path_ignored = true;
827 /* path_selected = TRUE;*/
828 break;
829 } else if (!fnd)
718 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), 830 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
719 _("Regular expression did not match any path or disk"), optarg); 831 _("Regular expression did not match any path or disk"), optarg);
720 832
@@ -774,14 +886,14 @@ process_arguments (int argc, char **argv)
774 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c])) 886 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
775 crit_usedspace_percent = argv[c++]; 887 crit_usedspace_percent = argv[c++];
776 888
777 if (argc > c && path == NULL) { 889 if (argc > c) {
778 se = np_add_parameter(&path_select_list, strdup(argv[c++])); 890 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
779 path_selected = TRUE; 891 path_selected = TRUE;
780 set_all_thresholds(se); 892 set_all_thresholds(se);
781 } 893 }
782 894
783 if (units == NULL) { 895 if (units == NULL) {
784 units = strdup ("MB"); 896 units = strdup ("MiB");
785 mult = (uintmax_t)1024 * 1024; 897 mult = (uintmax_t)1024 * 1024;
786 } 898 }
787 899
@@ -817,51 +929,6 @@ set_all_thresholds (struct parameter_list *path)
817 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); 929 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
818} 930}
819 931
820/* TODO: Remove?
821
822int
823validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
824{
825 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
826 printf (_("INPUT ERROR: No thresholds specified"));
827 print_path (mypath);
828 return ERROR;
829 }
830 else if ((wp >= 0.0 || cp >= 0.0) &&
831 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
832 printf (_("\
833INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
834 cp, wp);
835 print_path (mypath);
836 return ERROR;
837 }
838 else if ((iwp >= 0.0 || icp >= 0.0) &&
839 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
840 printf (_("\
841INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
842 icp, iwp);
843 print_path (mypath);
844 return ERROR;
845 }
846 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
847 printf (_("\
848INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
849 (unsigned long)c, (unsigned long)w);
850 print_path (mypath);
851 return ERROR;
852 }
853
854 return OK;
855}
856
857*/
858
859
860
861
862
863
864
865void 932void
866print_help (void) 933print_help (void)
867{ 934{
@@ -904,6 +971,8 @@ print_help (void)
904 printf (" %s\n", _("Display only devices/mountpoints with errors")); 971 printf (" %s\n", _("Display only devices/mountpoints with errors"));
905 printf (" %s\n", "-f, --freespace-ignore-reserved"); 972 printf (" %s\n", "-f, --freespace-ignore-reserved");
906 printf (" %s\n", _("Don't account root-reserved blocks into freespace in perfdata")); 973 printf (" %s\n", _("Don't account root-reserved blocks into freespace in perfdata"));
974 printf (" %s\n", "-P, --iperfdata");
975 printf (" %s\n", _("Display inode usage in perfdata"));
907 printf (" %s\n", "-g, --group=NAME"); 976 printf (" %s\n", "-g, --group=NAME");
908 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); 977 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together"));
909 printf (" %s\n", "-k, --kilobytes"); 978 printf (" %s\n", "-k, --kilobytes");
@@ -914,7 +983,7 @@ print_help (void)
914 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"));
915 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)"));
916 printf (" %s\n", "-M, --mountpoint"); 985 printf (" %s\n", "-M, --mountpoint");
917 printf (" %s\n", _("Display the mountpoint instead of the partition")); 986 printf (" %s\n", _("Display the (block) device instead of the mount point"));
918 printf (" %s\n", "-m, --megabytes"); 987 printf (" %s\n", "-m, --megabytes");
919 printf (" %s\n", _("Same as '--units MB'")); 988 printf (" %s\n", _("Same as '--units MB'"));
920 printf (" %s\n", "-A, --all"); 989 printf (" %s\n", "-A, --all");
@@ -927,6 +996,9 @@ print_help (void)
927 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)"));
928 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");
929 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)"));
930 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1002 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
931 printf (" %s\n", "-u, --units=STRING"); 1003 printf (" %s\n", "-u, --units=STRING");
932 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); 1004 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -937,12 +1009,20 @@ print_help (void)
937 printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)")); 1009 printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)"));
938 1010
939 printf ("\n"); 1011 printf ("\n");
1012 printf ("%s\n", _("General usage hints:"));
1013 printf (" %s\n", _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as"));
1014 printf (" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."));
1015 printf (" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} {thresholds b} ...\""));
1016
1017
1018
1019 printf ("\n");
940 printf ("%s\n", _("Examples:")); 1020 printf ("%s\n", _("Examples:"));
941 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /"); 1021 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
942 printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB")); 1022 printf (" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
943 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); 1023 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'");
944 printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); 1024 printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex"));
945 printf (" %s\n", _("are grouped which means the freespace thresholds are applied to all disks together")); 1025 printf (" %s\n\n", _("are grouped which means the freespace thresholds are applied to all disks together"));
946 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar"); 1026 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar");
947 printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); 1027 printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M"));
948 1028
@@ -955,12 +1035,12 @@ void
955print_usage (void) 1035print_usage (void)
956{ 1036{
957 printf ("%s\n", _("Usage:")); 1037 printf ("%s\n", _("Usage:"));
958 printf (" %s -w limit -c limit [-W limit] [-K limit] {-p path | -x device}\n", progname); 1038 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);
959 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 1039 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
960 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 1040 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
961} 1041}
962 1042
963void 1043bool
964stat_path (struct parameter_list *p) 1044stat_path (struct parameter_list *p)
965{ 1045{
966 /* Stat entry to check that dir exists and is accessible */ 1046 /* Stat entry to check that dir exists and is accessible */
@@ -969,9 +1049,14 @@ stat_path (struct parameter_list *p)
969 if (stat (p->name, &stat_buf[0])) { 1049 if (stat (p->name, &stat_buf[0])) {
970 if (verbose >= 3) 1050 if (verbose >= 3)
971 printf("stat failed on %s\n", p->name); 1051 printf("stat failed on %s\n", p->name);
972 printf("DISK %s - ", _("CRITICAL")); 1052 if (ignore_missing == true) {
973 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno)); 1053 return false;
1054 } else {
1055 printf("DISK %s - ", _("CRITICAL"));
1056 die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
1057 }
974 } 1058 }
1059 return true;
975} 1060}
976 1061
977 1062
@@ -991,66 +1076,87 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
991 continue; 1076 continue;
992#endif 1077#endif
993 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 1078 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
994 stat_path(p_list); 1079 if (! stat_path(p_list))
1080 continue;
995 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); 1081 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
996 get_path_stats(p_list, &tmpfsp); 1082 get_path_stats(p_list, &tmpfsp);
997 if (verbose >= 3) 1083 if (verbose >= 3)
998 printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1084 printf("Group %s: adding %lu blocks sized %lu, (%s) used_units=%lu free_units=%lu total_units=%lu mult=%lu\n",
999 p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units, 1085 p_list->group,
1000 p_list->dtotal_units, mult); 1086 tmpfsp.fsu_blocks,
1001 1087 tmpfsp.fsu_blocksize,
1002 /* prevent counting the first FS of a group twice since its parameter_list entry 1088 p_list->best_match->me_mountdir,
1089 p_list->dused_units,
1090 p_list->dfree_units,
1091 p_list->dtotal_units,
1092 mult);
1093
1094 /* prevent counting the first FS of a group twice since its parameter_list entry
1003 * is used to carry the information of all file systems of the entire group */ 1095 * is used to carry the information of all file systems of the entire group */
1004 if (! first) { 1096 if (! first) {
1005 p->total += p_list->total; 1097 p->total += p_list->total;
1006 p->available += p_list->available; 1098 p->available += p_list->available;
1007 p->available_to_root += p_list->available_to_root; 1099 p->available_to_root += p_list->available_to_root;
1008 p->used += p_list->used; 1100 p->used += p_list->used;
1009 1101
1010 p->dused_units += p_list->dused_units; 1102 p->dused_units += p_list->dused_units;
1011 p->dfree_units += p_list->dfree_units; 1103 p->dfree_units += p_list->dfree_units;
1012 p->dtotal_units += p_list->dtotal_units; 1104 p->dtotal_units += p_list->dtotal_units;
1013 p->inodes_total += p_list->inodes_total; 1105 p->inodes_total += p_list->inodes_total;
1014 p->inodes_free += p_list->inodes_free; 1106 p->inodes_free += p_list->inodes_free;
1107 p->inodes_free_to_root += p_list->inodes_free_to_root;
1108 p->inodes_used += p_list->inodes_used;
1015 } 1109 }
1016 first = 0; 1110 first = 0;
1017 } 1111 }
1018 if (verbose >= 3) 1112 if (verbose >= 3)
1019 printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1113 printf("Group %s now has: used_units=%lu free_units=%lu total_units=%lu fsu_blocksize=%lu mult=%lu\n",
1020 p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units, 1114 p->group,
1021 p->dfree_units, p->dtotal_units, mult); 1115 p->dused_units,
1116 p->dfree_units,
1117 p->dtotal_units,
1118 tmpfsp.fsu_blocksize,
1119 mult);
1022 } 1120 }
1023 /* modify devname and mountdir for output */ 1121 /* modify devname and mountdir for output */
1024 p->best_match->me_mountdir = p->best_match->me_devname = p->group; 1122 p->best_match->me_mountdir = p->best_match->me_devname = p->group;
1025 } 1123 }
1026 /* finally calculate percentages for either plain FS or summed up group */ 1124 /* finally calculate percentages for either plain FS or summed up group */
1027 p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */ 1125 p->dused_pct = calculate_percent( p->used, p->used + p->available ); /* used + available can never be > uintmax */
1028 p->dfree_pct = 100 - p->dused_pct; 1126 p->dfree_pct = 100 - p->dused_pct;
1029 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); 1127 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total);
1030 p->dfree_inodes_percent = 100 - p->dused_inodes_percent; 1128 p->dfree_inodes_percent = 100 - p->dused_inodes_percent;
1031 1129
1032} 1130}
1033 1131
1034void 1132void
1035get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { 1133get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1036 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available 1134 p->available = fsp->fsu_bavail;
1037 * space on BSD (the actual value should be negative but fsp->fsu_bavail
1038 * is unsigned) */
1039 p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail;
1040 p->available_to_root = fsp->fsu_bfree; 1135 p->available_to_root = fsp->fsu_bfree;
1041 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1136 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1042 if (freespace_ignore_reserved) { 1137 if (freespace_ignore_reserved) {
1043 /* option activated : we substract the root-reserved space from the total */ 1138 /* option activated : we subtract the root-reserved space from the total */
1044 p->total = fsp->fsu_blocks - p->available_to_root + p->available; 1139 p->total = fsp->fsu_blocks - p->available_to_root + p->available;
1045 } else { 1140 } else {
1046 /* default behaviour : take all the blocks into account */ 1141 /* default behaviour : take all the blocks into account */
1047 p->total = fsp->fsu_blocks; 1142 p->total = fsp->fsu_blocks;
1048 } 1143 }
1049 1144
1050 p->dused_units = p->used*fsp->fsu_blocksize/mult; 1145 p->dused_units = p->used*fsp->fsu_blocksize/mult;
1051 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1146 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1052 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1147 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1053 p->inodes_total = fsp->fsu_files; /* Total file nodes. */ 1148 /* Free file nodes. Not sure the workaround is required, but in case...*/
1054 p->inodes_free = fsp->fsu_ffree; /* Free file nodes. */ 1149 p->inodes_free = fsp->fsu_ffree;
1150 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1151 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1152 if (freespace_ignore_reserved) {
1153 /* option activated : we subtract the root-reserved inodes from the total */
1154 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */
1155 /* for others, fsp->fsu_ffree == fsp->fsu_favail */
1156 p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free;
1157 } else {
1158 /* default behaviour : take all the inodes into account */
1159 p->inodes_total = fsp->fsu_files;
1160 }
1055 np_add_name(&seen, p->best_match->me_mountdir); 1161 np_add_name(&seen, p->best_match->me_mountdir);
1056} 1162}