Code

use GNU fileutils for check_disk
authorKarl DeBisschop <kdebisschop@users.sourceforge.net>
Tue, 18 Mar 2003 07:48:44 +0000 (07:48 +0000)
committerKarl DeBisschop <kdebisschop@users.sourceforge.net>
Tue, 18 Mar 2003 07:48:44 +0000 (07:48 +0000)
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@430 f882894a-f735-0410-b71e-b25c423dba1c

configure.in
lib/Makefile.am
plugins/check_disk.c

index 24f66d203a6ea77db4615fc07194b3cd2f310d0f..78a454ffe2078f808d5b8eaaf1c7dabc3825e8d1 100644 (file)
@@ -30,31 +30,6 @@ AC_MINIX
 AC_PROG_MAKE_SET
 AC_PROG_AWK
 
-# Check for SunOS statfs brokenness wrt partitions 2GB and larger.
-# If <sys/vfs.h> 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 <sys/types.h>
-#include <sys/vfs.h>],
-[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 <inttypes.h> exists,
+# doesn't clash with <sys/types.h>, and declares uintmax_t.
+
+AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h,
+[AC_TRY_COMPILE(
+  [#include <sys/types.h>
+#include <inttypes.h>],
+  [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 <inttypes.h> exists, doesn't clash with <sys/types.h>,
+   and declares uintmax_t. ])
+fi
 
-dnl Linux
-AC_CHECK_HEADERS(sys/vfs.h,
-                 [AC_TRY_COMPILE([#include <sys/vfs.h>],
-                                 [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 <sys/param.h>
-#include <sys/mount.h>],
-                                 [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 <sys/vfs.h> 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 <sys/types.h>
+#include <sys/vfs.h>],
+[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)
 
index 9a26e419be607ecb68aaf47585c8a1956634ba18..6353d01c343726671741a5bb47b4aec7294366ec 100644 (file)
@@ -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)
index 485ae82260701bdccaa2b8db73d82fa50241f65d..2558f6d3897d765d2bcb3f99c65e4313b73056d8 100644 (file)
@@ -55,18 +55,81 @@ const char *options = "\
     Print version information\n";
 
 #include "common.h"
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#include <assert.h>
 #include "popen.h"
 #include "utils.h"
 #include <stdarg.h>
+#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 <inttypes.h>
-#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 <sys/vfs.h>
-#else
-#include <sys/param.h>
-#include <sys/mount.h>
-#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);
 }