Back to index

nagios-plugins  1.4.16
Enumerations | Functions | Variables
check_disk.c File Reference
#include "common.h"
#include <assert.h>
#include "popen.h"
#include "utils.h"
#include "utils_disk.h"
#include <stdarg.h>
#include "fsusage.h"
#include "mountlist.h"
#include "intprops.h"
#include "regex.h"

Go to the source code of this file.

Enumerations

enum  { SYNC_OPTION = CHAR_MAX + 1, NO_SYNC_OPTION, BLOCK_SIZE_OPTION }

Functions

int process_arguments (int, char **)
void print_path (const char *mypath)
void set_all_thresholds (struct parameter_list *path)
int validate_arguments (uintmax_t, uintmax_t, double, double, double, double, char *)
void print_help (void)
void print_usage (void)
double calculate_percent (uintmax_t, uintmax_t)
void stat_path (struct parameter_list *p)
void get_stats (struct parameter_list *p, struct fs_usage *fsp)
void get_path_stats (struct parameter_list *p, struct fs_usage *fsp)
int main (int argc, char **argv)

Variables

const char * progname = "check_disk"
const char * program_name = "check_disk"
const char * copyright = "1999-2008"
const char * email = "nagiosplug-devel@lists.sourceforge.net"
static int inode_format = 1
static int show_all_fs = 1
static int show_local_fs = 0
static int stat_remote_fs = 0
static struct name_listfs_exclude_list
static struct name_listdp_exclude_list
static struct parameter_listpath_select_list = NULL
static struct mount_entrymount_list
double w_dfp = -1.0
double c_dfp = -1.0
char * path
char * exclude_device
char * units
uintmax_t mult = 1024 * 1024
int verbose = 0
int erronly = FALSE
int display_mntp = FALSE
int exact_match = FALSE
char * warn_freespace_units = NULL
char * crit_freespace_units = NULL
char * warn_freespace_percent = NULL
char * crit_freespace_percent = NULL
char * warn_usedspace_units = NULL
char * crit_usedspace_units = NULL
char * warn_usedspace_percent = NULL
char * crit_usedspace_percent = NULL
char * warn_usedinodes_percent = NULL
char * crit_usedinodes_percent = NULL
char * warn_freeinodes_percent = NULL
char * crit_freeinodes_percent = NULL
int path_selected = FALSE
char * group = NULL
struct stat * stat_buf
struct name_listseen = NULL

Enumeration Type Documentation

anonymous enum
Enumerator:
SYNC_OPTION 
NO_SYNC_OPTION 
BLOCK_SIZE_OPTION 

Definition at line 106 of file check_disk.c.


Function Documentation

double calculate_percent ( uintmax_t  value,
uintmax_t  total 
)

Definition at line 367 of file check_disk.c.

                                                           {
  double pct = -1;
  /* I don't understand the below, but it is taken from coreutils' df */
  /* Seems to be calculating pct, in the best possible way */
  if (value <= TYPE_MAXIMUM(uintmax_t) / 100
    && total != 0) {
    uintmax_t u100 = value * 100;
    pct = u100 / total + (u100 % total != 0);
  } else {
    /* Possible rounding errors - see coreutils' df for more explanation */
    double u = value;
    double t = total;
    if (t) {
      long int lipct = pct = u * 100 / t;
      double ipct = lipct;

      /* Like 'pct = ceil (dpct);', but without ceil - from coreutils again */
      if (ipct - 1 < pct && pct <= ipct + 1)
        pct = ipct + (ipct < pct);
    }
  }
  return pct;
}

Here is the caller graph for this function:

void get_path_stats ( struct parameter_list p,
struct fs_usage fsp 
)

