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, dfree_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);
250 dfree_inodes_percent = 100 - dused_inodes_percent;
252 if (verbose >= 3) {
253 printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g\n",
254 me->me_mountdir, dused_pct, dfree_pct, dused_units, dfree_units, dtotal_units, dused_inodes_percent);
255 }
257 /* Threshold comparisons */
259 temp_result = get_status(dfree_units, path->freespace_units);
260 if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
261 result = max_state( result, temp_result );
263 temp_result = get_status(dfree_pct, path->freespace_percent);
264 if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
265 result = max_state( result, temp_result );
267 temp_result = get_status(dused_units, path->usedspace_units);
268 if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
269 result = max_state( result, temp_result );
271 temp_result = get_status(dused_pct, path->usedspace_percent);
272 if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
273 result = max_state( result, temp_result );
275 temp_result = get_status(dused_inodes_percent, path->usedinodes_percent);
276 if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
277 result = max_state( result, temp_result );
279 asprintf (&perf, "%s %s", perf,
280 perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
281 dused_units, units,
282 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)w_df, (uintmax_t)((1.0-w_dfp/100.0)*dtotal_units)), */
283 FALSE, 0, /* min ((uintmax_t)dtotal_units-(uintmax_t)c_df, (uintmax_t)((1.0-c_dfp/100.0)*dtotal_units)), */
284 FALSE, 0, /* inode_space_pct - this is not meant to be here???, */
285 FALSE, 0));; /* dtotal_units)); */
287 if (disk_result==STATE_OK && erronly && !verbose)
288 continue;
290 if (disk_result!=STATE_OK || verbose>=0) {
291 asprintf (&output, "%s %s %.0f %s (%.0f%%",
292 output,
293 (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
294 dfree_units,
295 units,
296 dfree_pct);
297 if (dused_inodes_percent < 0) {
298 asprintf(&output, "%s inode=-);", output);
299 } else {
300 asprintf(&output, "%s inode=%.0f%%);", output, dfree_inodes_percent );
301 }
302 }
304 /* TODO: Need to do a similar debug line
305 asprintf (&details, _("%s\n\
306 %.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
307 details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
308 me->me_devname, me->me_type, me->me_mountdir,
309 (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
310 */
312 }
314 }
316 if (verbose > 2)
317 asprintf (&output, "%s%s", output, details);
320 printf ("DISK %s%s|%s\n", state_text (result), output, perf);
321 return result;
322 }
325 double calculate_percent(uintmax_t value, uintmax_t total) {
326 double pct = -1;
327 /* I don't understand the below, but it is taken from coreutils' df */
328 /* Seems to be calculating pct, in the best possible way */
329 if (value <= TYPE_MAXIMUM(uintmax_t) / 100
330 && total != 0) {
331 uintmax_t u100 = value * 100;
332 pct = u100 / total + (u100 % total != 0);
333 } else {
334 /* Possible rounding errors - see coreutils' df for more explanation */
335 double u = value;
336 double t = total;
337 if (t) {
338 long int lipct = pct = u * 100 / t;
339 double ipct = lipct;
341 /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
342 if (ipct - 1 < pct && pct <= ipct + 1)
343 pct = ipct + (ipct < pct);
344 }
345 }
346 return pct;
347 }
349 /* process command-line arguments */
350 int
351 process_arguments (int argc, char **argv)
352 {
353 int c;
354 struct parameter_list *se;
355 struct parameter_list *temp_list;
356 int result = OK;
357 struct stat *stat_buf;
359 int option = 0;
360 static struct option longopts[] = {
361 {"timeout", required_argument, 0, 't'},
362 {"warning", required_argument, 0, 'w'},
363 {"critical", required_argument, 0, 'c'},
364 {"iwarning", required_argument, 0, 'W'},
365 /* Dang, -C is taken. We might want to reshuffle this. */
366 {"icritical", required_argument, 0, 'K'},
367 {"local", required_argument, 0, 'l'},
368 {"kilobytes", required_argument, 0, 'k'},
369 {"megabytes", required_argument, 0, 'm'},
370 {"units", required_argument, 0, 'u'},
371 {"path", required_argument, 0, 'p'},
372 {"partition", required_argument, 0, 'p'},
373 {"exclude_device", required_argument, 0, 'x'},
374 {"exclude-type", required_argument, 0, 'X'},
375 {"mountpoint", no_argument, 0, 'M'},
376 {"errors-only", no_argument, 0, 'e'},
377 {"exact-match", no_argument, 0, 'E'},
378 {"verbose", no_argument, 0, 'v'},
379 {"quiet", no_argument, 0, 'q'},
380 {"clear", no_argument, 0, 'C'},
381 {"version", no_argument, 0, 'V'},
382 {"help", no_argument, 0, 'h'},
383 {0, 0, 0, 0}
384 };
386 if (argc < 2)
387 return ERROR;
389 np_add_name(&fs_exclude_list, "iso9660");
391 for (c = 1; c < argc; c++)
392 if (strcmp ("-to", argv[c]) == 0)
393 strcpy (argv[c], "-t");
395 while (1) {
396 c = getopt_long (argc, argv, "+?VqhveCt:c:w:K:W:u:p:x:X:mklME", longopts, &option);
398 if (c == -1 || c == EOF)
399 break;
401 switch (c) {
402 case 't': /* timeout period */
403 if (is_integer (optarg)) {
404 timeout_interval = atoi (optarg);
405 break;
406 }
407 else {
408 usage2 (_("Timeout interval must be a positive integer"), optarg);
409 }
411 /* See comments for 'c' */
412 case 'w': /* warning threshold */
413 if (strstr(optarg, "%")) {
414 if (*optarg == '@') {
415 warn_freespace_percent = optarg;
416 } else {
417 asprintf(&warn_freespace_percent, "@%s", optarg);
418 }
419 } else {
420 if (*optarg == '@') {
421 warn_freespace_units = optarg;
422 } else {
423 asprintf(&warn_freespace_units, "@%s", optarg);
424 }
425 }
426 break;
428 /* Awful mistake where the range values do not make sense. Normally,
429 you alert if the value is within the range, but since we are using
430 freespace, we have to alert if outside the range. Thus we artifically
431 force @ at the beginning of the range, so that it is backwards compatible
432 */
433 case 'c': /* critical threshold */
434 if (strstr(optarg, "%")) {
435 if (*optarg == '@') {
436 crit_freespace_percent = optarg;
437 } else {
438 asprintf(&crit_freespace_percent, "@%s", optarg);
439 }
440 } else {
441 if (*optarg == '@') {
442 crit_freespace_units = optarg;
443 } else {
444 asprintf(&crit_freespace_units, "@%s", optarg);
445 }
446 }
447 break;
449 case 'W': /* warning inode threshold */
450 warn_usedinodes_percent = optarg;
451 break;
452 case 'K': /* critical inode threshold */
453 crit_usedinodes_percent = optarg;
454 break;
455 case 'u':
456 if (units)
457 free(units);
458 if (! strcmp (optarg, "bytes")) {
459 mult = (uintmax_t)1;
460 units = strdup ("B");
461 } else if (! strcmp (optarg, "kB")) {
462 mult = (uintmax_t)1024;
463 units = strdup ("kB");
464 } else if (! strcmp (optarg, "MB")) {
465 mult = (uintmax_t)1024 * 1024;
466 units = strdup ("MB");
467 } else if (! strcmp (optarg, "GB")) {
468 mult = (uintmax_t)1024 * 1024 * 1024;
469 units = strdup ("GB");
470 } else if (! strcmp (optarg, "TB")) {
471 mult = (uintmax_t)1024 * 1024 * 1024 * 1024;
472 units = strdup ("TB");
473 } else {
474 die (STATE_UNKNOWN, _("unit type %s not known\n"), optarg);
475 }
476 if (units == NULL)
477 die (STATE_UNKNOWN, _("failed allocating storage for '%s'\n"), "units");
478 break;
479 case 'k': /* display mountpoint */
480 mult = 1024;
481 if (units)
482 free(units);
483 units = strdup ("kB");
484 break;
485 case 'm': /* display mountpoint */
486 mult = 1024 * 1024;
487 if (units)
488 free(units);
489 units = strdup ("MB");
490 break;
491 case 'l':
492 show_local_fs = 1;
493 break;
494 case 'p': /* select path */
495 if (! (warn_freespace_units || crit_freespace_units || warn_freespace_percent ||
496 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
497 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
498 crit_usedinodes_percent)) {
499 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -p\n"));
500 }
501 se = np_add_parameter(&path_select_list, optarg);
502 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
503 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
504 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
505 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
506 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
507 break;
508 case 'x': /* exclude path or partition */
509 np_add_name(&dp_exclude_list, optarg);
510 break;
511 case 'X': /* exclude file system type */
512 np_add_name(&fs_exclude_list, optarg);
513 break;
514 case 'v': /* verbose */
515 verbose++;
516 break;
517 case 'q': /* verbose */
518 verbose--;
519 break;
520 case 'e':
521 erronly = TRUE;
522 break;
523 case 'E':
524 exact_match = TRUE;
525 break;
526 case 'M': /* display mountpoint */
527 display_mntp = TRUE;
528 break;
529 case 'C':
530 warn_freespace_units = NULL;
531 crit_freespace_units = NULL;
532 warn_usedspace_units = NULL;
533 crit_usedspace_units = NULL;
534 warn_freespace_percent = NULL;
535 crit_freespace_percent = NULL;
536 warn_usedspace_percent = NULL;
537 crit_usedspace_percent = NULL;
538 warn_usedinodes_percent = NULL;
539 crit_usedinodes_percent = NULL;
540 break;
541 case 'V': /* version */
542 print_revision (progname, revision);
543 exit (STATE_OK);
544 case 'h': /* help */
545 print_help ();
546 exit (STATE_OK);
547 case '?': /* help */
548 usage (_("Unknown argument"));
549 }
550 }
552 /* Support for "check_disk warn crit [fs]" with thresholds at used% level */
553 c = optind;
554 if (warn_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
555 warn_usedspace_percent = argv[c++];
557 if (crit_usedspace_percent == NULL && argc > c && is_intnonneg (argv[c]))
558 crit_usedspace_percent = argv[c++];
560 if (argc > c && path == NULL) {
561 se = np_add_parameter(&path_select_list, strdup(argv[c++]));
562 set_thresholds(&se->freespace_units, warn_freespace_units, crit_freespace_units);
563 set_thresholds(&se->freespace_percent, warn_freespace_percent, crit_freespace_percent);
564 set_thresholds(&se->usedspace_units, warn_usedspace_units, crit_usedspace_units);
565 set_thresholds(&se->usedspace_percent, warn_usedspace_percent, crit_usedspace_percent);
566 set_thresholds(&se->usedinodes_percent, warn_usedinodes_percent, crit_usedinodes_percent);
567 }
569 if (units == NULL) {
570 units = strdup ("MB");
571 mult = (uintmax_t)1024 * 1024;
572 }
574 if (path_select_list) {
575 temp_list = path_select_list;
576 stat_buf = malloc(sizeof *stat_buf);
577 while (temp_list) {
578 /* Stat each entry to check that dir exists */
579 if (stat (temp_list->name, &stat_buf[0])) {
580 printf("DISK %s - ", _("CRITICAL"));
581 die (STATE_CRITICAL, _("%s does not exist\n"), temp_list->name);
582 }
583 /* if (validate_arguments (temp_list->w_df,
584 temp_list->c_df,
585 temp_list->w_dfp,
586 temp_list->c_dfp,
587 temp_list->w_idfp,
588 temp_list->c_idfp,
589 temp_list->name) == ERROR)
590 result = ERROR;
591 */
592 temp_list = temp_list->name_next;
593 }
594 free(stat_buf);
595 return result;
596 } else {
597 return TRUE;
598 /* return validate_arguments (w_df, c_df, w_dfp, c_dfp, w_idfp, c_idfp, NULL); */
599 }
600 }
604 void
605 print_path (const char *mypath)
606 {
607 if (mypath == NULL)
608 printf ("\n");
609 else
610 printf (_(" for %s\n"), mypath);
612 //return;
613 }
617 /* TODO: Remove?
619 int
620 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
621 {
622 if (w < 0 && c < 0 && wp < 0.0 && cp < 0.0) {
623 printf (_("INPUT ERROR: No thresholds specified"));
624 print_path (mypath);
625 return ERROR;
626 }
627 else if ((wp >= 0.0 || cp >= 0.0) &&
628 (wp < 0.0 || cp < 0.0 || wp > 100.0 || cp > 100.0 || cp > wp)) {
629 printf (_("\
630 INPUT ERROR: C_DFP (%f) should be less than W_DFP (%.1f) and both should be between zero and 100 percent, inclusive"),
631 cp, wp);
632 print_path (mypath);
633 return ERROR;
634 }
635 else if ((iwp >= 0.0 || icp >= 0.0) &&
636 (iwp < 0.0 || icp < 0.0 || iwp > 100.0 || icp > 100.0 || icp > iwp)) {
637 printf (_("\
638 INPUT ERROR: C_IDFP (%f) should be less than W_IDFP (%.1f) and both should be between zero and 100 percent, inclusive"),
639 icp, iwp);
640 print_path (mypath);
641 return ERROR;
642 }
643 else if ((w > 0 || c > 0) && (w == 0 || c == 0 || c > w)) {
644 printf (_("\
645 INPUT ERROR: C_DF (%lu) should be less than W_DF (%lu) and both should be greater than zero"),
646 (unsigned long)c, (unsigned long)w);
647 print_path (mypath);
648 return ERROR;
649 }
651 return OK;
652 }
654 */
662 void
663 print_help (void)
664 {
665 print_revision (progname, revision);
667 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
668 printf (COPYRIGHT, copyright, email);
670 printf ("%s\n", _("This plugin checks the amount of used disk space on a mounted file system"));
671 printf ("%s\n", _("and generates an alert if free space is less than one of the threshold values"));
673 printf ("\n\n");
675 print_usage ();
677 printf (_(UT_HELP_VRSN));
679 printf (" %s\n", "-w, --warning=INTEGER");
680 printf (" %s\n", _("Exit with WARNING status if less than INTEGER units of disk are free"));
681 printf (" %s\n", "-w, --warning=PERCENT%");
682 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of disk space is free"));
683 printf (" %s\n", "-W, --iwarning=PERCENT%");
684 printf (" %s\n", _("Exit with WARNING status if less than PERCENT of inode space is free"));
685 printf (" %s\n", "-K, --icritical=PERCENT%");
686 printf (" %s\n", _("Exit with CRITICAL status if less than PERCENT of inode space is free"));
687 printf (" %s\n", "-c, --critical=INTEGER");
688 printf (" %s\n", _("Exit with CRITICAL status if less than INTEGER units of disk are free"));
689 printf (" %s\n", "-c, --critical=PERCENT%");
690 printf (" %s\n", _("Exit with CRITCAL status if less than PERCENT of disk space is free"));
691 printf (" %s\n", "-C, --clear");
692 printf (" %s\n", _("Clear thresholds"));
693 printf (" %s\n", "-u, --units=STRING");
694 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
695 printf (" %s\n", "-k, --kilobytes");
696 printf (" %s\n", _("Same as '--units kB'"));
697 printf (" %s\n", "-m, --megabytes");
698 printf (" %s\n", _("Same as '--units MB'"));
699 printf (" %s\n", "-l, --local");
700 printf (" %s\n", _("Only check local filesystems"));
701 printf (" %s\n", "-p, --path=PATH, --partition=PARTITION");
702 printf (" %s\n", _("Path or partition (may be repeated)"));
703 printf (" %s\n", "-x, --exclude_device=PATH <STRING>");
704 printf (" %s\n", _("Ignore device (only works if -p unspecified)"));
705 printf (" %s\n", _("-X, --exclude-type=TYPE <STRING>"));
706 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)"));
707 printf (" %s\n", "-m, --mountpoint");
708 printf (" %s\n", _("Display the mountpoint instead of the partition"));
709 printf (" %s\n", "-E, --exact-match");
710 printf (" %s\n", _("For paths or partitions specified with -p, only check for exact paths"));
711 printf (" %s\n", "-e, --errors-only");
712 printf (" %s\n", _("Display only devices/mountpoints with errors"));
713 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
714 printf (_(UT_VERBOSE));
715 printf ("\n");
716 printf ("%s\n", _("Examples:"));
717 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
718 printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
719 printf (_(UT_SUPPORT));
720 }
724 void
725 print_usage (void)
726 {
727 printf (_("Usage:"));
728 printf (" %s -w limit -c limit [-p path | -x device] [-t timeout]", progname);
729 printf ("[-m] [-e] [-W limit] [-K limit] [-v] [-q] [-E]\n");
730 }