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.c449
1 files changed, 275 insertions, 174 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 874a0ee..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
@@ -58,9 +58,6 @@ const char *email = "devel@monitoring-plugins.org";
58# define ERROR -1 58# define ERROR -1
59#endif 59#endif
60 60
61/* If nonzero, show inode information. */
62static int inode_format = 1;
63
64/* If nonzero, show even filesystems with zero size or 61/* If nonzero, show even filesystems with zero size or
65 uninteresting types. */ 62 uninteresting types. */
66static int show_all_fs = 1; 63static int show_all_fs = 1;
@@ -115,11 +112,12 @@ enum
115{ 112{
116 SYNC_OPTION = CHAR_MAX + 1, 113 SYNC_OPTION = CHAR_MAX + 1,
117 NO_SYNC_OPTION, 114 NO_SYNC_OPTION,
118 BLOCK_SIZE_OPTION 115 BLOCK_SIZE_OPTION,
116 IGNORE_MISSING
119}; 117};
120 118
121#ifdef _AIX 119#ifdef _AIX
122 #pragma alloca 120#pragma alloca
123#endif 121#endif
124 122
125int process_arguments (int, char **); 123int process_arguments (int, char **);
@@ -129,13 +127,10 @@ int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, ch
129void print_help (void); 127void print_help (void);
130void print_usage (void); 128void print_usage (void);
131double calculate_percent(uintmax_t, uintmax_t); 129double calculate_percent(uintmax_t, uintmax_t);
132void stat_path (struct parameter_list *p); 130bool stat_path (struct parameter_list *p);
133void get_stats (struct parameter_list *p, struct fs_usage *fsp); 131void get_stats (struct parameter_list *p, struct fs_usage *fsp);
134void get_path_stats (struct parameter_list *p, struct fs_usage *fsp); 132void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
135 133
136double w_dfp = -1.0;
137double c_dfp = -1.0;
138char *path;
139char *exclude_device; 134char *exclude_device;
140char *units; 135char *units;
141uintmax_t mult = 1024 * 1024; 136uintmax_t mult = 1024 * 1024;
@@ -143,7 +138,9 @@ int verbose = 0;
143int erronly = FALSE; 138int erronly = FALSE;
144int display_mntp = FALSE; 139int display_mntp = FALSE;
145int exact_match = FALSE; 140int exact_match = FALSE;
141bool ignore_missing = false;
146int freespace_ignore_reserved = FALSE; 142int freespace_ignore_reserved = FALSE;
143int display_inodes_perfdata = FALSE;
147char *warn_freespace_units = NULL; 144char *warn_freespace_units = NULL;
148char *crit_freespace_units = NULL; 145char *crit_freespace_units = NULL;
149char *warn_freespace_percent = NULL; 146char *warn_freespace_percent = NULL;
@@ -157,6 +154,7 @@ char *crit_usedinodes_percent = NULL;
157char *warn_freeinodes_percent = NULL; 154char *warn_freeinodes_percent = NULL;
158char *crit_freeinodes_percent = NULL; 155char *crit_freeinodes_percent = NULL;
159int path_selected = FALSE; 156int path_selected = FALSE;
157bool path_ignored = false;
160char *group = NULL; 158char *group = NULL;
161struct stat *stat_buf; 159struct stat *stat_buf;
162struct name_list *seen = NULL; 160struct name_list *seen = NULL;
@@ -168,27 +166,28 @@ main (int argc, char **argv)
168 int result = STATE_UNKNOWN; 166 int result = STATE_UNKNOWN;
169 int disk_result = STATE_UNKNOWN; 167 int disk_result = STATE_UNKNOWN;
170 char *output; 168 char *output;
169 char *ignored;
171 char *details; 170 char *details;
172 char *perf; 171 char *perf;
173 char *preamble; 172 char *perf_ilabel;
173 char *preamble = " - free space:";
174 char *ignored_preamble = " - ignored paths:";
174 char *flag_header; 175 char *flag_header;
175 double inode_space_pct;
176 double warning_high_tide;
177 double critical_high_tide;
178 int temp_result; 176 int temp_result;
179 177
180 struct mount_entry *me; 178 struct mount_entry *me;
181 struct fs_usage fsp, tmpfsp; 179 struct fs_usage fsp;
182 struct parameter_list *temp_list, *path; 180 struct parameter_list *temp_list, *path;
183 181
184#ifdef __CYGWIN__ 182#ifdef __CYGWIN__
185 char mountdir[32]; 183 char mountdir[32];
186#endif 184#endif
187 185
188 preamble = strdup (" - free space:");
189 output = strdup (""); 186 output = strdup ("");
187 ignored = strdup ("");
190 details = strdup (""); 188 details = strdup ("");
191 perf = strdup (""); 189 perf = strdup ("");
190 perf_ilabel = strdup ("");
192 stat_buf = malloc(sizeof *stat_buf); 191 stat_buf = malloc(sizeof *stat_buf);
193 192
194 setlocale (LC_ALL, ""); 193 setlocale (LC_ALL, "");
@@ -206,7 +205,7 @@ main (int argc, char **argv)
206 /* If a list of paths has not been selected, find entire 205 /* If a list of paths has not been selected, find entire
207 mount list and create list of paths 206 mount list and create list of paths
208 */ 207 */
209 if (path_selected == FALSE) { 208 if (path_selected == FALSE && path_ignored == false) {
210 for (me = mount_list; me; me = me->me_next) { 209 for (me = mount_list; me; me = me->me_next) {
211 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) { 210 if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
212 path = np_add_parameter(&path_select_list, me->me_mountdir); 211 path = np_add_parameter(&path_select_list, me->me_mountdir);
@@ -216,24 +215,49 @@ main (int argc, char **argv)
216 set_all_thresholds(path); 215 set_all_thresholds(path);
217 } 216 }
218 } 217 }
219 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 }
220 222
221 /* Error if no match found for specified paths */ 223 /* Error if no match found for specified paths */
222 temp_list = path_select_list; 224 temp_list = path_select_list;
223 225
224 while (temp_list) { 226 while (path_select_list) {
225 if (! temp_list->best_match) { 227 if (! path_select_list->best_match && ignore_missing == true) {
226 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;
227 } 242 }
243 }
244
245 path_select_list = temp_list;
228 246
229 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 }
230 } 252 }
231 253
232 /* Process for every path in list */ 254 /* Process for every path in list */
233 for (path = path_select_list; path; path=path->name_next) { 255 for (path = path_select_list; path; path=path->name_next) {
234 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)
235 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",
236 path->freespace_percent->critical->end); 258 path->name,
259 path->freespace_percent->warning->end,
260 path->freespace_percent->critical->end);
237 261
238 if (verbose >= 3 && path->group != NULL) 262 if (verbose >= 3 && path->group != NULL)
239 printf("Group of %s: %s\n",path->name,path->group); 263 printf("Group of %s: %s\n",path->name,path->group);
@@ -243,26 +267,34 @@ main (int argc, char **argv)
243 267
244 me = path->best_match; 268 me = path->best_match;
245 269
270 if (!me) {
271 continue;
272 }
273
246#ifdef __CYGWIN__ 274#ifdef __CYGWIN__
247 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 275 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
248 continue; 276 continue;
249 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); 277 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10);
250 if (GetDriveType(mountdir) != DRIVE_FIXED) 278 if (GetDriveType(mountdir) != DRIVE_FIXED)
251 me->me_remote = 1; 279 me->me_remote = 1;
252#endif 280#endif
253 /* Filters */ 281 /* Filters */
254 282
255 /* Remove filesystems already seen */ 283 /* Remove filesystems already seen */
256 if (np_seen_name(seen, me->me_mountdir)) { 284 if (np_seen_name(seen, me->me_mountdir)) {
257 continue; 285 continue;
258 } 286 }
259 np_add_name(&seen, me->me_mountdir); 287 np_add_name(&seen, me->me_mountdir);
260 288
261 if (path->group == NULL) { 289 if (path->group == NULL) {
262 /* Skip remote filesystems if we're not interested in them */ 290 /* Skip remote filesystems if we're not interested in them */
263 if (me->me_remote && show_local_fs) { 291 if (me->me_remote && show_local_fs) {
264 if (stat_remote_fs) 292 if (stat_remote_fs) {
265 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 }
266 continue; 298 continue;
267 /* 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 */
268 } else if (me->me_dummy && !show_all_fs) { 300 } else if (me->me_dummy && !show_all_fs) {
@@ -281,15 +313,30 @@ main (int argc, char **argv)
281 } 313 }
282 } 314 }
283 315
284 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 }
285 get_fs_usage (me->me_mountdir, me->me_devname, &fsp); 323 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
286 324
287 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) { 325 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
288 get_stats (path, &fsp); 326 get_stats (path, &fsp);
289 327
290 if (verbose >= 3) { 328 if (verbose >= 3) {
291 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",
292 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);
293 } 340 }
294 341
295 /* Threshold comparisons */ 342 /* Threshold comparisons */
@@ -326,68 +373,89 @@ main (int argc, char **argv)
326 */ 373 */
327 374
328 /* *_high_tide must be reinitialized at each run */ 375 /* *_high_tide must be reinitialized at each run */
329 warning_high_tide = UINT_MAX; 376 uint64_t warning_high_tide = UINT64_MAX;
330 critical_high_tide = UINT_MAX;
331 377
332 if (path->freespace_units->warning != NULL) { 378 if (path->freespace_units->warning != NULL) {
333 warning_high_tide = path->dtotal_units - path->freespace_units->warning->end; 379 warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult;
334 } 380 }
335 if (path->freespace_percent->warning != NULL) { 381 if (path->freespace_percent->warning != NULL) {
336 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)) );
337 } 383 }
384
385 uint64_t critical_high_tide = UINT64_MAX;
386
338 if (path->freespace_units->critical != NULL) { 387 if (path->freespace_units->critical != NULL) {
339 critical_high_tide = path->dtotal_units - path->freespace_units->critical->end; 388 critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult;
340 } 389 }
341 if (path->freespace_percent->critical != NULL) { 390 if (path->freespace_percent->critical != NULL) {
342 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)) );
343 } 392 }
344 393
345 /* Nb: *_high_tide are unset when == UINT_MAX */ 394 /* Nb: *_high_tide are unset when == UINT64_MAX */
346 xasprintf (&perf, "%s %s", perf, 395 xasprintf (&perf, "%s %s", perf,
347 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 396 perfdata_uint64 (
348 path->dused_units, units, 397 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
349 (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide, 398 path->dused_units * mult, "B",
350 (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide, 399 (warning_high_tide == UINT64_MAX ? FALSE : TRUE), warning_high_tide,
351 TRUE, 0, 400 (critical_high_tide == UINT64_MAX ? FALSE : TRUE), critical_high_tide,
352 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 }
353 426
354 if (disk_result==STATE_OK && erronly && !verbose) 427 if (disk_result==STATE_OK && erronly && !verbose)
355 continue; 428 continue;
356 429
357 if(disk_result && verbose >= 1) { 430 if(disk_result && verbose >= 1) {
358 xasprintf(&flag_header, " %s [", state_text (disk_result)); 431 xasprintf(&flag_header, " %s [", state_text (disk_result));
359 } else { 432 } else {
360 xasprintf(&flag_header, ""); 433 xasprintf(&flag_header, "");
361 } 434 }
362 xasprintf (&output, "%s%s %s %.0f %s (%.0f%%", 435 xasprintf (&output, "%s%s %s %llu%s (%.0f%%",
363 output, flag_header, 436 output, flag_header,
364 (!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,
365 path->dfree_units, 438 path->dfree_units,
366 units, 439 units,
367 path->dfree_pct); 440 path->dfree_pct);
368 if (path->dused_inodes_percent < 0) { 441 if (path->dused_inodes_percent < 0) {
369 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); 442 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : ""));
370 } else { 443 } else {
371 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) ? "]" : ""));
372 } 445 }
373 free(flag_header); 446 free(flag_header);
374 /* TODO: Need to do a similar debug line
375 xasprintf (&details, _("%s\n\
376%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
377 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
378 me->me_devname, me->me_type, me->me_mountdir,
379 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
380 */
381
382 } 447 }
383
384 } 448 }
385 449
386 if (verbose >= 2) 450 if (verbose >= 2)
387 xasprintf (&output, "%s%s", output, details); 451 xasprintf (&output, "%s%s", output, details);
388 452
453 if (strcmp(output, "") == 0 && ! erronly) {
454 preamble = "";
455 xasprintf (&output, " - No disks were found for provided parameters;");
456 }
389 457
390 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);
391 return result; 459 return result;
392} 460}
393 461
@@ -423,9 +491,7 @@ process_arguments (int argc, char **argv)
423 int c, err; 491 int c, err;
424 struct parameter_list *se; 492 struct parameter_list *se;
425 struct parameter_list *temp_list = NULL, *previous = NULL; 493 struct parameter_list *temp_list = NULL, *previous = NULL;
426 struct parameter_list *temp_path_select_list = NULL; 494 struct mount_entry *me;
427 struct mount_entry *me, *temp_me;
428 int result = OK;
429 regex_t re; 495 regex_t re;
430 int cflags = REG_NOSUB | REG_EXTENDED; 496 int cflags = REG_NOSUB | REG_EXTENDED;
431 int default_cflags = cflags; 497 int default_cflags = cflags;
@@ -458,8 +524,10 @@ process_arguments (int argc, char **argv)
458 {"ignore-ereg-partition", required_argument, 0, 'i'}, 524 {"ignore-ereg-partition", required_argument, 0, 'i'},
459 {"ignore-eregi-path", required_argument, 0, 'I'}, 525 {"ignore-eregi-path", required_argument, 0, 'I'},
460 {"ignore-eregi-partition", required_argument, 0, 'I'}, 526 {"ignore-eregi-partition", required_argument, 0, 'I'},
527 {"ignore-missing", no_argument, 0, IGNORE_MISSING},
461 {"local", no_argument, 0, 'l'}, 528 {"local", no_argument, 0, 'l'},
462 {"stat-remote-fs", no_argument, 0, 'L'}, 529 {"stat-remote-fs", no_argument, 0, 'L'},
530 {"iperfdata", no_argument, 0, 'P'},
463 {"mountpoint", no_argument, 0, 'M'}, 531 {"mountpoint", no_argument, 0, 'M'},
464 {"errors-only", no_argument, 0, 'e'}, 532 {"errors-only", no_argument, 0, 'e'},
465 {"exact-match", no_argument, 0, 'E'}, 533 {"exact-match", no_argument, 0, 'E'},
@@ -482,7 +550,7 @@ process_arguments (int argc, char **argv)
482 strcpy (argv[c], "-t"); 550 strcpy (argv[c], "-t");
483 551
484 while (1) { 552 while (1) {
485 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);
486 554
487 if (c == -1 || c == EOF) 555 if (c == -1 || c == EOF)
488 break; 556 break;
@@ -516,7 +584,7 @@ process_arguments (int argc, char **argv)
516 584
517 /* Awful mistake where the range values do not make sense. Normally, 585 /* Awful mistake where the range values do not make sense. Normally,
518 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
519 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
520 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
521 */ 589 */
522 case 'c': /* critical threshold */ 590 case 'c': /* critical threshold */
@@ -535,14 +603,14 @@ process_arguments (int argc, char **argv)
535 } 603 }
536 break; 604 break;
537 605
538 case 'W': /* warning inode threshold */ 606 case 'W': /* warning inode threshold */
539 if (*optarg == '@') { 607 if (*optarg == '@') {
540 warn_freeinodes_percent = optarg; 608 warn_freeinodes_percent = optarg;
541 } else { 609 } else {
542 xasprintf(&warn_freeinodes_percent, "@%s", optarg); 610 xasprintf(&warn_freeinodes_percent, "@%s", optarg);
543 } 611 }
544 break; 612 break;
545 case 'K': /* critical inode threshold */ 613 case 'K': /* critical inode threshold */
546 if (*optarg == '@') { 614 if (*optarg == '@') {
547 crit_freeinodes_percent = optarg; 615 crit_freeinodes_percent = optarg;
548 } else { 616 } else {
@@ -552,21 +620,39 @@ process_arguments (int argc, char **argv)
552 case 'u': 620 case 'u':
553 if (units) 621 if (units)
554 free(units); 622 free(units);
555 if (! strcmp (optarg, "bytes")) { 623 if (! strcasecmp (optarg, "bytes")) {
556 mult = (uintmax_t)1; 624 mult = (uintmax_t)1;
557 units = strdup ("B"); 625 units = strdup ("B");
558 } else if (! strcmp (optarg, "kB")) { 626 } else if (!strcmp(optarg, "KiB")) {
559 mult = (uintmax_t)1024; 627 mult = (uintmax_t)1024;
628 units = strdup ("KiB");
629 } else if (! strcmp (optarg, "kB")) {
630 mult = (uintmax_t)1000;
560 units = strdup ("kB"); 631 units = strdup ("kB");
561 } else if (! strcmp (optarg, "MB")) { 632 } else if (!strcmp(optarg, "MiB")) {
562 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;
563 units = strdup ("MB"); 637 units = strdup ("MB");
564 } else if (! strcmp (optarg, "GB")) { 638 } else if (!strcmp(optarg, "GiB")) {
565 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;
566 units = strdup ("GB"); 643 units = strdup ("GB");
567 } else if (! strcmp (optarg, "TB")) { 644 } else if (!strcmp(optarg, "TiB")) {
568 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;
569 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");
570 } else { 656 } else {
571 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); 657 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
572 } 658 }
@@ -577,19 +663,23 @@ process_arguments (int argc, char **argv)
577 mult = 1024; 663 mult = 1024;
578 if (units) 664 if (units)
579 free(units); 665 free(units);
580 units = strdup ("kB"); 666 units = strdup ("kiB");
581 break; 667 break;
582 case 'm': /* display mountpoint */ 668 case 'm': /* display mountpoint */
583 mult = 1024 * 1024; 669 mult = 1024 * 1024;
584 if (units) 670 if (units)
585 free(units); 671 free(units);
586 units = strdup ("MB"); 672 units = strdup ("MiB");
587 break; 673 break;
588 case 'L': 674 case 'L':
589 stat_remote_fs = 1; 675 stat_remote_fs = 1;
676 /* fallthrough */
590 case 'l': 677 case 'l':
591 show_local_fs = 1; 678 show_local_fs = 1;
592 break; 679 break;
680 case 'P':
681 display_inodes_perfdata = 1;
682 break;
593 case 'p': /* select path */ 683 case 'p': /* select path */
594 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 684 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
595 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 685 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
@@ -601,12 +691,19 @@ process_arguments (int argc, char **argv)
601 /* 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 */
602 if (! (se = np_find_parameter(path_select_list, optarg))) { 692 if (! (se = np_find_parameter(path_select_list, optarg))) {
603 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 }
604 } 699 }
605 se->group = group; 700 se->group = group;
606 set_all_thresholds(se); 701 set_all_thresholds(se);
607 702
608 /* 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 */
609 stat_path(se); 704 if (!stat_path(se)) {
705 break;
706 }
610 /* 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
611 * 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
612 * 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 */
@@ -649,6 +746,7 @@ process_arguments (int argc, char **argv)
649 break; 746 break;
650 case 'I': 747 case 'I':
651 cflags |= REG_ICASE; 748 cflags |= REG_ICASE;
749 // Intentional fallthrough
652 case 'i': 750 case 'i':
653 if (!path_selected) 751 if (!path_selected)
654 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"));
@@ -686,16 +784,21 @@ process_arguments (int argc, char **argv)
686 cflags = default_cflags; 784 cflags = default_cflags;
687 break; 785 break;
688 786
787 case IGNORE_MISSING:
788 ignore_missing = true;
789 break;
689 case 'A': 790 case 'A':
690 optarg = strdup(".*"); 791 optarg = strdup(".*");
792 // Intentional fallthrough
691 case 'R': 793 case 'R':
692 cflags |= REG_ICASE; 794 cflags |= REG_ICASE;
795 // Intentional fallthrough
693 case 'r': 796 case 'r':
694 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 797 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
695 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 798 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
696 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent || 799 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
697 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) { 800 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) {
698 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"));
699 } 802 }
700 803
701 err = regcomp(&re, optarg, cflags); 804 err = regcomp(&re, optarg, cflags);
@@ -719,7 +822,11 @@ process_arguments (int argc, char **argv)
719 } 822 }
720 } 823 }
721 824
722 if (!fnd) 825 if (!fnd && ignore_missing == true) {
826 path_ignored = true;
827 /* path_selected = TRUE;*/
828 break;
829 } else if (!fnd)
723 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), 830 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"),
724 _("Regular expression did not match any path or disk"), optarg); 831 _("Regular expression did not match any path or disk"), optarg);
725 832
@@ -779,14 +886,14 @@ process_arguments (int argc, char **argv)
779 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c])) 886 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
780 crit_usedspace_percent = argv[c++]; 887 crit_usedspace_percent = argv[c++];
781 888
782 if (argc > c && path == NULL) { 889 if (argc > c) {
783 se = np_add_parameter(&path_select_list, strdup(argv[c++])); 890 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
784 path_selected = TRUE; 891 path_selected = TRUE;
785 set_all_thresholds(se); 892 set_all_thresholds(se);
786 } 893 }
787 894
788 if (units == NULL) { 895 if (units == NULL) {
789 units = strdup ("MB"); 896 units = strdup ("MiB");
790 mult = (uintmax_t)1024 * 1024; 897 mult = (uintmax_t)1024 * 1024;
791 } 898 }
792 899
@@ -822,51 +929,6 @@ set_all_thresholds (struct parameter_list *path)
822 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent); 929 set_thresholds(&path->freeinodes_percent, warn_freeinodes_percent, crit_freeinodes_percent);
823} 930}
824 931
825/* TODO: Remove?
826
827int
828validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
829{
830 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
831 printf (_("INPUT ERROR: No thresholds specified"));
832 print_path (mypath);
833 return ERROR;
834 }
835 else if ((wp >= 0.0 || cp >= 0.0) &&
836 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
837 printf (_("\
838INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
839 cp, wp);
840 print_path (mypath);
841 return ERROR;
842 }
843 else if ((iwp >= 0.0 || icp >= 0.0) &&
844 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
845 printf (_("\
846INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
847 icp, iwp);
848 print_path (mypath);
849 return ERROR;
850 }
851 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
852 printf (_("\
853INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
854 (unsigned long)c, (unsigned long)w);
855 print_path (mypath);
856 return ERROR;
857 }
858
859 return OK;
860}
861
862*/
863
864
865
866
867
868
869
870void 932void
871print_help (void) 933print_help (void)
872{ 934{
@@ -909,6 +971,8 @@ print_help (void)
909 printf (" %s\n", _("Display only devices/mountpoints with errors")); 971 printf (" %s\n", _("Display only devices/mountpoints with errors"));
910 printf (" %s\n", "-f, --freespace-ignore-reserved"); 972 printf (" %s\n", "-f, --freespace-ignore-reserved");
911 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"));
912 printf (" %s\n", "-g, --group=NAME"); 976 printf (" %s\n", "-g, --group=NAME");
913 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"));
914 printf (" %s\n", "-k, --kilobytes"); 978 printf (" %s\n", "-k, --kilobytes");
@@ -919,7 +983,7 @@ print_help (void)
919 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"));
920 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)"));
921 printf (" %s\n", "-M, --mountpoint"); 985 printf (" %s\n", "-M, --mountpoint");
922 printf (" %s\n", _("Display the mountpoint instead of the partition")); 986 printf (" %s\n", _("Display the (block) device instead of the mount point"));
923 printf (" %s\n", "-m, --megabytes"); 987 printf (" %s\n", "-m, --megabytes");
924 printf (" %s\n", _("Same as '--units MB'")); 988 printf (" %s\n", _("Same as '--units MB'"));
925 printf (" %s\n", "-A, --all"); 989 printf (" %s\n", "-A, --all");
@@ -932,6 +996,9 @@ print_help (void)
932 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)"));
933 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");
934 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)"));
935 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1002 printf (UT_PLUG_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
936 printf (" %s\n", "-u, --units=STRING"); 1003 printf (" %s\n", "-u, --units=STRING");
937 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); 1004 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
@@ -942,12 +1009,20 @@ print_help (void)
942 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)"));
943 1010
944 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");
945 printf ("%s\n", _("Examples:")); 1020 printf ("%s\n", _("Examples:"));
946 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 /");
947 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"));
948 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.*$'");
949 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"));
950 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"));
951 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");
952 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"));
953 1028
@@ -960,12 +1035,12 @@ void
960print_usage (void) 1035print_usage (void)
961{ 1036{
962 printf ("%s\n", _("Usage:")); 1037 printf ("%s\n", _("Usage:"));
963 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);
964 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");
965 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 1040 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n");
966} 1041}
967 1042
968void 1043bool
969stat_path (struct parameter_list *p) 1044stat_path (struct parameter_list *p)
970{ 1045{
971 /* Stat entry to check that dir exists and is accessible */ 1046 /* Stat entry to check that dir exists and is accessible */
@@ -974,9 +1049,14 @@ stat_path (struct parameter_list *p)
974 if (stat (p->name, &stat_buf[0])) { 1049 if (stat (p->name, &stat_buf[0])) {
975 if (verbose >= 3) 1050 if (verbose >= 3)
976 printf("stat failed on %s\n", p->name); 1051 printf("stat failed on %s\n", p->name);
977 printf("DISK %s - ", _("CRITICAL")); 1052 if (ignore_missing == true) {
978 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 }
979 } 1058 }
1059 return true;
980} 1060}
981 1061
982 1062
@@ -996,66 +1076,87 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
996 continue; 1076 continue;
997#endif 1077#endif
998 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 1078 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
999 stat_path(p_list); 1079 if (! stat_path(p_list))
1080 continue;
1000 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);
1001 get_path_stats(p_list, &tmpfsp); 1082 get_path_stats(p_list, &tmpfsp);
1002 if (verbose >= 3) 1083 if (verbose >= 3)
1003 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",
1004 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,
1005 p_list->dtotal_units, mult); 1086 tmpfsp.fsu_blocks,
1006 1087 tmpfsp.fsu_blocksize,
1007 /* 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
1008 * 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 */
1009 if (! first) { 1096 if (! first) {
1010 p->total += p_list->total; 1097 p->total += p_list->total;
1011 p->available += p_list->available; 1098 p->available += p_list->available;
1012 p->available_to_root += p_list->available_to_root; 1099 p->available_to_root += p_list->available_to_root;
1013 p->used += p_list->used; 1100 p->used += p_list->used;
1014 1101
1015 p->dused_units += p_list->dused_units; 1102 p->dused_units += p_list->dused_units;
1016 p->dfree_units += p_list->dfree_units; 1103 p->dfree_units += p_list->dfree_units;
1017 p->dtotal_units += p_list->dtotal_units; 1104 p->dtotal_units += p_list->dtotal_units;
1018 p->inodes_total += p_list->inodes_total; 1105 p->inodes_total += p_list->inodes_total;
1019 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;
1020 } 1109 }
1021 first = 0; 1110 first = 0;
1022 } 1111 }
1023 if (verbose >= 3) 1112 if (verbose >= 3)
1024 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",
1025 p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units, 1114 p->group,
1026 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);
1027 } 1120 }
1028 /* modify devname and mountdir for output */ 1121 /* modify devname and mountdir for output */
1029 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;
1030 } 1123 }
1031 /* finally calculate percentages for either plain FS or summed up group */ 1124 /* finally calculate percentages for either plain FS or summed up group */
1032 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 */
1033 p->dfree_pct = 100 - p->dused_pct; 1126 p->dfree_pct = 100 - p->dused_pct;
1034 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);
1035 p->dfree_inodes_percent = 100 - p->dused_inodes_percent; 1128 p->dfree_inodes_percent = 100 - p->dused_inodes_percent;
1036 1129
1037} 1130}
1038 1131
1039void 1132void
1040get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { 1133get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1041 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available 1134 p->available = fsp->fsu_bavail;
1042 * space on BSD (the actual value should be negative but fsp->fsu_bavail
1043 * is unsigned) */
1044 p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail;
1045 p->available_to_root = fsp->fsu_bfree; 1135 p->available_to_root = fsp->fsu_bfree;
1046 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1136 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1047 if (freespace_ignore_reserved) { 1137 if (freespace_ignore_reserved) {
1048 /* option activated : we substract the root-reserved space from the total */ 1138 /* option activated : we subtract the root-reserved space from the total */
1049 p->total = fsp->fsu_blocks - p->available_to_root + p->available; 1139 p->total = fsp->fsu_blocks - p->available_to_root + p->available;
1050 } else { 1140 } else {
1051 /* default behaviour : take all the blocks into account */ 1141 /* default behaviour : take all the blocks into account */
1052 p->total = fsp->fsu_blocks; 1142 p->total = fsp->fsu_blocks;
1053 } 1143 }
1054 1144
1055 p->dused_units = p->used*fsp->fsu_blocksize/mult; 1145 p->dused_units = p->used*fsp->fsu_blocksize/mult;
1056 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1146 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1057 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1147 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1058 p->inodes_total = fsp->fsu_files; /* Total file nodes. */ 1148 /* Free file nodes. Not sure the workaround is required, but in case...*/
1059 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 }
1060 np_add_name(&seen, p->best_match->me_mountdir); 1161 np_add_name(&seen, p->best_match->me_mountdir);
1061} 1162}