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 /plugins | |
| 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
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_disk.c | 220 |
1 files changed, 77 insertions, 143 deletions
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 | } |
