Code

e7a3b2161d01a501446bfab4a77f0017c118edd0
[nagiosplug.git] / plugins / check_disk.c
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
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)
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 */
244      
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 );
278       
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;
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;
357 /* process command-line arguments */
358 int
359 process_arguments (int argc, char **argv)
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   }
612 void
613 print_path (const char *mypath) 
615   if (mypath == NULL)
616     printf ("\n");
617   else
618     printf (_(" for %s\n"), mypath);
620   //return;
625 /* TODO: Remove?
627 int
628 validate_arguments (uintmax_t w, uintmax_t c, double wp, double cp, double iwp, double icp, char *mypath)
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   }
658   
659   return OK;
662 */
670 void
671 print_help (void)
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));
732 void
733 print_usage (void)
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");