Definition at line 996 of file check_disk.c.

                                                                {
  p->total = fsp->fsu_blocks;
  /* 2007-12-08 - Workaround for Gnulib reporting insanely high available
  * space on BSD (the actual value should be negative but fsp->fsu_bavail
  * is unsigned) */
  p->available = fsp->fsu_bavail > fsp->fsu_bfree ? 0 : fsp->fsu_bavail;
  p->available_to_root = fsp->fsu_bfree;
  p->used = p->total - p->available_to_root;
  
  p->dused_units = p->used*fsp->fsu_blocksize/mult;
  p->dfree_units = p->available*fsp->fsu_blocksize/mult;
  p->dtotal_units = p->total*fsp->fsu_blocksize/mult;
  p->inodes_total = fsp->fsu_files;      /* Total file nodes. */
  p->inodes_free  = fsp->fsu_ffree;      /* Free file nodes. */
  np_add_name(&seen, p->best_match->me_mountdir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void get_stats ( struct parameter_list p,
struct fs_usage fsp 
)

Definition at line 944 of file check_disk.c.

                                                           {
  struct parameter_list *p_list;
  struct fs_usage tmpfsp;
  int first = 1;

  if (p->group == NULL) {
    get_path_stats(p,fsp);
  } else {
    /* find all group members */
    for (p_list = path_select_list; p_list; p_list=p_list->name_next) {
      if (p_list->group && ! (strcmp(p_list->group, p->group))) {
        stat_path(p_list);
        get_fs_usage (p_list->best_match->me_mountdir, p_list->best_match->me_devname, &tmpfsp);
        get_path_stats(p_list, &tmpfsp); 
        if (verbose >= 3)
          printf("Group %s: adding %llu blocks sized %llu, (%s) used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n",
                 p_list->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p_list->best_match->me_mountdir, p_list->dused_units, p_list->dfree_units,
                 p_list->dtotal_units, mult);

        /* prevent counting the first FS of a group twice since its parameter_list entry 
         * is used to carry the information of all file systems of the entire group */
        if (! first) {
          p->total += p_list->total;
          p->available += p_list->available;
          p->available_to_root += p_list->available_to_root;
          p->used += p_list->used;
            
          p->dused_units += p_list->dused_units;
          p->dfree_units += p_list->dfree_units;
          p->dtotal_units += p_list->dtotal_units;
          p->inodes_total += p_list->inodes_total;
          p->inodes_free  += p_list->inodes_free;
        }
        first = 0;
      }
      if (verbose >= 3) 
        printf("Group %s now has: used_units=%g free_units=%g total_units=%g fsu_blocksize=%llu mult=%llu\n",
               p->group, tmpfsp.fsu_bavail, tmpfsp.fsu_blocksize, p->best_match->me_mountdir, p->dused_units,
               p->dfree_units, p->dtotal_units, mult);
    }
    /* modify devname and mountdir for output */
    p->best_match->me_mountdir = p->best_match->me_devname = p->group;
  }
  /* finally calculate percentages for either plain FS or summed up group */
  p->dused_pct = calculate_percent( p->used, p->used + p->available );       /* used + available can never be > uintmax */
  p->dfree_pct = 100 - p->dused_pct;
  p->dused_inodes_percent = calculate_percent(p->inodes_total - p->inodes_free, p->inodes_total);
  p->dfree_inodes_percent = 100 - p->dused_inodes_percent;
  
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 157 of file check_disk.c.

{
  int result = STATE_UNKNOWN;
  int disk_result = STATE_UNKNOWN;
  char *output;
  char *details;
  char *perf;
  char *preamble;
  double inode_space_pct;
  double warning_high_tide;
  double critical_high_tide;
  int temp_result;

  struct mount_entry *me;
  struct fs_usage fsp, tmpfsp;
  struct parameter_list *temp_list, *path;

  preamble = strdup (" - free space:");
  output = strdup ("");
  details = strdup ("");
  perf = strdup ("");
  stat_buf = malloc(sizeof *stat_buf);

  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  mount_list = read_file_system_list (0);

  /* Parse extra opts if any */
  argv = np_extra_opts (&argc, argv, progname);

  if (process_arguments (argc, argv) == ERROR)
    usage4 (_("Could not parse arguments"));

  /* If a list of paths has not been selected, find entire
     mount list and create list of paths
   */
  if (path_selected == FALSE) {
    for (me = mount_list; me; me = me->me_next) {
      if (! (path = np_find_parameter(path_select_list, me->me_mountdir))) {
        path = np_add_parameter(&path_select_list, me->me_mountdir);
      }
      path->best_match = me;
      path->group = group;
      set_all_thresholds(path);
    }
  }
  np_set_best_match(path_select_list, mount_list, exact_match);

  /* Error if no match found for specified paths */
  temp_list = path_select_list;

  while (temp_list) {
    if (! temp_list->best_match) {
      die (STATE_CRITICAL, _("DISK %s: %s not found\n"), _("CRITICAL"), temp_list->name);
    }

    temp_list = temp_list->name_next;
  }

  /* Process for every path in list */
  for (path = path_select_list; path; path=path->name_next) {

    if (verbose >= 3 && path->freespace_percent->warning != NULL && path->freespace_percent->critical != NULL)
      printf("Thresholds(pct) for %s warn: %f crit %f\n",path->name, path->freespace_percent->warning->end,
                                                         path->freespace_percent->critical->end);

    if (verbose >= 3 && path->group != NULL)
      printf("Group of %s: %s\n",path->name,path->group);

    /* reset disk result */
    disk_result = STATE_UNKNOWN;

    me = path->best_match;

    /* Filters */

    /* Remove filesystems already seen */
    if (np_seen_name(seen, me->me_mountdir)) {
      continue;
    } 
    np_add_name(&seen, me->me_mountdir);

    if (path->group == NULL) {
      /* Skip remote filesystems if we're not interested in them */
      if (me->me_remote && show_local_fs) {
        if (stat_remote_fs)
          stat_path(path);
        continue;
      /* Skip pseudo fs's if we haven't asked for all fs's */
      } else if (me->me_dummy && !show_all_fs) {
        continue;
      /* Skip excluded fstypes */
      } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) {
        continue;
      /* Skip excluded fs's */
      } else if (dp_exclude_list &&
               (np_find_name (dp_exclude_list, me->me_devname) ||
                np_find_name (dp_exclude_list, me->me_mountdir))) {
        continue;
      }

      stat_path(path);
      get_fs_usage (me->me_mountdir, me->me_devname, &fsp);
    }

    if (fsp.fsu_blocks && strcmp ("none", me->me_mountdir)) {
      get_stats (path, &fsp);

      if (verbose >= 3) {
        printf ("For %s, used_pct=%g free_pct=%g used_units=%g free_units=%g total_units=%g used_inodes_pct=%g free_inodes_pct=%g fsp.fsu_blocksize=%llu mult=%llu\n",
          me->me_mountdir, path->dused_pct, path->dfree_pct, path->dused_units, path->dfree_units, path->dtotal_units, path->dused_inodes_percent, path->dfree_inodes_percent, fsp.fsu_blocksize, mult);
      }

      /* Threshold comparisons */

      temp_result = get_status(path->dfree_units, path->freespace_units);
      if (verbose >=3) printf("Freespace_units result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      temp_result = get_status(path->dfree_pct, path->freespace_percent);
      if (verbose >=3) printf("Freespace%% result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      temp_result = get_status(path->dused_units, path->usedspace_units);
      if (verbose >=3) printf("Usedspace_units result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      temp_result = get_status(path->dused_pct, path->usedspace_percent);
      if (verbose >=3) printf("Usedspace_percent result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      temp_result = get_status(path->dused_inodes_percent, path->usedinodes_percent);
      if (verbose >=3) printf("Usedinodes_percent result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      temp_result = get_status(path->dfree_inodes_percent, path->freeinodes_percent);
      if (verbose >=3) printf("Freeinodes_percent result=%d\n", temp_result);
      disk_result = max_state( disk_result, temp_result );

      result = max_state(result, disk_result);

      /* What a mess of units. The output shows free space, the perf data shows used space. Yikes!
         Hack here. Trying to get warn/crit levels from freespace_(units|percent) for perf
         data. Assumption that start=0. Roll on new syntax...
      */

      /* *_high_tide must be reinitialized at each run */
      warning_high_tide = UINT_MAX;
      critical_high_tide = UINT_MAX;

      if (path->freespace_units->warning != NULL) {
        warning_high_tide = path->dtotal_units - path->freespace_units->warning->end;
      }
      if (path->freespace_percent->warning != NULL) {
        warning_high_tide = abs( min( (double) warning_high_tide, (double) (1.0 - path->freespace_percent->warning->end/100)*path->dtotal_units ));
      }
      if (path->freespace_units->critical != NULL) {
        critical_high_tide = path->dtotal_units - path->freespace_units->critical->end;
      }
      if (path->freespace_percent->critical != NULL) {
        critical_high_tide = abs( min( (double) critical_high_tide, (double) (1.0 - path->freespace_percent->critical->end/100)*path->dtotal_units ));
      }

      /* Nb: *_high_tide are unset when == UINT_MAX */
      asprintf (&perf, "%s %s", perf,
                perfdata ((!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
                          path->dused_units, units,
                          (warning_high_tide != UINT_MAX ? TRUE : FALSE), warning_high_tide,
                          (critical_high_tide != UINT_MAX ? TRUE : FALSE), critical_high_tide,
                          TRUE, 0,
                          TRUE, path->dtotal_units));

      if (disk_result==STATE_OK && erronly && !verbose)
        continue;

      asprintf (&output, "%s %s %.0f %s (%.0f%%",
                output,
                (!strcmp(me->me_mountdir, "none") || display_mntp) ? me->me_devname : me->me_mountdir,
                path->dfree_units,
                units,
                path->dfree_pct);
      if (path->dused_inodes_percent < 0) {
        asprintf(&output, "%s inode=-);", output);
      } else {
        asprintf(&output, "%s inode=%.0f%%);", output, path->dfree_inodes_percent );
      }

      /* TODO: Need to do a similar debug line
      asprintf (&details, _("%s\n\
%.0f of %.0f %s (%.0f%% inode=%.0f%%) free on %s (type %s mounted on %s) warn:%lu crit:%lu warn%%:%.0f%% crit%%:%.0f%%"),
                details, dfree_units, dtotal_units, units, dfree_pct, inode_space_pct,
                me->me_devname, me->me_type, me->me_mountdir,
                (unsigned long)w_df, (unsigned long)c_df, w_dfp, c_dfp);
      */

    }

  }

  if (verbose >= 2)
    asprintf (&output, "%s%s", output, details);


  printf ("DISK %s%s%s|%s\n", state_text (result), (erronly && result==STATE_OK) ? "" : preamble, output, perf);
  return result;
}

Here is the call graph for this function:

void print_help ( void  )
void print_path ( const char *  mypath)

Definition at line 763 of file check_disk.c.

{
  if (mypath == NULL)
    printf ("\n");
  else
    printf (_(" for %s\n"), mypath);
}
void print_usage ( void  )

Definition at line 389 of file check_cpqarray.c.

{
  printf("cpqarrayd [options]\n");
  printf("   -h         prints this text\n");
  printf("   -d         enables debugging\n");
}
int process_arguments ( int  argc,
char **  argv 
)
void set_all_thresholds ( struct parameter_list path)
void stat_path ( struct parameter_list p)

Definition at line 929 of file check_disk.c.

{
  /* Stat entry to check that dir exists and is accessible */
  if (verbose >= 3)
    printf("calling stat on %s\n", p->name);
  if (stat (p->name, &stat_buf[0])) {
    if (verbose >= 3)
      printf("stat failed on %s\n", p->name);
    printf("DISK %s - ", _("CRITICAL"));
    die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int validate_arguments ( uintmax_t  ,
uintmax_t  ,
double  ,
double  ,
double  ,
double  ,
char *   
)

Variable Documentation

double c_dfp = -1.0

Definition at line 129 of file check_disk.c.

const char* copyright = "1999-2008"

Definition at line 31 of file check_disk.c.

Definition at line 149 of file check_disk.c.

Definition at line 141 of file check_disk.c.

Definition at line 139 of file check_disk.c.

Definition at line 147 of file check_disk.c.

Definition at line 145 of file check_disk.c.

Definition at line 143 of file check_disk.c.

Definition at line 136 of file check_disk.c.

struct name_list* dp_exclude_list [static]

Definition at line 97 of file check_disk.c.

const char* email = "nagiosplug-devel@lists.sourceforge.net"

Definition at line 32 of file check_disk.c.

int erronly = FALSE

Definition at line 135 of file check_disk.c.

Definition at line 137 of file check_disk.c.

Definition at line 131 of file check_disk.c.

struct name_list* fs_exclude_list [static]

Definition at line 95 of file check_disk.c.

char* group = NULL

Definition at line 151 of file check_disk.c.

int inode_format = 1 [static]

Definition at line 57 of file check_disk.c.

struct mount_entry* mount_list [static]

Definition at line 102 of file check_disk.c.

uintmax_t mult = 1024 * 1024

Definition at line 133 of file check_disk.c.

char* path

Definition at line 130 of file check_disk.c.

struct parameter_list* path_select_list = NULL [static]

Definition at line 99 of file check_disk.c.

Definition at line 150 of file check_disk.c.

const char* progname = "check_disk"

Definition at line 29 of file check_disk.c.

const char* program_name = "check_disk"

Definition at line 30 of file check_disk.c.

struct name_list* seen = NULL

Definition at line 153 of file check_disk.c.

int show_all_fs = 1 [static]

Definition at line 61 of file check_disk.c.

int show_local_fs = 0 [static]

Definition at line 64 of file check_disk.c.

struct stat* stat_buf

Definition at line 152 of file check_disk.c.

int stat_remote_fs = 0 [static]

Definition at line 67 of file check_disk.c.

char* units

Definition at line 132 of file check_disk.c.

int verbose = 0

Definition at line 134 of file check_disk.c.

double w_dfp = -1.0

Definition at line 128 of file check_disk.c.

Definition at line 148 of file check_disk.c.

Definition at line 140 of file check_disk.c.

Definition at line 138 of file check_disk.c.

Definition at line 146 of file check_disk.c.

Definition at line 144 of file check_disk.c.

Definition at line 142 of file check_disk.c.