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.c246
1 files changed, 153 insertions, 93 deletions
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 0d73a4f1..54befcad 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;
@@ -144,6 +141,7 @@ int erronly = FALSE;
144int display_mntp = FALSE; 141int display_mntp = FALSE;
145int exact_match = FALSE; 142int exact_match = FALSE;
146int freespace_ignore_reserved = FALSE; 143int freespace_ignore_reserved = FALSE;
144int display_inodes_perfdata = FALSE;
147char *warn_freespace_units = NULL; 145char *warn_freespace_units = NULL;
148char *crit_freespace_units = NULL; 146char *crit_freespace_units = NULL;
149char *warn_freespace_percent = NULL; 147char *warn_freespace_percent = NULL;
@@ -170,15 +168,14 @@ main (int argc, char **argv)
170 char *output; 168 char *output;
171 char *details; 169 char *details;
172 char *perf; 170 char *perf;
171 char *perf_ilabel;
173 char *preamble; 172 char *preamble;
174 char *flag_header; 173 char *flag_header;
175 double inode_space_pct; 174 double inode_space_pct;
176 double warning_high_tide;
177 double critical_high_tide;
178 int temp_result; 175 int temp_result;
179 176
180 struct mount_entry *me; 177 struct mount_entry *me;
181 struct fs_usage fsp, tmpfsp; 178 struct fs_usage fsp;
182 struct parameter_list *temp_list, *path; 179 struct parameter_list *temp_list, *path;
183 180
184#ifdef __CYGWIN__ 181#ifdef __CYGWIN__
@@ -189,6 +186,7 @@ main (int argc, char **argv)
189 output = strdup (""); 186 output = strdup ("");
190 details = strdup (""); 187 details = strdup ("");
191 perf = strdup (""); 188 perf = strdup ("");
189 perf_ilabel = strdup ("");
192 stat_buf = malloc(sizeof *stat_buf); 190 stat_buf = malloc(sizeof *stat_buf);
193 191
194 setlocale (LC_ALL, ""); 192 setlocale (LC_ALL, "");
@@ -245,17 +243,17 @@ main (int argc, char **argv)
245 243
246#ifdef __CYGWIN__ 244#ifdef __CYGWIN__
247 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11) 245 if (strncmp(path->name, "/cygdrive/", 10) != 0 || strlen(path->name) > 11)
248 continue; 246 continue;
249 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10); 247 snprintf(mountdir, sizeof(mountdir), "%s:\\", me->me_mountdir + 10);
250 if (GetDriveType(mountdir) != DRIVE_FIXED) 248 if (GetDriveType(mountdir) != DRIVE_FIXED)
251 me->me_remote = 1; 249 me->me_remote = 1;
252#endif 250#endif
253 /* Filters */ 251 /* Filters */
254 252
255 /* Remove filesystems already seen */ 253 /* Remove filesystems already seen */
256 if (np_seen_name(seen, me->me_mountdir)) { 254 if (np_seen_name(seen, me->me_mountdir)) {
257 continue; 255 continue;
258 } 256 }
259 np_add_name(&seen, me->me_mountdir); 257 np_add_name(&seen, me->me_mountdir);
260 258
261 if (path->group == NULL) { 259 if (path->group == NULL) {
@@ -288,8 +286,17 @@ main (int argc, char **argv)
288 get_stats (path, &fsp); 286 get_stats (path, &fsp);
289 287
290 if (verbose >= 3) { 288 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", 289 printf ("For %s, used_pct=%g free_pct=%g used_units=%llu free_units=%llu total_units=%llu used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n",
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); 290 me->me_mountdir,
291 path->dused_pct,
292 path->dfree_pct,
293 path->dused_units,
294 path->dfree_units,
295 path->dtotal_units,
296 path->dused_inodes_percent,
297 path->dfree_inodes_percent,
298 fsp.fsu_blocksize,
299 mult);
293 } 300 }
294 301
295 /* Threshold comparisons */ 302 /* Threshold comparisons */
@@ -326,54 +333,79 @@ main (int argc, char **argv)
326 */ 333 */
327 334
328 /* *_high_tide must be reinitialized at each run */ 335 /* *_high_tide must be reinitialized at each run */
329 warning_high_tide = UINT_MAX; 336 uint64_t warning_high_tide = UINT64_MAX;
330 critical_high_tide = UINT_MAX;
331 337
332 if (path->freespace_units->warning != NULL) { 338 if (path->freespace_units->warning != NULL) {
333 warning_high_tide = path->dtotal_units - path->freespace_units->warning->end; 339 warning_high_tide = (path->dtotal_units - path->freespace_units->warning->end) * mult;
334 } 340 }
335 if (path->freespace_percent->warning != NULL) { 341 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 )); 342 warning_high_tide = min( warning_high_tide, (uint64_t)((1.0 - path->freespace_percent->warning->end/100) * (path->dtotal_units * mult)) );
337 } 343 }
344
345 uint64_t critical_high_tide = UINT64_MAX;
346
338 if (path->freespace_units->critical != NULL) { 347 if (path->freespace_units->critical != NULL) {
339 critical_high_tide = path->dtotal_units - path->freespace_units->critical->end; 348 critical_high_tide = (path->dtotal_units - path->freespace_units->critical->end) * mult;
340 } 349 }
341 if (path->freespace_percent->critical != NULL) { 350 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 )); 351 critical_high_tide = min( critical_high_tide, (uint64_t)((1.0 - path->freespace_percent->critical->end/100) * (path->dtotal_units * mult)) );
343 } 352 }
344 353
345 /* Nb: *_high_tide are unset when == UINT_MAX */ 354 /* Nb: *_high_tide are unset when == UINT64_MAX */
346 xasprintf (&perf, "%s %s", perf, 355 xasprintf (&perf, "%s %s", perf,
347 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 356 perfdata_uint64 (
348 path->dused_units, units, 357 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
349 (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide, 358 path->dused_units * mult, "B",
350 (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide, 359 (warning_high_tide == UINT64_MAX ? FALSE : TRUE), warning_high_tide,
351 TRUE, 0, 360 (critical_high_tide == UINT64_MAX ? FALSE : TRUE), critical_high_tide,
352 TRUE, path->dtotal_units)); 361 TRUE, 0,
362 TRUE, path->dtotal_units * mult));
363
364 if (display_inodes_perfdata) {
365 /* *_high_tide must be reinitialized at each run */
366 warning_high_tide = UINT64_MAX;
367 critical_high_tide = UINT64_MAX;
368
369 if (path->freeinodes_percent->warning != NULL) {
370 warning_high_tide = llabs( min( (double) warning_high_tide, (double) (1.0 - path->freeinodes_percent->warning->end/100)*path->inodes_total ));
371 }
372 if (path->freeinodes_percent->critical != NULL) {
373 critical_high_tide = llabs( min( (double) critical_high_tide, (double) (1.0 - path->freeinodes_percent->critical->end/100)*path->inodes_total ));
374 }
375
376 xasprintf (&perf_ilabel, "%s (inodes)", (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir);
377 /* Nb: *_high_tide are unset when == UINT64_MAX */
378 xasprintf (&perf, "%s %s", perf,
379 perfdata_uint64 (perf_ilabel,
380 path->inodes_used, "",
381 (warning_high_tide != UINT64_MAX ? TRUE : FALSE), warning_high_tide,
382 (critical_high_tide != UINT64_MAX ? TRUE : FALSE), critical_high_tide,
383 TRUE, 0,
384 TRUE, path->inodes_total));
385 }
353 386
354 if (disk_result==STATE_OK && erronly && !verbose) 387 if (disk_result==STATE_OK && erronly && !verbose)
355 continue; 388 continue;
356 389
357 if(disk_result && verbose >= 1) { 390 if(disk_result && verbose >= 1) {
358 xasprintf(&flag_header, " %s [", state_text (disk_result)); 391 xasprintf(&flag_header, " %s [", state_text (disk_result));
359 } else { 392 } else {
360 xasprintf(&flag_header, ""); 393 xasprintf(&flag_header, "");
361 } 394 }
362 xasprintf (&output, "%s%s %s %.0f %s (%.0f%%", 395 xasprintf (&output, "%s%s %s %llu%s (%.0f%%",
363 output, flag_header, 396 output, flag_header,
364 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir, 397 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
365 path->dfree_units, 398 path->dfree_units,
366 units, 399 units,
367 path->dfree_pct); 400 path->dfree_pct);
368 if (path->dused_inodes_percent < 0) { 401 if (path->dused_inodes_percent < 0) {
369 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : "")); 402 xasprintf(&output, "%s inode=-)%s;", output, (disk_result ? "]" : ""));
370 } else { 403 } else {
371 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : "")); 404 xasprintf(&output, "%s inode=%.0f%%)%s;", output, path->dfree_inodes_percent, ((disk_result && verbose >= 1) ? "]" : ""));
372 } 405 }
373 free(flag_header); 406 free(flag_header);
374 /* TODO: Need to do a similar debug line 407 /* TODO: Need to do a similar debug line
375 xasprintf (&details, _("%s\n\ 408 xasprintf (&details, _("%s\n\%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
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, 409 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
378 me->me_devname, me->me_type, me->me_mountdir, 410 me->me_devname, me->me_type, me->me_mountdir,
379 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp); 411 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
@@ -423,9 +455,7 @@ process_arguments (int argc, char **argv)
423 int c, err; 455 int c, err;
424 struct parameter_list *se; 456 struct parameter_list *se;
425 struct parameter_list *temp_list = NULL, *previous = NULL; 457 struct parameter_list *temp_list = NULL, *previous = NULL;
426 struct parameter_list *temp_path_select_list = NULL; 458 struct mount_entry *me;
427 struct mount_entry *me, *temp_me;
428 int result = OK;
429 regex_t re; 459 regex_t re;
430 int cflags = REG_NOSUB | REG_EXTENDED; 460 int cflags = REG_NOSUB | REG_EXTENDED;
431 int default_cflags = cflags; 461 int default_cflags = cflags;
@@ -460,6 +490,7 @@ process_arguments (int argc, char **argv)
460 {"ignore-eregi-partition", required_argument, 0, 'I'}, 490 {"ignore-eregi-partition", required_argument, 0, 'I'},
461 {"local", no_argument, 0, 'l'}, 491 {"local", no_argument, 0, 'l'},
462 {"stat-remote-fs", no_argument, 0, 'L'}, 492 {"stat-remote-fs", no_argument, 0, 'L'},
493 {"iperfdata", no_argument, 0, 'P'},
463 {"mountpoint", no_argument, 0, 'M'}, 494 {"mountpoint", no_argument, 0, 'M'},
464 {"errors-only", no_argument, 0, 'e'}, 495 {"errors-only", no_argument, 0, 'e'},
465 {"exact-match", no_argument, 0, 'E'}, 496 {"exact-match", no_argument, 0, 'E'},
@@ -482,7 +513,7 @@ process_arguments (int argc, char **argv)
482 strcpy (argv[c], "-t"); 513 strcpy (argv[c], "-t");
483 514
484 while (1) { 515 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); 516 c = getopt_long (argc, argv, "+?VqhvefCt:c:w:K:W:u:p:x:X:N:mklLPg:R:r:i:I:MEA", longopts, &option);
486 517
487 if (c == -1 || c == EOF) 518 if (c == -1 || c == EOF)
488 break; 519 break;
@@ -535,14 +566,14 @@ process_arguments (int argc, char **argv)
535 } 566 }
536 break; 567 break;
537 568
538 case 'W': /* warning inode threshold */ 569 case 'W': /* warning inode threshold */
539 if (*optarg == '@') { 570 if (*optarg == '@') {
540 warn_freeinodes_percent = optarg; 571 warn_freeinodes_percent = optarg;
541 } else { 572 } else {
542 xasprintf(&warn_freeinodes_percent, "@%s", optarg); 573 xasprintf(&warn_freeinodes_percent, "@%s", optarg);
543 } 574 }
544 break; 575 break;
545 case 'K': /* critical inode threshold */ 576 case 'K': /* critical inode threshold */
546 if (*optarg == '@') { 577 if (*optarg == '@') {
547 crit_freeinodes_percent = optarg; 578 crit_freeinodes_percent = optarg;
548 } else { 579 } else {
@@ -552,21 +583,24 @@ process_arguments (int argc, char **argv)
552 case 'u': 583 case 'u':
553 if (units) 584 if (units)
554 free(units); 585 free(units);
555 if (! strcmp (optarg, "bytes")) { 586 if (! strcasecmp (optarg, "bytes")) {
556 mult = (uintmax_t)1; 587 mult = (uintmax_t)1;
557 units = strdup ("B"); 588 units = strdup ("B");
558 } else if (! strcmp (optarg, "kB")) { 589 } else if ( (! strcmp (optarg, "kB")) || (!strcmp(optarg, "KiB")) ) {
559 mult = (uintmax_t)1024; 590 mult = (uintmax_t)1024;
560 units = strdup ("kB"); 591 units = strdup ("kiB");
561 } else if (! strcmp (optarg, "MB")) { 592 } else if ( (! strcmp (optarg, "MB")) || (!strcmp(optarg, "MiB")) ) {
562 mult = (uintmax_t)1024 * 1024; 593 mult = (uintmax_t)1024 * 1024;
563 units = strdup ("MB"); 594 units = strdup ("MiB");
564 } else if (! strcmp (optarg, "GB")) { 595 } else if ( (! strcmp (optarg, "GB")) || (!strcmp(optarg, "GiB")) ) {
565 mult = (uintmax_t)1024 * 1024 * 1024; 596 mult = (uintmax_t)1024 * 1024 * 1024;
566 units = strdup ("GB"); 597 units = strdup ("GiB");
567 } else if (! strcmp (optarg, "TB")) { 598 } else if ( (! strcmp (optarg, "TB")) || (!strcmp(optarg, "TiB")) ) {
568 mult = (uintmax_t)1024 * 1024 * 1024 * 1024; 599 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
569 units = strdup ("TB"); 600 units = strdup ("TiB");
601 } else if ( (! strcmp (optarg, "PB")) || (!strcmp(optarg, "PiB")) ) {
602 mult = (uintmax_t)1024 * 1024 * 1024 * 1024 * 1024;
603 units = strdup ("PiB");
570 } else { 604 } else {
571 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg); 605 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
572 } 606 }
@@ -577,19 +611,23 @@ process_arguments (int argc, char **argv)
577 mult = 1024; 611 mult = 1024;
578 if (units) 612 if (units)
579 free(units); 613 free(units);
580 units = strdup ("kB"); 614 units = strdup ("kiB");
581 break; 615 break;
582 case 'm': /* display mountpoint */ 616 case 'm': /* display mountpoint */
583 mult = 1024 * 1024; 617 mult = 1024 * 1024;
584 if (units) 618 if (units)
585 free(units); 619 free(units);
586 units = strdup ("MB"); 620 units = strdup ("MiB");
587 break; 621 break;
588 case 'L': 622 case 'L':
589 stat_remote_fs = 1; 623 stat_remote_fs = 1;
624 /* fallthrough */
590 case 'l': 625 case 'l':
591 show_local_fs = 1; 626 show_local_fs = 1;
592 break; 627 break;
628 case 'P':
629 display_inodes_perfdata = 1;
630 break;
593 case 'p': /* select path */ 631 case 'p': /* select path */
594 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent || 632 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
595 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 633 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
@@ -762,10 +800,10 @@ process_arguments (int argc, char **argv)
762 break; 800 break;
763 case 'V': /* version */ 801 case 'V': /* version */
764 print_revision (progname, NP_VERSION); 802 print_revision (progname, NP_VERSION);
765 exit (STATE_OK); 803 exit (STATE_UNKNOWN);
766 case 'h': /* help */ 804 case 'h': /* help */
767 print_help (); 805 print_help ();
768 exit (STATE_OK); 806 exit (STATE_UNKNOWN);
769 case '?': /* help */ 807 case '?': /* help */
770 usage (_("Unknown argument")); 808 usage (_("Unknown argument"));
771 } 809 }
@@ -786,7 +824,7 @@ process_arguments (int argc, char **argv)
786 } 824 }
787 825
788 if (units == NULL) { 826 if (units == NULL) {
789 units = strdup ("MB"); 827 units = strdup ("MiB");
790 mult = (uintmax_t)1024 * 1024; 828 mult = (uintmax_t)1024 * 1024;
791 } 829 }
792 830
@@ -909,6 +947,8 @@ print_help (void)
909 printf (" %s\n", _("Display only devices/mountpoints with errors")); 947 printf (" %s\n", _("Display only devices/mountpoints with errors"));
910 printf (" %s\n", "-f, --freespace-ignore-reserved"); 948 printf (" %s\n", "-f, --freespace-ignore-reserved");
911 printf (" %s\n", _("Don't account root-reserved blocks into freespace in perfdata")); 949 printf (" %s\n", _("Don't account root-reserved blocks into freespace in perfdata"));
950 printf (" %s\n", "-P, --iperfdata");
951 printf (" %s\n", _("Display inode usage in perfdata"));
912 printf (" %s\n", "-g, --group=NAME"); 952 printf (" %s\n", "-g, --group=NAME");
913 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together")); 953 printf (" %s\n", _("Group paths. Thresholds apply to (free-)space of all partitions together"));
914 printf (" %s\n", "-k, --kilobytes"); 954 printf (" %s\n", "-k, --kilobytes");
@@ -998,50 +1038,59 @@ get_stats (struct parameter_list *p, struct fs_usage *fsp) {
998 if (p_list->group && ! (strcmp(p_list->group, p->group))) { 1038 if (p_list->group && ! (strcmp(p_list->group, p->group))) {
999 stat_path(p_list); 1039 stat_path(p_list);
1000 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp); 1040 get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
1001 get_path_stats(p_list, &tmpfsp); 1041 get_path_stats(p_list, &tmpfsp);
1002 if (verbose >= 3) 1042 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", 1043 printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%lu free_units=%llu total_units=%llu mult=%llu\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, 1044 p_list->group,
1005 p_list->dtotal_units, mult); 1045 tmpfsp.fsu_blocks,
1006 1046 tmpfsp.fsu_blocksize,
1007 /* prevent counting the first FS of a group twice since its parameter_list entry 1047 p_list->best_match->me_mountdir,
1048 p_list->dused_units,
1049 p_list->dfree_units,
1050 p_list->dtotal_units,
1051 mult);
1052
1053 /* 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 */ 1054 * is used to carry the information of all file systems of the entire group */
1009 if (! first) { 1055 if (! first) {
1010 p->total += p_list->total; 1056 p->total += p_list->total;
1011 p->available += p_list->available; 1057 p->available += p_list->available;
1012 p->available_to_root += p_list->available_to_root; 1058 p->available_to_root += p_list->available_to_root;
1013 p->used += p_list->used; 1059 p->used += p_list->used;
1014 1060
1015 p->dused_units += p_list->dused_units; 1061 p->dused_units += p_list->dused_units;
1016 p->dfree_units += p_list->dfree_units; 1062 p->dfree_units += p_list->dfree_units;
1017 p->dtotal_units += p_list->dtotal_units; 1063 p->dtotal_units += p_list->dtotal_units;
1018 p->inodes_total += p_list->inodes_total; 1064 p->inodes_total += p_list->inodes_total;
1019 p->inodes_free += p_list->inodes_free; 1065 p->inodes_free += p_list->inodes_free;
1066 p->inodes_free_to_root += p_list->inodes_free_to_root;
1067 p->inodes_used += p_list->inodes_used;
1020 } 1068 }
1021 first = 0; 1069 first = 0;
1022 } 1070 }
1023 if (verbose >= 3) 1071 if (verbose >= 3)
1024 printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n", 1072 printf("Group %s now has: used_units=%llu free_units=%llu total_units=%llu fsu_blocksize=%llu mult=%llu\n",
1025 p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units, 1073 p->group,
1026 p->dfree_units, p->dtotal_units, mult); 1074 p->dused_units,
1075 p->dfree_units,
1076 p->dtotal_units,
1077 tmpfsp.fsu_blocksize,
1078 mult);
1027 } 1079 }
1028 /* modify devname and mountdir for output */ 1080 /* modify devname and mountdir for output */
1029 p->best_match->me_mountdir = p->best_match->me_devname = p->group; 1081 p->best_match->me_mountdir = p->best_match->me_devname = p->group;
1030 } 1082 }
1031 /* finally calculate percentages for either plain FS or summed up group */ 1083 /* 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 */ 1084 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; 1085 p->dfree_pct = 100 - p->dused_pct;
1034 p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total); 1086 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; 1087 p->dfree_inodes_percent = 100 - p->dused_inodes_percent;
1036 1088
1037} 1089}
1038 1090
1039void 1091void
1040get_path_stats (struct parameter_list *p, struct fs_usage *fsp) { 1092get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1041 /* 2007-12-08 - Workaround for Gnulib reporting insanely high available 1093 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; 1094 p->available_to_root = fsp->fsu_bfree;
1046 p->used = fsp->fsu_blocks - fsp->fsu_bfree; 1095 p->used = fsp->fsu_blocks - fsp->fsu_bfree;
1047 if (freespace_ignore_reserved) { 1096 if (freespace_ignore_reserved) {
@@ -1051,11 +1100,22 @@ get_path_stats (struct parameter_list *p, struct fs_usage *fsp) {
1051 /* default behaviour : take all the blocks into account */ 1100 /* default behaviour : take all the blocks into account */
1052 p->total = fsp->fsu_blocks; 1101 p->total = fsp->fsu_blocks;
1053 } 1102 }
1054 1103
1055 p->dused_units = p->used*fsp->fsu_blocksize/mult; 1104 p->dused_units = p->used*fsp->fsu_blocksize/mult;
1056 p->dfree_units = p->available*fsp->fsu_blocksize/mult; 1105 p->dfree_units = p->available*fsp->fsu_blocksize/mult;
1057 p->dtotal_units = p->total*fsp->fsu_blocksize/mult; 1106 p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
1058 p->inodes_total = fsp->fsu_files; /* Total file nodes. */ 1107 /* Free file nodes. Not sure the workaround is required, but in case...*/
1059 p->inodes_free = fsp->fsu_ffree; /* Free file nodes. */ 1108 p->inodes_free = fsp->fsu_favail > fsp->fsu_ffree ? 0 : fsp->fsu_favail;
1109 p->inodes_free_to_root = fsp->fsu_ffree; /* Free file nodes for root. */
1110 p->inodes_used = fsp->fsu_files - fsp->fsu_ffree;
1111 if (freespace_ignore_reserved) {
1112 /* option activated : we substract the root-reserved inodes from the total */
1113 /* not all OS report fsp->fsu_favail, only the ones with statvfs syscall */
1114 /* for others, fsp->fsu_ffree == fsp->fsu_favail */
1115 p->inodes_total = fsp->fsu_files - p->inodes_free_to_root + p->inodes_free;
1116 } else {
1117 /* default behaviour : take all the inodes into account */
1118 p->inodes_total = fsp->fsu_files;
1119 }
1060 np_add_name(&seen, p->best_match->me_mountdir); 1120 np_add_name(&seen, p->best_match->me_mountdir);
1061} 1121}