1 /******************************************************************************
2 *
3 * Nagios check_disk plugin
4 *
5 * License: GPL
6 * Copyright (c) 1999-2006 nagios-plugins team
7 *
8 * Last Modified: $Date$
9 *
10 * Description:
11 *
12 * This file contains the check_disk plugin
13 *
14 * License Information:
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 * $Id$
31 *
32 *****************************************************************************/
34 const char *progname = "check_disk";
35 const char *program_name = "check_disk"; /* Required for coreutils libs */
36 const char *revision = "$Revision$";
37 const char *copyright = "1999-2006";
38 const char *email = "nagiosplug-devel@lists.sourceforge.net";
41 #include "common.h"
42 #if HAVE_INTTYPES_H
43 # include <inttypes.h>
44 #endif
45 #include <assert.h>
46 #include "popen.h"
47 #include "utils.h"
48 #include "utils_disk.h"
49 #include <stdarg.h>
50 #include "fsusage.h"
51 #include "mountlist.h"
52 #include "intprops.h" /* necessary for TYPE_MAXIMUM */
53 #if HAVE_LIMITS_H
54 # include <limits.h>
55 #endif
58 /* If nonzero, show inode information. */
59 static int inode_format = 1;
61 /* If nonzero, show even filesystems with zero size or
62 uninteresting types. */
63 static int show_all_fs = 1;
65 /* If nonzero, show only local filesystems. */
66 static int show_local_fs = 0;
68 /* If positive, the units to use when printing sizes;
69 if negative, the human-readable base. */
70 /* static int output_block_size; */
72 /* If nonzero, invoke the `sync' system call before getting any usage data.
73 Using this option can make df very slow, especially with many or very
74 busy disks. Note that this may make a difference on some systems --
75 SunOs4.1.3, for one. It is *not* necessary on Linux. */
76 /* static int require_sync = 0; */
78 /* Linked list of filesystem types to display.
79 If `fs_select_list' is NULL, list all types.
80 This table is generated dynamically from command-line options,
81 rather than hardcoding into the program what it thinks are the
82 valid filesystem types; let the user specify any filesystem type
83 they want to, and if there are any filesystems of that type, they
84 will be shown.
86 Some filesystem types:
87 4.2 4.3 ufs nfs swap ignore io vm efs dbg */
89 /* static struct parameter_list *fs_select_list; */
91 /* Linked list of filesystem types to omit.
92 If the list is empty, don't exclude any types. */
94 static struct name_list *fs_exclude_list;
96 static struct name_list *dp_exclude_list;
98 static struct parameter_list *path_select_list = NULL;
100 /* Linked list of mounted filesystems. */
101 static struct mount_entry *mount_list;
103 /* For long options that have no equivalent short option, use a
104 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
105 enum
106 {
107 SYNC_OPTION = CHAR_MAX + 1,
108 NO_SYNC_OPTION,
109 BLOCK_SIZE_OPTION
110 };
112 #ifdef _AIX
113 #pragma alloca
114 #endif
116 /* Linked list of mounted filesystems. */
117 static struct mount_entry *mount_list;
119 int process_arguments (int, char **);
120 void print_path (const char *mypath);
121 int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *);
122 void print_help (void);
123 void print_usage (void);
125 double w_dfp = -1.0;
126 double c_dfp = -1.0;
127 char *path;
128 char *exclude_device;
129 char *units;
130 uintmax_t mult = 1024 * 1024;
131 int verbose = 0;
132 int erronly = FALSE;
133 int display_mntp = FALSE;
134 int exact_match = FALSE;
135 char *warn_freespace_units = NULL;
136 char *crit_freespace_units = NULL;
137 char *warn_freespace_percent = NULL;
138 char *crit_freespace_percent = NULL;
139 char *warn_usedspace_units = NULL;
140 char *crit_usedspace_units = NULL;
141 char *warn_usedspace_percent = NULL;
142 char *crit_usedspace_percent = NULL;
143 char *warn_usedinodes_percent = NULL;
144 char *crit_usedinodes_percent = NULL;
147 int
148 main (int argc, char **argv)
149 {
150 int result = STATE_UNKNOWN;
151 int disk_result = STATE_UNKNOWN;
152 char *output;
153 char *details;
154 char *perf;
155 float inode_space_pct;
156 uintmax_t total, available, available_to_root, used;
157 double dfree_pct = -1, dused_pct = -1;
158 double dused_units, dfree_units, dtotal_units;
159 double dused_inodes_percent;
160 int temp_result;
162 struct mount_entry *me;
163 struct fs_usage fsp;
164 struct parameter_list *temp_list, *path;
165 struct name_list *seen = NULL;
167 output = strdup (" - free space:");
168 details = strdup ("");
169 perf = strdup ("");
171 setlocale (LC_ALL, "");
172 bindtextdomain (PACKAGE, LOCALEDIR);
173 textdomain (PACKAGE);
175 mount_list = read_file_system_list (0);
177 if (process_arguments (argc, argv) == ERROR)
178 usage4 (_("Could not parse arguments"));
180 /* If a list of paths has not been selected, find entire
181 mount list and create list of paths
182 */
183 if (! path_select_list) {
184 for (me = mount_list; me; me = me->me_next) {
185 path = np_add_parameter(&path_select_list, me->me_mountdir);
186 path->best_match = me;
187 set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
188 set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
189 set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
190 set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
191 set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
192 }
193 } else {
194 np_set_best_match(path_select_list, mount_list, exact_match);
196 /* Error if no match found for specified paths */
197 temp_list = path_select_list;
198 while (temp_list) {
199 if (! temp_list->best_match) {
200 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
201 }
202 temp_list = temp_list->name_next;
203 }
204 }
206 /* Process for every path in list */
207 for (path = path_select_list; path; path=path->name_next) {
208 me = path->best_match;
210 /* Filters */
212 /* Remove filesystems already seen */
213 if (np_seen_name(seen, me->me_mountdir)) {
214 continue;
215 } else {
216 np_add_name(&seen, me->me_mountdir);
217 }
218 /* Skip remote filesystems if we're not interested in them */
219 if (me->me_remote && show_local_fs) {
220 continue;
221 /* Skip pseudo fs's if we haven't asked for all fs's */
222 } else if (me->me_dummy && !show_all_fs) {
223 continue;
224 /* Skip excluded fstypes */
225 } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
226 continue;
227 /* Skip excluded fs's */
228 } else if (dp_exclude_list &&
229 (np_find_name (dp_exclude_list, me->me_devname) ||
230 np_find_name (dp_exclude_list, me->me_mountdir))) {
231 continue;
232 }
234 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
236 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
237 total = fsp.fsu_blocks;
238 available = fsp.fsu_bavail;
239 available_to_root = fsp.fsu_bfree;
240 used = total - available_to_root;
242 /* I don't understand the below, but it is taken from coreutils' df */
243 /* Is setting dused_pct, in the best possible way */
244 if (used <= TYPE_MAXIMUM(uintmax_t) / 100) {
245 uintmax_t u100 = used * 100;
246 uintmax_t nonroot_total = used + available;
247 dused_pct = u100 / nonroot_total + (u100 % nonroot_total != 0);
248 } else {
249 /* Possible rounding errors - see coreutils' df for more explanation */
250 double u = used;
251 double a = available;
252 double nonroot_total = u + a;
253 if (nonroot_total) {
254 long int lipct = dused_pct = u * 100 / nonroot_total;
255 double ipct = lipct;
257 /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
258 if (ipct - 1 < dused_pct && dused_pct <= ipct + 1)
259 dused_pct = ipct + (ipct < dused_pct);
260 }
261 }
263 dfree_pct = 100 - dused_pct;
264 dused_units = used*fsp.fsu_blocksize/mult;
265 dfree_units = available*fsp.fsu_blocksize/mult;
266 dtotal_units = total*fsp.fsu_blocksize/mult;
267 dused_inodes_percent = (fsp.fsu_files - fsp.fsu_ffree) * 100 / fsp.fsu_files;
269 if (verbose >= 3) {
270 printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n",
271 me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
272 }
274 /* Threshold comparisons */
276 temp_result = get_status(dfree_units, path->freespace_units);
277 if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
278 result = max_state( result, temp_result );
280 temp_result = get_status(dfree_pct, path->freespace_percent);
281 if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
282 result = max_state( result, temp_result );
284 temp_result = get_status(dused_units, path->usedspace_units);
285 if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
286 result = max_state( result, temp_result );
288 temp_result = get_status(dused_pct, path->usedspace_percent);
289 if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
290 result = max_state( result, temp_result );
292 temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
293 if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
294 result = max_state( result, temp_result );
300 /* Moved this computation up here so we can add it
301 * to perf */
302 inode_space_pct = (float)fsp.fsu_ffree*100/fsp.fsu_files;
305 asprintf (&perf, "%s %s", perf,
306 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
307 dused_units, units,
308 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*dtotal_units)), */
309 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*dtotal_units)), */
310 FALSE, 0, /* inode_space_pct, */
311 FALSE, 0));; /* dtotal_units)); */
313 if (disk_result==STATE_OK && erronly && !verbose)
314 continue;
316 if (disk_result!=STATE_OK || verbose>=0) {
317 asprintf (&output, ("%s %s %.0f %s (%.0f%% inode=%.0f%%);"),
318 output,
319 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
320 dfree_units,
321 units,
322 dfree_pct,
323 inode_space_pct);
324 }
326 /* Need to do a similar one
327 asprintf (&details, _("%s\n\
328 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
329 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
330 me->me_devname, me->me_type, me->me_mountdir,
331 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
332 */
334 }
336 }
338 if (verbose > 2)
339 asprintf (&output, "%s%s", output, details);
342 printf ("DISK %s%s|%s\n", state_text (result), output, perf);
343 return result;
344 }
348 /* process command-line arguments */
349 int
350 process_arguments (int argc, char **argv)
351 {
352 int c;
353 struct parameter_list *se;
354 struct parameter_list *temp_list;
355 int result = OK;
356 struct stat *stat_buf;
358 int option = 0;
359 static struct option longopts[] = {
360 {"timeout", required_argument, 0, 't'},
361 {"warning", required_argument, 0, 'w'},
362 {"critical", required_argument, 0, 'c'},
363 {"iwarning", required_argument, 0, 'W'},
364 /* Dang, -C is taken. We might want to reshuffle this. */
365 {"icritical", required_argument, 0, 'K'},
366 {"local", required_argument, 0, 'l'},
367 {"kilobytes", required_argument, 0, 'k'},
368 {"megabytes", required_argument, 0, 'm'},
369 {"units", required_argument, 0, 'u'},
370 {"path", required_argument, 0, 'p'},
371 {"partition", required_argument, 0, 'p'},
372 {"exclude_device", required_argument, 0, 'x'},
373 {"exclude-type", required_argument, 0, 'X'},
374 {"mountpoint", no_argument, 0, 'M'},
375 {"errors-only", no_argument, 0, 'e'},
376 {"exact-match", no_argument, 0, 'E'},
377 {"verbose", no_argument, 0, 'v'},
378 {"quiet", no_argument, 0, 'q'},
379 {"clear", no_argument, 0, 'C'},
380 {"version", no_argument, 0, 'V'},
381 {"help", no_argument, 0, 'h'},
382 {0, 0, 0, 0}
383 };
385 if (argc < 2)
386 return ERROR;
388 np_add_name(&fs_exclude_list, "iso9660");
390 for (c = 1; c < argc; c++)
391 if (strcmp ("-to", argv[c]) == 0)
392 strcpy (argv[c], "-t");
394 while (1) {
395 c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
397 if (c == -1 || c == EOF)
398 break;
400 switch (c) {
401 case 't': /* timeout period */
402 if (is_integer (optarg)) {
403 timeout_interval = atoi (optarg);
404 break;
405 }
406 else {
407 usage2 (_("Timeout interval must be a positive integer"), optarg);
408 }
410 /* See comments for 'c' */
411 case 'w': /* warning threshold */
412 if (strstr(optarg, "%")) {
413 if (*optarg == '@') {
414 warn_freespace_percent = optarg;
415 } else {
416 asprintf(&warn_freespace_percent, "@%s", optarg);
417 }
418 } else {
419 if (*optarg == '@') {
420 warn_freespace_units = optarg;
421 } else {
422 asprintf(&warn_freespace_units, "@%s", optarg);
423 }
424 }
425 break;
427 /* Awful mistake where the range values do not make sense. Normally,
428 you alert if the value is within the range, but since we are using
429 freespace, we have to alert if outside the range. Thus we artifically
430 force @ at the beginning of the range, so that it is backwards compatible
431 */
432 case 'c': /* critical threshold */
433 if (strstr(optarg, "%")) {
434 if (*optarg == '@') {
435 crit_freespace_percent = optarg;
436 } else {
437 asprintf(&crit_freespace_percent, "@%s", optarg);
438 }
439 } else {
440 if (*optarg == '@') {
441 crit_freespace_units = optarg;
442 } else {
443 asprintf(&crit_freespace_units, "@%s", optarg);
444 }
445 }
446 break;
448 case 'W': /* warning inode threshold */
449 warn_usedinodes_percent = optarg;
450 break;
451 case 'K': /* critical inode threshold */
452 crit_usedinodes_percent = optarg;
453 break;
454 case 'u':
455 if (units)
456 free(units);
457 if (! strcmp (optarg, "bytes")) {
458 mult = (uintmax_t)1;
459 units = strdup ("B");
460 } else if (! strcmp (optarg, "kB")) {
461 mult = (uintmax_t)1024;
462 units = strdup ("kB");
463 } else if (! strcmp (optarg, "MB")) {
464 mult = (uintmax_t)1024 * 1024;
465 units = strdup ("MB");
466 } else if (! strcmp (optarg, "GB")) {
467 mult = (uintmax_t)1024 * 1024 * 1024;
468 units = strdup ("GB");
469 } else if (! strcmp (optarg, "TB")) {
470 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
471 units = strdup ("TB");
472 } else {
473 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
474 }
475 if (units == NULL)
476 die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
477 break;
478 case 'k': /* display mountpoint */
479 mult = 1024;
480 if (units)
481 free(units);
482 units = strdup ("kB");
483 break;
484 case 'm': /* display mountpoint */
485 mult = 1024 * 1024;
486 if (units)
487 free(units);
488 units = strdup ("MB");
489 break;
490 case 'l':
491 show_local_fs = 1;
492 break;
493 case 'p': /* select path */
494 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
495 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
496 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
497 crit_usedinodes_percent)) {
498 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
499 }
500 se = np_add_parameter(&path_select_list, optarg);
501 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
502 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
503 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
504 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
505 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
506 break;
507 case 'x': /* exclude path or partition */
508 np_add_name(&dp_exclude_list, optarg);
509 break;
510 case 'X': /* exclude file system type */
511 np_add_name(&fs_exclude_list, optarg);
512 break;
513 case 'v': /* verbose */
514 verbose++;
515 break;
516 case 'q': /* verbose */
517 verbose--;
518 break;
519 case 'e':
520 erronly = TRUE;
521 break;
522 case 'E':
523 exact_match = TRUE;
524 break;
525 case 'M': /* display mountpoint */
526 display_mntp = TRUE;
527 break;
528 case 'C':
529 warn_freespace_units = NULL;
530 crit_freespace_units = NULL;
531 warn_usedspace_units = NULL;
532 crit_usedspace_units = NULL;
533 warn_freespace_percent = NULL;
534 crit_freespace_percent = NULL;
535 warn_usedspace_percent = NULL;
536 crit_usedspace_percent = NULL;
537 warn_usedinodes_percent = NULL;
538 crit_usedinodes_percent = NULL;
539 break;
540 case 'V': /* version */
541 print_revision (progname, revision);
542 exit (STATE_OK);
543 case 'h': /* help */
544 print_help ();
545 exit (STATE_OK);
546 case '?': /* help */
547 usage (_("Unknown argument"));
548 }
549 }
551 /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
552 c = optind;
553 if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
554 warn_usedspace_percent = argv[c++];
556 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
557 crit_usedspace_percent = argv[c++];
559 if (argc > c && path == NULL) {
560 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
561 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
562 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
563 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
564 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
565 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
566 }
568 if (units == NULL) {
569 units = strdup ("MB");
570 mult = (uintmax_t)1024 * 1024;
571 }
573 if (path_select_list) {
574 temp_list = path_select_list;
575 stat_buf = malloc(sizeof *stat_buf);
576 while (temp_list) {
577 /* Stat each entry to check that dir exists */
578 if (stat (temp_list->name, &stat_buf[0])) {
579 printf("DISK %s - ", _("CRITICAL"));
580 die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
581 }
582 /* if (validate_arguments (temp_list->w_df,
583 temp_list->c_df,
584 temp_list->w_dfp,
585 temp_list->c_dfp,
586 temp_list->w_idfp,
587 temp_list->c_idfp,
588 temp_list->name) == ERROR)
589 result = ERROR;
590 */
591 temp_list = temp_list->name_next;
592 }
593 free(stat_buf);
594 return result;
595 } else {
596 return TRUE;
597 /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
598 }
599 }
603 void
604 print_path (const char *mypath)
605 {
606 if (mypath == NULL)
607 printf ("\n");
608 else
609 printf (_(" for %s\n"), mypath);
611 //return;
612 }
616 /* TODO: Remove?
618 int
619 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
620 {
621 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
622 printf (_("INPUT ERROR: No thresholds specified"));
623 print_path (mypath);
624 return ERROR;
625 }
626 else if ((wp >= 0.0 || cp >= 0.0) &&
627 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
628 printf (_("\
629 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
630 cp, wp);
631 print_path (mypath);
632 return ERROR;
633 }
634 else if ((iwp >= 0.0 || icp >= 0.0) &&
635 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
636 printf (_("\
637 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
638 icp, iwp);
639 print_path (mypath);
640 return ERROR;
641 }
642 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
643 printf (_("\
644 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
645 (unsigned long)c, (unsigned long)w);
646 print_path (mypath);
647 return ERROR;
648 }
650 return OK;
651 }
653 */
661 void
662 print_help (void)
663 {
664 print_revision (progname, revision);
666 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
667 printf (COPYRIGHT, copyright, email);
669 printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
670 printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
672 printf ("\n\n");
674 print_usage ();
676 printf (_(UT_HELP_VRSN));
678 printf (" %s\n", "-w, --warning=INTEGER");
679 printf (" %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
680 printf (" %s\n", "-w, --warning=PERCENT%");
681 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
682 printf (" %s\n", "-W, --iwarning=PERCENT%");
683 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
684 printf (" %s\n", "-K, --icritical=PERCENT%");
685 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
686 printf (" %s\n", "-c, --critical=INTEGER");
687 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
688 printf (" %s\n", "-c, --critical=PERCENT%");
689 printf (" %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
690 printf (" %s\n", "-C, --clear");
691 printf (" %s\n", _("Clear thresholds"));
692 printf (" %s\n", "-u, --units=STRING");
693 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
694 printf (" %s\n", "-k, --kilobytes");
695 printf (" %s\n", _("Same as '--units kB'"));
696 printf (" %s\n", "-m, --megabytes");
697 printf (" %s\n", _("Same as '--units MB'"));
698 printf (" %s\n", "-l, --local");
699 printf (" %s\n", _("Only check local filesystems"));
700 printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
701 printf (" %s\n", _("Path or partition (may be repeated)"));
702 printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
703 printf (" %s\n", _("Ignore device (only works if -p unspecified)"));
704 printf (" %s\n", _("-X, --exclude-type=TYPE <STRING>"));
705 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
706 printf (" %s\n", "-m, --mountpoint");
707 printf (" %s\n", _("Display the mountpoint instead of the partition"));
708 printf (" %s\n", "-E, --exact-match");
709 printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
710 printf (" %s\n", "-e, --errors-only");
711 printf (" %s\n", _("Display only devices/mountpoints with errors"));
712 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
713 printf (_(UT_VERBOSE));
714 printf ("\n");
715 printf ("%s\n", _("Examples:"));
716 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
717 printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
718 printf (_(UT_SUPPORT));
719 }
723 void
724 print_usage (void)
725 {
726 printf (_("Usage:"));
727 printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
728 printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");
729 }