diff options
| author | Karl DeBisschop <kdebisschop@users.sourceforge.net> | 2003-03-18 07:48:44 +0000 |
|---|---|---|
| committer | Karl DeBisschop <kdebisschop@users.sourceforge.net> | 2003-03-18 07:48:44 +0000 |
| commit | 18270bf20a930f713850fb8c2efa20b2a0f212c1 (patch) | |
| tree | a5735acd1fdd4dcfe50d67b2aaf14809fc560864 | |
| parent | cc7522b25bfc0157eb51777f8345812e79760179 (diff) | |
| download | monitoring-plugins-18270bf20a930f713850fb8c2efa20b2a0f212c1.tar.gz | |
use GNU fileutils for check_disk
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@430 f882894a-f735-0410-b71e-b25c423dba1c
| -rw-r--r-- | configure.in | 84 | ||||
| -rw-r--r-- | lib/Makefile.am | 4 | ||||
| -rw-r--r-- | plugins/check_disk.c | 220 |
3 files changed, 126 insertions, 182 deletions
diff --git a/configure.in b/configure.in index 24f66d20..78a454ff 100644 --- a/configure.in +++ b/configure.in | |||
| @@ -30,31 +30,6 @@ AC_MINIX | |||
| 30 | AC_PROG_MAKE_SET | 30 | AC_PROG_MAKE_SET |
| 31 | AC_PROG_AWK | 31 | AC_PROG_AWK |
| 32 | 32 | ||
| 33 | # Check for SunOS statfs brokenness wrt partitions 2GB and larger. | ||
| 34 | # If <sys/vfs.h> exists and struct statfs has a member named f_spare, | ||
| 35 | # enable the work-around code in fsusage.c. | ||
| 36 | AC_MSG_CHECKING([for statfs that truncates block counts]) | ||
| 37 | AC_CACHE_VAL(fu_cv_sys_truncating_statfs, | ||
| 38 | [AC_TRY_COMPILE([ | ||
| 39 | #if !defined(sun) && !defined(__sun) | ||
| 40 | choke -- this is a workaround for a Sun-specific problem | ||
| 41 | #endif | ||
| 42 | #include <sys/types.h> | ||
| 43 | #include <sys/vfs.h>], | ||
| 44 | [struct statfs t; long c = *(t.f_spare);], | ||
| 45 | fu_cv_sys_truncating_statfs=yes | ||
| 46 | AC_MSG_RESULT(yes), | ||
| 47 | fu_cv_sys_truncating_statfs=no | ||
| 48 | AC_MSG_RESULT(no), | ||
| 49 | )]) | ||
| 50 | if test $fu_cv_sys_truncating_statfs = yes; then | ||
| 51 | AC_DEFINE(STATFS_TRUNCATES_BLOCK_COUNTS, 1, | ||
| 52 | [ Define if the block counts reported by statfs may be truncated to 2GB | ||
| 53 | and the correct values may be stored in the f_spare array. | ||
| 54 | (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem. | ||
| 55 | SunOS 4.1.1 seems not to be affected.)]) | ||
| 56 | fi | ||
| 57 | |||
| 58 | saved_srcdir=$srcdir | 33 | saved_srcdir=$srcdir |
| 59 | srcdir=$srcdir/lib | 34 | srcdir=$srcdir/lib |
| 60 | test -f $srcdir/getloadavg.c \ | 35 | test -f $srcdir/getloadavg.c \ |
| @@ -484,19 +459,49 @@ AC_HEADER_TIME | |||
| 484 | AC_HEADER_SYS_WAIT | 459 | AC_HEADER_SYS_WAIT |
| 485 | 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) | 460 | 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) |
| 486 | AC_CHECK_HEADERS(stdarg.h sys/unistd.h unistd.h ctype.h stdlib.h) | 461 | AC_CHECK_HEADERS(stdarg.h sys/unistd.h unistd.h ctype.h stdlib.h) |
| 462 | 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) | ||
| 463 | |||
| 464 | # Define HAVE_INTTYPES_H if <inttypes.h> exists, | ||
| 465 | # doesn't clash with <sys/types.h>, and declares uintmax_t. | ||
| 466 | |||
| 467 | AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, | ||
| 468 | [AC_TRY_COMPILE( | ||
| 469 | [#include <sys/types.h> | ||
| 470 | #include <inttypes.h>], | ||
| 471 | [uintmax_t i = (uintmax_t) -1;], | ||
| 472 | jm_ac_cv_header_inttypes_h=yes, | ||
| 473 | jm_ac_cv_header_inttypes_h=no)]) | ||
| 474 | |||
| 475 | if test $jm_ac_cv_header_inttypes_h = yes; then | ||
| 476 | AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, | ||
| 477 | [Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, | ||
| 478 | and declares uintmax_t. ]) | ||
| 479 | fi | ||
| 487 | 480 | ||
| 488 | dnl Linux | 481 | # Check for SunOS statfs brokenness wrt partitions 2GB and larger. |
| 489 | AC_CHECK_HEADERS(sys/vfs.h, | 482 | # If <sys/vfs.h> exists and struct statfs has a member named f_spare, |
| 490 | [AC_TRY_COMPILE([#include <sys/vfs.h>], | 483 | # enable the work-around code in fsusage.c. |
| 491 | [struct statfs buf; long foo; statfs ("/", &buf); foo = buf.f_namelen;], | 484 | AC_MSG_CHECKING([for statfs that truncates block counts]) |
| 492 | [AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if statfs struct can be found])])]) | 485 | AC_CACHE_VAL(fu_cv_sys_truncating_statfs, |
| 493 | 486 | [AC_TRY_COMPILE([ | |
| 494 | dnl FreeBSD | 487 | #if !defined(sun) && !defined(__sun) |
| 495 | AC_CHECK_HEADERS(sys/param.h sys/mount.h, | 488 | choke -- this is a workaround for a Sun-specific problem |
| 496 | [AC_TRY_COMPILE([#include <sys/param.h> | 489 | #endif |
| 497 | #include <sys/mount.h>], | 490 | #include <sys/types.h> |
| 498 | [struct statfs buf; int foo; statfs ("/", &buf); foo = buf.f_flags;], | 491 | #include <sys/vfs.h>], |
| 499 | [AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if statfs struct can be found])])]) | 492 | [struct statfs t; long c = *(t.f_spare);], |
| 493 | fu_cv_sys_truncating_statfs=yes | ||
| 494 | AC_MSG_RESULT(yes), | ||
| 495 | fu_cv_sys_truncating_statfs=no | ||
| 496 | AC_MSG_RESULT(no), | ||
| 497 | )]) | ||
| 498 | if test $fu_cv_sys_truncating_statfs = yes; then | ||
| 499 | AC_DEFINE(STATFS_TRUNCATES_BLOCK_COUNTS, 1, | ||
| 500 | [ Define if the block counts reported by statfs may be truncated to 2GB | ||
| 501 | and the correct values may be stored in the f_spare array. | ||
| 502 | (SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem. | ||
| 503 | SunOS 4.1.1 seems not to be affected.)]) | ||
| 504 | fi | ||
| 500 | 505 | ||
| 501 | dnl Checks for typedefs, structures, and compiler characteristics. | 506 | dnl Checks for typedefs, structures, and compiler characteristics. |
| 502 | AC_C_CONST | 507 | AC_C_CONST |
| @@ -955,6 +960,11 @@ fi | |||
| 955 | 960 | ||
| 956 | AC_DEFINE_UNQUOTED(DF_COMMAND,"$with_df_command",[path and args for df command]) | 961 | AC_DEFINE_UNQUOTED(DF_COMMAND,"$with_df_command",[path and args for df command]) |
| 957 | 962 | ||
| 963 | dnl jm_LIST_MOUNTED_FILESYSTEMS([list_mounted_fs=yes], [list_mounted_fs=no]) | ||
| 964 | jm_FSTYPENAME | ||
| 965 | jm_FILE_SYSTEM_USAGE([space=yes], [space=no]) | ||
| 966 | jm_AFS | ||
| 967 | |||
| 958 | AC_PATH_PROG(PATH_TO_PING,ping) | 968 | AC_PATH_PROG(PATH_TO_PING,ping) |
| 959 | AC_PATH_PROG(PATH_TO_PING6,ping6) | 969 | AC_PATH_PROG(PATH_TO_PING6,ping6) |
| 960 | 970 | ||
diff --git a/lib/Makefile.am b/lib/Makefile.am index 9a26e419..6353d01c 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | noinst_LIBRARIES = libnagiosplug.a | 3 | noinst_LIBRARIES = libnagiosplug.a |
| 4 | 4 | ||
| 5 | noinst_HEADERS = getopt.h | 5 | noinst_HEADERS = getopt.h fsusage.h mountlist.h |
| 6 | 6 | ||
| 7 | libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c | 7 | libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c fsusage.c mountlist.c |
| 8 | 8 | ||
| 9 | INCLUDES = -I$(srcdir) | 9 | INCLUDES = -I$(srcdir) |
diff --git a/plugins/check_disk.c b/plugins/check_disk.c index 485ae822..2558f6d3 100644 --- a/plugins/check_disk.c +++ b/plugins/check_disk.c | |||
| @@ -55,18 +55,81 @@ const char *options = "\ | |||
| 55 | Print version information\n"; | 55 | Print version information\n"; |
| 56 | 56 | ||
| 57 | #include "common.h" | 57 | #include "common.h" |
| 58 | #if HAVE_INTTYPES_H | ||
| 59 | # include <inttypes.h> | ||
| 60 | #endif | ||
| 61 | #include <assert.h> | ||
| 58 | #include "popen.h" | 62 | #include "popen.h" |
| 59 | #include "utils.h" | 63 | #include "utils.h" |
| 60 | #include <stdarg.h> | 64 | #include <stdarg.h> |
| 65 | #include "../lib/fsusage.h" | ||
| 66 | |||
| 67 | /* If nonzero, show inode information. */ | ||
| 68 | static int inode_format; | ||
| 69 | |||
| 70 | /* If nonzero, show even filesystems with zero size or | ||
| 71 | uninteresting types. */ | ||
| 72 | static int show_all_fs; | ||
| 73 | |||
| 74 | /* If nonzero, show only local filesystems. */ | ||
| 75 | static int show_local_fs; | ||
| 76 | |||
| 77 | /* If nonzero, output data for each filesystem corresponding to a | ||
| 78 | command line argument -- even if it's a dummy (automounter) entry. */ | ||
| 79 | static int show_listed_fs; | ||
| 80 | |||
| 81 | /* If positive, the units to use when printing sizes; | ||
| 82 | if negative, the human-readable base. */ | ||
| 83 | static int output_block_size; | ||
| 84 | |||
| 85 | /* If nonzero, invoke the `sync' system call before getting any usage data. | ||
| 86 | Using this option can make df very slow, especially with many or very | ||
| 87 | busy disks. Note that this may make a difference on some systems -- | ||
| 88 | SunOs4.1.3, for one. It is *not* necessary on Linux. */ | ||
| 89 | static int require_sync = 0; | ||
| 90 | |||
| 91 | /* A filesystem type to display. */ | ||
| 92 | |||
| 93 | struct fs_type_list | ||
| 94 | { | ||
| 95 | char *fs_name; | ||
| 96 | struct fs_type_list *fs_next; | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* Linked list of filesystem types to display. | ||
| 100 | If `fs_select_list' is NULL, list all types. | ||
| 101 | This table is generated dynamically from command-line options, | ||
| 102 | rather than hardcoding into the program what it thinks are the | ||
| 103 | valid filesystem types; let the user specify any filesystem type | ||
| 104 | they want to, and if there are any filesystems of that type, they | ||
| 105 | will be shown. | ||
| 106 | |||
| 107 | Some filesystem types: | ||
| 108 | 4.2 4.3 ufs nfs swap ignore io vm efs dbg */ | ||
| 109 | |||
| 110 | static struct fs_type_list *fs_select_list; | ||
| 111 | |||
| 112 | /* Linked list of filesystem types to omit. | ||
| 113 | If the list is empty, don't exclude any types. */ | ||
| 114 | |||
| 115 | static struct fs_type_list *fs_exclude_list; | ||
| 116 | |||
| 117 | /* Linked list of mounted filesystems. */ | ||
| 118 | static struct mount_entry *mount_list; | ||
| 119 | |||
| 120 | /* For long options that have no equivalent short option, use a | ||
| 121 | non-character as a pseudo short option, starting with CHAR_MAX + 1. */ | ||
| 122 | enum | ||
| 123 | { | ||
| 124 | SYNC_OPTION = CHAR_MAX + 1, | ||
| 125 | NO_SYNC_OPTION, | ||
| 126 | BLOCK_SIZE_OPTION | ||
| 127 | }; | ||
| 61 | 128 | ||
| 62 | #ifdef _AIX | 129 | #ifdef _AIX |
| 63 | #pragma alloca | 130 | #pragma alloca |
| 64 | #endif | 131 | #endif |
| 65 | 132 | ||
| 66 | #if HAVE_INTTYPES_H | ||
| 67 | # include <inttypes.h> | ||
| 68 | #endif | ||
| 69 | |||
| 70 | int process_arguments (int, char **); | 133 | int process_arguments (int, char **); |
| 71 | int validate_arguments (void); | 134 | int validate_arguments (void); |
| 72 | int check_disk (int usp, int free_disk); | 135 | int check_disk (int usp, int free_disk); |
| @@ -99,151 +162,22 @@ main (int argc, char **argv) | |||
| 99 | char mntp[MAX_INPUT_BUFFER]; | 162 | char mntp[MAX_INPUT_BUFFER]; |
| 100 | char *output = ""; | 163 | char *output = ""; |
| 101 | 164 | ||
| 102 | #ifdef HAVE_STRUCT_STATFS | 165 | struct fs_usage fsp; |
| 103 | #ifdef HAVE_SYS_VFS_H | 166 | char *disk; |
| 104 | #include <sys/vfs.h> | ||
| 105 | #else | ||
| 106 | #include <sys/param.h> | ||
| 107 | #include <sys/mount.h> | ||
| 108 | #endif | ||
| 109 | struct statfs buf; | ||
| 110 | #endif | ||
| 111 | 167 | ||
| 112 | if (process_arguments (argc, argv) != OK) | 168 | if (process_arguments (argc, argv) != OK) |
| 113 | usage ("Could not parse arguments\n"); | 169 | usage ("Could not parse arguments\n"); |
| 114 | 170 | ||
| 115 | #ifdef HAVE_STRUCT_STATFS | 171 | get_fs_usage (path, disk, &fsp); |
| 116 | |||
| 117 | if (statfs (path, &buf) == -1) { | ||
| 118 | switch (errno) | ||
| 119 | { | ||
| 120 | #ifdef ENOTDIR | ||
| 121 | case ENOTDIR: | ||
| 122 | terminate (STATE_UNKNOWN, "A component of the path prefix is not a directory.\n"); | ||
| 123 | #endif | ||
| 124 | #ifdef ENAMETOOLONG | ||
| 125 | case ENAMETOOLONG: | ||
| 126 | terminate (STATE_UNKNOWN, "path is too long.\n"); | ||
| 127 | #endif | ||
| 128 | #ifdef ENOENT | ||
| 129 | case ENOENT: | ||
| 130 | terminate (STATE_UNKNOWN, "The file referred to by path does not exist.\n"); | ||
| 131 | #endif | ||
| 132 | #ifdef EACCES | ||
| 133 | case EACCES: | ||
| 134 | terminate (STATE_UNKNOWN, "Search permission is denied for a component of the path prefix of path.\n"); | ||
| 135 | #endif | ||
| 136 | #ifdef ELOOP | ||
| 137 | case ELOOP: | ||
| 138 | terminate (STATE_UNKNOWN, "Too many symbolic links were encountered in translating path.\n"); | ||
| 139 | #endif | ||
| 140 | #ifdef EFAULT | ||
| 141 | case EFAULT: | ||
| 142 | terminate (STATE_UNKNOWN, "Buf or path points to an invalid address.\n"); | ||
| 143 | #endif | ||
| 144 | #ifdef EIO | ||
| 145 | case EIO: | ||
| 146 | terminate (STATE_UNKNOWN, "An I/O error occurred while reading from or writing to the file system.\n"); | ||
| 147 | #endif | ||
| 148 | #ifdef ENOMEM | ||
| 149 | case ENOMEM: | ||
| 150 | terminate (STATE_UNKNOWN, "Insufficient kernel memory was available.\n"); | ||
| 151 | #endif | ||
| 152 | #ifdef ENOSYS | ||
| 153 | case ENOSYS: | ||
| 154 | terminate (STATE_UNKNOWN, "The filesystem path is on does not support statfs.\n"); | ||
| 155 | #endif | ||
| 156 | } | ||
| 157 | } | ||
| 158 | 172 | ||
| 159 | usp = (buf.f_blocks - buf.f_bavail) / buf.f_blocks; | 173 | usp = (fsp.fsu_blocks - fsp.fsu_bavail) / fsp.fsu_blocks; |
| 160 | disk_result = check_disk (usp, buf.f_bavail); | 174 | disk_result = check_disk (usp, fsp.fsu_bavail); |
| 161 | result = disk_result; | 175 | result = disk_result; |
| 162 | asprintf (&output, "%ld of %ld kB free (%ld-byte blocks)", | 176 | asprintf (&output, "%llu of %llu kB (%2.0f%%) free (%d-byte blocks)", |
| 163 | buf.f_bavail*buf.f_bsize/1024, buf.f_blocks*buf.f_bsize/1024, buf.f_bsize); | 177 | fsp.fsu_bavail*fsp.fsu_blocksize/1024, |
| 164 | 178 | fsp.fsu_blocks*fsp.fsu_blocksize/1024, | |
| 165 | #else | 179 | (double)fsp.fsu_bavail*100/fsp.fsu_blocks, |
| 166 | 180 | fsp.fsu_blocksize); | |
| 167 | asprintf (&command_line, "%s %s", DF_COMMAND, path); | ||
| 168 | |||
| 169 | if (verbose>0) | ||
| 170 | printf ("%s ==> ", command_line); | ||
| 171 | |||
| 172 | child_process = spopen (command_line); | ||
| 173 | if (child_process == NULL) { | ||
| 174 | printf ("Could not open pipe: %s\n", command_line); | ||
| 175 | return STATE_UNKNOWN; | ||
| 176 | } | ||
| 177 | |||
| 178 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
| 179 | if (child_stderr == NULL) { | ||
| 180 | printf ("Could not open stderr for %s\n", command_line); | ||
| 181 | } | ||
| 182 | |||
| 183 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
| 184 | |||
| 185 | if (!index (input_buffer, '/')) | ||
| 186 | continue; | ||
| 187 | |||
| 188 | /* Fixes AIX /proc fs which lists - for size values */ | ||
| 189 | if (strstr (input_buffer, "/proc ") == input_buffer) | ||
| 190 | continue; | ||
| 191 | |||
| 192 | if (sscanf (input_buffer, "%s %d %d %d %d%% %s", file_system, | ||
| 193 | &total_disk, &used_disk, &free_disk, &usp, mntp) == 6 || | ||
| 194 | sscanf (input_buffer, "%s %*s %d %d %d %d%% %s", file_system, | ||
| 195 | &total_disk, &used_disk, &free_disk, &usp, mntp) == 6) { | ||
| 196 | |||
| 197 | if (strcmp(exclude_device,file_system) == 0 || | ||
| 198 | strcmp(exclude_device,mntp) == 0) { | ||
| 199 | if (verbose>0) | ||
| 200 | printf ("ignoring %s.", file_system); | ||
| 201 | continue; | ||
| 202 | } | ||
| 203 | |||
| 204 | disk_result = check_disk (usp, free_disk); | ||
| 205 | |||
| 206 | if (strcmp (file_system, "none") == 0) | ||
| 207 | strncpy (file_system, mntp, MAX_INPUT_BUFFER-1); | ||
| 208 | |||
| 209 | if (disk_result==STATE_OK && erronly && !verbose) | ||
| 210 | continue; | ||
| 211 | |||
| 212 | if (disk_result!=STATE_OK || verbose>=0) | ||
| 213 | asprintf (&output, "%s [%d kB (%d%%) free on %s]", output, | ||
| 214 | free_disk, 100 - usp, display_mntp ? mntp : file_system); | ||
| 215 | |||
| 216 | result = max_state (result, disk_result); | ||
| 217 | } | ||
| 218 | |||
| 219 | else { | ||
| 220 | printf ("Unable to read output:\n%s\n%s\n", command_line, input_buffer); | ||
| 221 | return result; | ||
| 222 | } | ||
| 223 | |||
| 224 | } | ||
| 225 | |||
| 226 | /* If we get anything on stderr, at least set warning */ | ||
| 227 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | ||
| 228 | if (result != STATE_CRITICAL) { | ||
| 229 | result = STATE_WARNING; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | /* close stderr */ | ||
| 234 | if (child_stderr) | ||
| 235 | (void) fclose (child_stderr); | ||
| 236 | |||
| 237 | /* close the pipe */ | ||
| 238 | if (spclose(child_process)!=0 && result!=STATE_CRITICAL) | ||
| 239 | result = STATE_WARNING; | ||
| 240 | |||
| 241 | if (usp < 0) | ||
| 242 | terminate (result, "Disk \"%s\" not mounted or nonexistant\n", path); | ||
| 243 | else if (result == STATE_UNKNOWN) | ||
| 244 | terminate (result, "Unable to read output\n%s\n%s\n", command_line, input_buffer); | ||
| 245 | |||
| 246 | #endif | ||
| 247 | 181 | ||
| 248 | terminate (result, "DISK %s %s\n", state_text (result), output); | 182 | terminate (result, "DISK %s %s\n", state_text (result), output); |
| 249 | } | 183 | } |
