From 18270bf20a930f713850fb8c2efa20b2a0f212c1 Mon Sep 17 00:00:00 2001 From: Karl DeBisschop Date: Tue, 18 Mar 2003 07:48:44 +0000 Subject: [PATCH] use GNU fileutils for check_disk git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@430 f882894a-f735-0410-b71e-b25c423dba1c --- configure.in | 84 +++++++++-------- lib/Makefile.am | 4 +- plugins/check_disk.c | 220 +++++++++++++++---------------------------- 3 files changed, 126 insertions(+), 182 deletions(-) diff --git a/configure.in b/configure.in index 24f66d2..78a454f 100644 --- a/configure.in +++ b/configure.in @@ -30,31 +30,6 @@ AC_MINIX AC_PROG_MAKE_SET AC_PROG_AWK -# Check for SunOS statfs brokenness wrt partitions 2GB and larger. -# If exists and struct statfs has a member named f_spare, -# enable the work-around code in fsusage.c. -AC_MSG_CHECKING([for statfs that truncates block counts]) -AC_CACHE_VAL(fu_cv_sys_truncating_statfs, -[AC_TRY_COMPILE([ -#if !defined(sun) && !defined(__sun) -choke -- this is a workaround for a Sun-specific problem -#endif -#include -#include ], -[struct statfs t; long c = *(t.f_spare);], -fu_cv_sys_truncating_statfs=yes -AC_MSG_RESULT(yes), -fu_cv_sys_truncating_statfs=no -AC_MSG_RESULT(no), -)]) -if test $fu_cv_sys_truncating_statfs = yes; then - AC_DEFINE(STATFS_TRUNCATES_BLOCK_COUNTS, 1, -[ Define if the block counts reported by statfs may be truncated to 2GB - and the correct values may be stored in the f_spare array. - (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem. - SunOS 4.1.1 seems not to be affected.)]) -fi - saved_srcdir=$srcdir srcdir=$srcdir/lib test -f $srcdir/getloadavg.c \ @@ -484,19 +459,49 @@ AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(signal.h strings.h string.h syslog.h unistd.h uio.h errno.h regex.h sys/types.h sys/time.h sys/socket.h sys/loadavg.h) AC_CHECK_HEADERS(stdarg.h sys/unistd.h unistd.h ctype.h stdlib.h) +AC_CHECK_HEADERS(limits.h sys/param.h sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h fcntl.h sys/statfs.h sys/dustat.h sys/statvfs.h) + +# Define HAVE_INTTYPES_H if exists, +# doesn't clash with , and declares uintmax_t. + +AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, +[AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_inttypes_h=yes, + jm_ac_cv_header_inttypes_h=no)]) + +if test $jm_ac_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, +[Define if exists, doesn't clash with , + and declares uintmax_t. ]) +fi -dnl Linux -AC_CHECK_HEADERS(sys/vfs.h, - [AC_TRY_COMPILE([#include ], - [struct statfs buf; long foo; statfs ("/", &buf); foo = buf.f_namelen;], - [AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if statfs struct can be found])])]) - -dnl FreeBSD -AC_CHECK_HEADERS(sys/param.h sys/mount.h, - [AC_TRY_COMPILE([#include -#include ], - [struct statfs buf; int foo; statfs ("/", &buf); foo = buf.f_flags;], - [AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if statfs struct can be found])])]) +# Check for SunOS statfs brokenness wrt partitions 2GB and larger. +# If exists and struct statfs has a member named f_spare, +# enable the work-around code in fsusage.c. +AC_MSG_CHECKING([for statfs that truncates block counts]) +AC_CACHE_VAL(fu_cv_sys_truncating_statfs, +[AC_TRY_COMPILE([ +#if !defined(sun) && !defined(__sun) +choke -- this is a workaround for a Sun-specific problem +#endif +#include +#include ], +[struct statfs t; long c = *(t.f_spare);], +fu_cv_sys_truncating_statfs=yes +AC_MSG_RESULT(yes), +fu_cv_sys_truncating_statfs=no +AC_MSG_RESULT(no), +)]) +if test $fu_cv_sys_truncating_statfs = yes; then + AC_DEFINE(STATFS_TRUNCATES_BLOCK_COUNTS, 1, +[ Define if the block counts reported by statfs may be truncated to 2GB + and the correct values may be stored in the f_spare array. + (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem. + SunOS 4.1.1 seems not to be affected.)]) +fi dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -955,6 +960,11 @@ fi AC_DEFINE_UNQUOTED(DF_COMMAND,"$with_df_command",[path and args for df command]) +dnl jm_LIST_MOUNTED_FILESYSTEMS([list_mounted_fs=yes], [list_mounted_fs=no]) +jm_FSTYPENAME +jm_FILE_SYSTEM_USAGE([space=yes], [space=no]) +jm_AFS + AC_PATH_PROG(PATH_TO_PING,ping) AC_PATH_PROG(PATH_TO_PING6,ping6) diff --git a/lib/Makefile.am b/lib/Makefile.am index 9a26e41..6353d01 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,8 +2,8 @@ noinst_LIBRARIES = libnagiosplug.a -noinst_HEADERS = getopt.h +noinst_HEADERS = getopt.h fsusage.h mountlist.h -libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c +libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c fsusage.c mountlist.c INCLUDES = -I$(srcdir) diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 485ae82..2558f6d 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c @@ -55,18 +55,81 @@ const char *options = "\ Print version information\n"; #include "common.h" +#if HAVE_INTTYPES_H +# include +#endif +#include #include "popen.h" #include "utils.h" #include +#include "../lib/fsusage.h" + +/* If nonzero, show inode information. */ +static int inode_format; + +/* If nonzero, show even filesystems with zero size or + uninteresting types. */ +static int show_all_fs; + +/* If nonzero, show only local filesystems. */ +static int show_local_fs; + +/* If nonzero, output data for each filesystem corresponding to a + command line argument -- even if it's a dummy (automounter) entry. */ +static int show_listed_fs; + +/* If positive, the units to use when printing sizes; + if negative, the human-readable base. */ +static int output_block_size; + +/* If nonzero, invoke the `sync' system call before getting any usage data. + Using this option can make df very slow, especially with many or very + busy disks. Note that this may make a difference on some systems -- + SunOs4.1.3, for one. It is *not* necessary on Linux. */ +static int require_sync = 0; + +/* A filesystem type to display. */ + +struct fs_type_list +{ + char *fs_name; + struct fs_type_list *fs_next; +}; + +/* Linked list of filesystem types to display. + If `fs_select_list' is NULL, list all types. + This table is generated dynamically from command-line options, + rather than hardcoding into the program what it thinks are the + valid filesystem types; let the user specify any filesystem type + they want to, and if there are any filesystems of that type, they + will be shown. + + Some filesystem types: + 4.2 4.3 ufs nfs swap ignore io vm efs dbg */ + +static struct fs_type_list *fs_select_list; + +/* Linked list of filesystem types to omit. + If the list is empty, don't exclude any types. */ + +static struct fs_type_list *fs_exclude_list; + +/* Linked list of mounted filesystems. */ +static struct mount_entry *mount_list; + +/* For long options that have no equivalent short option, use a + non-character as a pseudo short option, starting with CHAR_MAX + 1. */ +enum +{ + SYNC_OPTION = CHAR_MAX + 1, + NO_SYNC_OPTION, + BLOCK_SIZE_OPTION +}; #ifdef _AIX #pragma alloca #endif -#if HAVE_INTTYPES_H -# include -#endif - int process_arguments (int, char **); int validate_arguments (void); int check_disk (int usp, int free_disk); @@ -99,151 +162,22 @@ main (int argc, char **argv) char mntp[MAX_INPUT_BUFFER]; char *output = ""; -#ifdef HAVE_STRUCT_STATFS -#ifdef HAVE_SYS_VFS_H -#include -#else -#include -#include -#endif - struct statfs buf; -#endif + struct fs_usage fsp; + char *disk; if (process_arguments (argc, argv) != OK) usage ("Could not parse arguments\n"); -#ifdef HAVE_STRUCT_STATFS - - if (statfs (path, &buf) == -1) { - switch (errno) - { -#ifdef ENOTDIR - case ENOTDIR: - terminate (STATE_UNKNOWN, "A component of the path prefix is not a directory.\n"); -#endif -#ifdef ENAMETOOLONG - case ENAMETOOLONG: - terminate (STATE_UNKNOWN, "path is too long.\n"); -#endif -#ifdef ENOENT - case ENOENT: - terminate (STATE_UNKNOWN, "The file referred to by path does not exist.\n"); -#endif -#ifdef EACCES - case EACCES: - terminate (STATE_UNKNOWN, "Search permission is denied for a component of the path prefix of path.\n"); -#endif -#ifdef ELOOP - case ELOOP: - terminate (STATE_UNKNOWN, "Too many symbolic links were encountered in translating path.\n"); -#endif -#ifdef EFAULT - case EFAULT: - terminate (STATE_UNKNOWN, "Buf or path points to an invalid address.\n"); -#endif -#ifdef EIO - case EIO: - terminate (STATE_UNKNOWN, "An I/O error occurred while reading from or writing to the file system.\n"); -#endif -#ifdef ENOMEM - case ENOMEM: - terminate (STATE_UNKNOWN, "Insufficient kernel memory was available.\n"); -#endif -#ifdef ENOSYS - case ENOSYS: - terminate (STATE_UNKNOWN, "The filesystem path is on does not support statfs.\n"); -#endif - } - } + get_fs_usage (path, disk, &fsp); - usp = (buf.f_blocks - buf.f_bavail) / buf.f_blocks; - disk_result = check_disk (usp, buf.f_bavail); + usp = (fsp.fsu_blocks - fsp.fsu_bavail) / fsp.fsu_blocks; + disk_result = check_disk (usp, fsp.fsu_bavail); result = disk_result; - asprintf (&output, "%ld of %ld kB free (%ld-byte blocks)", - buf.f_bavail*buf.f_bsize/1024, buf.f_blocks*buf.f_bsize/1024, buf.f_bsize); - -#else - - asprintf (&command_line, "%s %s", DF_COMMAND, path); - - if (verbose>0) - printf ("%s ==> ", command_line); - - child_process = spopen (command_line); - if (child_process == NULL) { - printf ("Could not open pipe: %s\n", command_line); - return STATE_UNKNOWN; - } - - child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); - if (child_stderr == NULL) { - printf ("Could not open stderr for %s\n", command_line); - } - - while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { - - if (!index (input_buffer, '/')) - continue; - - /* Fixes AIX /proc fs which lists - for size values */ - if (strstr (input_buffer, "/proc ") == input_buffer) - continue; - - if (sscanf (input_buffer, "%s %d %d %d %d%% %s", file_system, - &total_disk, &used_disk, &free_disk, &usp, mntp) == 6 || - sscanf (input_buffer, "%s %*s %d %d %d %d%% %s", file_system, - &total_disk, &used_disk, &free_disk, &usp, mntp) == 6) { - - if (strcmp(exclude_device,file_system) == 0 || - strcmp(exclude_device,mntp) == 0) { - if (verbose>0) - printf ("ignoring %s.", file_system); - continue; - } - - disk_result = check_disk (usp, free_disk); - - if (strcmp (file_system, "none") == 0) - strncpy (file_system, mntp, MAX_INPUT_BUFFER-1); - - if (disk_result==STATE_OK && erronly && !verbose) - continue; - - if (disk_result!=STATE_OK || verbose>=0) - asprintf (&output, "%s [%d kB (%d%%) free on %s]", output, - free_disk, 100 - usp, display_mntp ? mntp : file_system); - - result = max_state (result, disk_result); - } - - else { - printf ("Unable to read output:\n%s\n%s\n", command_line, input_buffer); - return result; - } - - } - - /* If we get anything on stderr, at least set warning */ - while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { - if (result != STATE_CRITICAL) { - result = STATE_WARNING; - } - } - - /* close stderr */ - if (child_stderr) - (void) fclose (child_stderr); - - /* close the pipe */ - if (spclose(child_process)!=0 && result!=STATE_CRITICAL) - result = STATE_WARNING; - - if (usp < 0) - terminate (result, "Disk \"%s\" not mounted or nonexistant\n", path); - else if (result == STATE_UNKNOWN) - terminate (result, "Unable to read output\n%s\n%s\n", command_line, input_buffer); - -#endif + asprintf (&output, "%llu of %llu kB (%2.0f%%) free (%d-byte blocks)", + fsp.fsu_bavail*fsp.fsu_blocksize/1024, + fsp.fsu_blocks*fsp.fsu_blocksize/1024, + (double)fsp.fsu_bavail*100/fsp.fsu_blocks, + fsp.fsu_blocksize); terminate (result, "DISK %s %s\n", state_text (result), output); } -- 2.30.2