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);
124 double calculate_percent(uintmax_t, uintmax_t);
126 double w_dfp = -1.0;
127 double c_dfp = -1.0;
128 char *path;
129 char *exclude_device;
130 char *units;
131 uintmax_t mult = 1024 * 1024;
132 int verbose = 0;
133 int erronly = FALSE;
134 int display_mntp = FALSE;
135 int exact_match = FALSE;
136 char *warn_freespace_units = NULL;
137 char *crit_freespace_units = NULL;
138 char *warn_freespace_percent = NULL;
139 char *crit_freespace_percent = NULL;
140 char *warn_usedspace_units = NULL;
141 char *crit_usedspace_units = NULL;
142 char *warn_usedspace_percent = NULL;
143 char *crit_usedspace_percent = NULL;
144 char *warn_usedinodes_percent = NULL;
145 char *crit_usedinodes_percent = NULL;
148 int
149 main (int argc, char **argv)
150 {
151 int result = STATE_UNKNOWN;
152 int disk_result = STATE_UNKNOWN;
153 char *output;
154 char *details;
155 char *perf;
156 double inode_space_pct;
157 uintmax_t total, available, available_to_root, used;
158 double dfree_pct = -1, dused_pct = -1;
159 double dused_units, dfree_units, dtotal_units;
160 double dused_inodes_percent;
161 int temp_result;
163 struct mount_entry *me;
164 struct fs_usage fsp;
165 struct parameter_list *temp_list, *path;
166 struct name_list *seen = NULL;
168 output = strdup (" - free space:");
169 details = strdup ("");
170 perf = strdup ("");
172 setlocale (LC_ALL, "");
173 bindtextdomain (PACKAGE, LOCALEDIR);
174 textdomain (PACKAGE);
176 mount_list = read_file_system_list (0);
178 if (process_arguments (argc, argv) == ERROR)
179 usage4 (_("Could not parse arguments"));
181 /* If a list of paths has not been selected, find entire
182 mount list and create list of paths
183 */
184 if (! path_select_list) {
185 for (me = mount_list; me; me = me->me_next) {
186 path = np_add_parameter(&path_select_list, me->me_mountdir);
187 path->best_match = me;
188 set_thresholds(&path->freespace_units, warn_freespace_units, crit_freespace_units);
189 set_thresholds(&path->freespace_percent, warn_freespace_percent, crit_freespace_percent);
190 set_thresholds(&path->usedspace_units, warn_usedspace_units, crit_usedspace_units);
191 set_thresholds(&path->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
192 set_thresholds(&path->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
193 }
194 } else {
195 np_set_best_match(path_select_list, mount_list, exact_match);
197 /* Error if no match found for specified paths */
198 temp_list = path_select_list;
199 while (temp_list) {
200 if (! temp_list->best_match) {
201 die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
202 }
203 temp_list = temp_list->name_next;
204 }
205 }
207 /* Process for every path in list */
208 for (path = path_select_list; path; path=path->name_next) {
209 me = path->best_match;
211 /* Filters */
213 /* Remove filesystems already seen */
214 if (np_seen_name(seen, me->me_mountdir)) {
215 continue;
216 } else {
217 np_add_name(&seen, me->me_mountdir);
218 }
219 /* Skip remote filesystems if we're not interested in them */
220 if (me->me_remote && show_local_fs) {
221 continue;
222 /* Skip pseudo fs's if we haven't asked for all fs's */
223 } else if (me->me_dummy && !show_all_fs) {
224 continue;
225 /* Skip excluded fstypes */
226 } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
227 continue;
228 /* Skip excluded fs's */
229 } else if (dp_exclude_list &&
230 (np_find_name (dp_exclude_list, me->me_devname) ||
231 np_find_name (dp_exclude_list, me->me_mountdir))) {
232 continue;
233 }
235 get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
237 if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
238 total = fsp.fsu_blocks;
239 available = fsp.fsu_bavail;
240 available_to_root = fsp.fsu_bfree;
241 used = total - available_to_root;
243 dused_pct = calculate_percent( used, used + available ); /* used + available can never be > uintmax */
245 dfree_pct = 100 - dused_pct;
246 dused_units = used*fsp.fsu_blocksize/mult;
247 dfree_units = available*fsp.fsu_blocksize/mult;
248 dtotal_units = total*fsp.fsu_blocksize/mult;
249 dused_inodes_percent = calculate_percent(fsp.fsu_files - fsp.fsu_ffree, fsp.fsu_files);
251 if (verbose >= 3) {
252 printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n",
253 me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
254 }
256 /* Threshold comparisons */
258 temp_result = get_status(dfree_units, path->freespace_units);
259 if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
260 result = max_state( result, temp_result );
262 temp_result = get_status(dfree_pct, path->freespace_percent);
263 if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
264 result = max_state( result, temp_result );
266 temp_result = get_status(dused_units, path->usedspace_units);
267 if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
268 result = max_state( result, temp_result );
270 temp_result = get_status(dused_pct, path->usedspace_percent);
271 if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
272 result = max_state( result, temp_result );
274 temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
275 if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
276 result = max_state( result, temp_result );
282 /* Moved this computation up here so we can add it
283 * to perf */
284 inode_space_pct = (1 - dused_inodes_percent) * 100;
287 asprintf (&perf, "%s %s", perf,
288 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
289 dused_units, units,
290 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*dtotal_units)), */
291 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*dtotal_units)), */
292 FALSE, 0, /* inode_space_pct - this is not meant to be here???, */
293 FALSE, 0));; /* dtotal_units)); */
295 if (disk_result==STATE_OK && erronly && !verbose)
296 continue;
298 if (disk_result!=STATE_OK || verbose>=0) {
299 asprintf (&output, "%s %s %.0f %s (%.0f%%",
300 output,
301 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
302 dfree_units,
303 units,
304 dfree_pct);
305 if (dused_inodes_percent < 0) {
306 asprintf(&output, "%s inode=-);", output);
307 } else {
308 asprintf(&output, "%s inode=%.0f%%);", output, (1 - dused_inodes_percent) * 100);
309 }
310 }
312 /* TODO: Need to do a similar debug line
313 asprintf (&details, _("%s\n\
314 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
315 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
316 me->me_devname, me->me_type, me->me_mountdir,
317 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
318 */
320 }
322 }
324 if (verbose > 2)
325 asprintf (&output, "%s%s", output, details);
328 printf ("DISK %s%s|%s\n", state_text (result), output, perf);
329 return result;
330 }
333 double calculate_percent(uintmax_t value, uintmax_t total) {
334 double pct = -1;
335 /* I don't understand the below, but it is taken from coreutils' df */
336 /* Seems to be calculating pct, in the best possible way */
337 if (value <= TYPE_MAXIMUM(uintmax_t) / 100
338 && total != 0) {
339 uintmax_t u100 = value * 100;
340 pct = u100 / total + (u100 % total != 0);
341 } else {
342 /* Possible rounding errors - see coreutils' df for more explanation */
343 double u = value;
344 double t = total;
345 if (t) {
346 long int lipct = pct = u * 100 / t;
347 double ipct = lipct;
349 /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
350 if (ipct - 1 < pct && pct <= ipct + 1)
351 pct = ipct + (ipct < pct);
352 }
353 }
354 return pct;
355 }
357 /* process command-line arguments */
358 int
359 process_arguments (int argc, char **argv)
360 {
361 int c;
362 struct parameter_list *se;
363 struct parameter_list *temp_list;
364 int result = OK;
365 struct stat *stat_buf;
367 int option = 0;
368 static struct option longopts[] = {
369 {"timeout", required_argument, 0, 't'},
370 {"warning", required_argument, 0, 'w'},
371 {"critical", required_argument, 0, 'c'},
372 {"iwarning", required_argument, 0, 'W'},
373 /* Dang, -C is taken. We might want to reshuffle this. */
374 {"icritical", required_argument, 0, 'K'},
375 {"local", required_argument, 0, 'l'},
376 {"kilobytes", required_argument, 0, 'k'},
377 {"megabytes", required_argument, 0, 'm'},
378 {"units", required_argument, 0, 'u'},
379 {"path", required_argument, 0, 'p'},
380 {"partition", required_argument, 0, 'p'},
381 {"exclude_device", required_argument, 0, 'x'},
382 {"exclude-type", required_argument, 0, 'X'},
383 {"mountpoint", no_argument, 0, 'M'},
384 {"errors-only", no_argument, 0, 'e'},
385 {"exact-match", no_argument, 0, 'E'},
386 {"verbose", no_argument, 0, 'v'},
387 {"quiet", no_argument, 0, 'q'},
388 {"clear", no_argument, 0, 'C'},
389 {"version", no_argument, 0, 'V'},
390 {"help", no_argument, 0, 'h'},
391 {0, 0, 0, 0}
392 };
394 if (argc < 2)
395 return ERROR;
397 np_add_name(&fs_exclude_list, "iso9660");
399 for (c = 1; c < argc; c++)
400 if (strcmp ("-to", argv[c]) == 0)
401 strcpy (argv[c], "-t");
403 while (1) {
404 c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
406 if (c == -1 || c == EOF)
407 break;
409 switch (c) {
410 case 't': /* timeout period */
411 if (is_integer (optarg)) {
412 timeout_interval = atoi (optarg);
413 break;
414 }
415 else {
416 usage2 (_("Timeout interval must be a positive integer"), optarg);
417 }
419 /* See comments for 'c' */
420 case 'w': /* warning threshold */
421 if (strstr(optarg, "%")) {
422 if (*optarg == '@') {
423 warn_freespace_percent = optarg;
424 } else {
425 asprintf(&warn_freespace_percent, "@%s", optarg);
426 }
427 } else {
428 if (*optarg == '@') {
429 warn_freespace_units = optarg;
430 } else {
431 asprintf(&warn_freespace_units, "@%s", optarg);
432 }
433 }
434 break;
436 /* Awful mistake where the range values do not make sense. Normally,
437 you alert if the value is within the range, but since we are using
438 freespace, we have to alert if outside the range. Thus we artifically
439 force @ at the beginning of the range, so that it is backwards compatible
440 */
441 case 'c': /* critical threshold */
442 if (strstr(optarg, "%")) {
443 if (*optarg == '@') {
444 crit_freespace_percent = optarg;
445 } else {
446 asprintf(&crit_freespace_percent, "@%s", optarg);
447 }
448 } else {
449 if (*optarg == '@') {
450 crit_freespace_units = optarg;
451 } else {
452 asprintf(&crit_freespace_units, "@%s", optarg);
453 }
454 }
455 break;
457 case 'W': /* warning inode threshold */
458 warn_usedinodes_percent = optarg;
459 break;
460 case 'K': /* critical inode threshold */
461 crit_usedinodes_percent = optarg;
462 break;
463 case 'u':
464 if (units)
465 free(units);
466 if (! strcmp (optarg, "bytes")) {
467 mult = (uintmax_t)1;
468 units = strdup ("B");
469 } else if (! strcmp (optarg, "kB")) {
470 mult = (uintmax_t)1024;
471 units = strdup ("kB");
472 } else if (! strcmp (optarg, "MB")) {
473 mult = (uintmax_t)1024 * 1024;
474 units = strdup ("MB");
475 } else if (! strcmp (optarg, "GB")) {
476 mult = (uintmax_t)1024 * 1024 * 1024;
477 units = strdup ("GB");
478 } else if (! strcmp (optarg, "TB")) {
479 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
480 units = strdup ("TB");
481 } else {
482 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
483 }
484 if (units == NULL)
485 die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
486 break;
487 case 'k': /* display mountpoint */
488 mult = 1024;
489 if (units)
490 free(units);
491 units = strdup ("kB");
492 break;
493 case 'm': /* display mountpoint */
494 mult = 1024 * 1024;
495 if (units)
496 free(units);
497 units = strdup ("MB");
498 break;
499 case 'l':
500 show_local_fs = 1;
501 break;
502 case 'p': /* select path */
503 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
504 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
505 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
506 crit_usedinodes_percent)) {
507 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
508 }
509 se = np_add_parameter(&path_select_list, optarg);
510 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
511 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
512 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
513 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
514 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
515 break;
516 case 'x': /* exclude path or partition */
517 np_add_name(&dp_exclude_list, optarg);
518 break;
519 case 'X': /* exclude file system type */
520 np_add_name(&fs_exclude_list, optarg);
521 break;
522 case 'v': /* verbose */
523 verbose++;
524 break;
525 case 'q': /* verbose */
526 verbose--;
527 break;
528 case 'e':
529 erronly = TRUE;
530 break;
531 case 'E':
532 exact_match = TRUE;
533 break;
534 case 'M': /* display mountpoint */
535 display_mntp = TRUE;
536 break;
537 case 'C':
538 warn_freespace_units = NULL;
539 crit_freespace_units = NULL;
540 warn_usedspace_units = NULL;
541 crit_usedspace_units = NULL;
542 warn_freespace_percent = NULL;
543 crit_freespace_percent = NULL;
544 warn_usedspace_percent = NULL;
545 crit_usedspace_percent = NULL;
546 warn_usedinodes_percent = NULL;
547 crit_usedinodes_percent = NULL;
548 break;
549 case 'V': /* version */
550 print_revision (progname, revision);
551 exit (STATE_OK);
552 case 'h': /* help */
553 print_help ();
554 exit (STATE_OK);
555 case '?': /* help */
556 usage (_("Unknown argument"));
557 }
558 }
560 /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
561 c = optind;
562 if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
563 warn_usedspace_percent = argv[c++];
565 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
566 crit_usedspace_percent = argv[c++];
568 if (argc > c && path == NULL) {
569 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
570 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
571 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
572 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
573 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
574 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
575 }
577 if (units == NULL) {
578 units = strdup ("MB");
579 mult = (uintmax_t)1024 * 1024;
580 }
582 if (path_select_list) {
583 temp_list = path_select_list;
584 stat_buf = malloc(sizeof *stat_buf);
585 while (temp_list) {
586 /* Stat each entry to check that dir exists */
587 if (stat (temp_list->name, &stat_buf[0])) {
588 printf("DISK %s - ", _("CRITICAL"));
589 die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
590 }
591 /* if (validate_arguments (temp_list->w_df,
592 temp_list->c_df,
593 temp_list->w_dfp,
594 temp_list->c_dfp,
595 temp_list->w_idfp,
596 temp_list->c_idfp,
597 temp_list->name) == ERROR)
598 result = ERROR;
599 */
600 temp_list = temp_list->name_next;
601 }
602 free(stat_buf);
603 return result;
604 } else {
605 return TRUE;
606 /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
607 }
608 }
612 void
613 print_path (const char *mypath)
614 {
615 if (mypath == NULL)
616 printf ("\n");
617 else
618 printf (_(" for %s\n"), mypath);
620 //return;
621 }
625 /* TODO: Remove?
627 int
628 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
629 {
630 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
631 printf (_("INPUT ERROR: No thresholds specified"));
632 print_path (mypath);
633 return ERROR;
634 }
635 else if ((wp >= 0.0 || cp >= 0.0) &&
636 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
637 printf (_("\
638 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
639 cp, wp);
640 print_path (mypath);
641 return ERROR;
642 }
643 else if ((iwp >= 0.0 || icp >= 0.0) &&
644 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
645 printf (_("\
646 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
647 icp, iwp);
648 print_path (mypath);
649 return ERROR;
650 }
651 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
652 printf (_("\
653 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
654 (unsigned long)c, (unsigned long)w);
655 print_path (mypath);
656 return ERROR;
657 }
659 return OK;
660 }
662 */
670 void
671 print_help (void)
672 {
673 print_revision (progname, revision);
675 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
676 printf (COPYRIGHT, copyright, email);
678 printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
679 printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
681 printf ("\n\n");
683 print_usage ();
685 printf (_(UT_HELP_VRSN));
687 printf (" %s\n", "-w, --warning=INTEGER");
688 printf (" %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
689 printf (" %s\n", "-w, --warning=PERCENT%");
690 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
691 printf (" %s\n", "-W, --iwarning=PERCENT%");
692 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
693 printf (" %s\n", "-K, --icritical=PERCENT%");
694 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
695 printf (" %s\n", "-c, --critical=INTEGER");
696 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
697 printf (" %s\n", "-c, --critical=PERCENT%");
698 printf (" %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
699 printf (" %s\n", "-C, --clear");
700 printf (" %s\n", _("Clear thresholds"));
701 printf (" %s\n", "-u, --units=STRING");
702 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
703 printf (" %s\n", "-k, --kilobytes");
704 printf (" %s\n", _("Same as '--units kB'"));
705 printf (" %s\n", "-m, --megabytes");
706 printf (" %s\n", _("Same as '--units MB'"));
707 printf (" %s\n", "-l, --local");
708 printf (" %s\n", _("Only check local filesystems"));
709 printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
710 printf (" %s\n", _("Path or partition (may be repeated)"));
711 printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
712 printf (" %s\n", _("Ignore device (only works if -p unspecified)"));
713 printf (" %s\n", _("-X, --exclude-type=TYPE <STRING>"));
714 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
715 printf (" %s\n", "-m, --mountpoint");
716 printf (" %s\n", _("Display the mountpoint instead of the partition"));
717 printf (" %s\n", "-E, --exact-match");
718 printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
719 printf (" %s\n", "-e, --errors-only");
720 printf (" %s\n", _("Display only devices/mountpoints with errors"));
721 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
722 printf (_(UT_VERBOSE));
723 printf ("\n");
724 printf ("%s\n", _("Examples:"));
725 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
726 printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
727 printf (_(UT_SUPPORT));
728 }
732 void
733 print_usage (void)
734 {
735 printf (_("Usage:"));
736 printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
737 printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");
738 }