summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in84
-rw-r--r--lib/Makefile.am4
-rw-r--r--plugins/check_disk.c220
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
30AC_PROG_MAKE_SET 30AC_PROG_MAKE_SET
31AC_PROG_AWK 31AC_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.
36AC_MSG_CHECKING([for statfs that truncates block counts])
37AC_CACHE_VAL(fu_cv_sys_truncating_statfs,
38[AC_TRY_COMPILE([
39#if !defined(sun) && !defined(__sun)
40choke -- 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);],
45fu_cv_sys_truncating_statfs=yes
46AC_MSG_RESULT(yes),
47fu_cv_sys_truncating_statfs=no
48AC_MSG_RESULT(no),
49)])
50if 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.)])
56fi
57
58saved_srcdir=$srcdir 33saved_srcdir=$srcdir
59srcdir=$srcdir/lib 34srcdir=$srcdir/lib
60test -f $srcdir/getloadavg.c \ 35test -f $srcdir/getloadavg.c \
@@ -484,19 +459,49 @@ AC_HEADER_TIME
484AC_HEADER_SYS_WAIT 459AC_HEADER_SYS_WAIT
485AC_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) 460AC_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)
486AC_CHECK_HEADERS(stdarg.h sys/unistd.h unistd.h ctype.h stdlib.h) 461AC_CHECK_HEADERS(stdarg.h sys/unistd.h unistd.h ctype.h stdlib.h)
462AC_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
467AC_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
475if 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. ])
479fi
487 480
488dnl Linux 481# Check for SunOS statfs brokenness wrt partitions 2GB and larger.
489AC_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;], 484AC_MSG_CHECKING([for statfs that truncates block counts])
492 [AC_DEFINE(HAVE_STRUCT_STATFS,1,[Define if statfs struct can be found])])]) 485AC_CACHE_VAL(fu_cv_sys_truncating_statfs,
493 486[AC_TRY_COMPILE([
494dnl FreeBSD 487#if !defined(sun) && !defined(__sun)
495AC_CHECK_HEADERS(sys/param.h sys/mount.h, 488choke -- 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);],
493fu_cv_sys_truncating_statfs=yes
494AC_MSG_RESULT(yes),
495fu_cv_sys_truncating_statfs=no
496AC_MSG_RESULT(no),
497)])
498if 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.)])
504fi
500 505
501dnl Checks for typedefs, structures, and compiler characteristics. 506dnl Checks for typedefs, structures, and compiler characteristics.
502AC_C_CONST 507AC_C_CONST
@@ -955,6 +960,11 @@ fi
955 960
956AC_DEFINE_UNQUOTED(DF_COMMAND,"$with_df_command",[path and args for df command]) 961AC_DEFINE_UNQUOTED(DF_COMMAND,"$with_df_command",[path and args for df command])
957 962
963dnl jm_LIST_MOUNTED_FILESYSTEMS([list_mounted_fs=yes], [list_mounted_fs=no])
964jm_FSTYPENAME
965jm_FILE_SYSTEM_USAGE([space=yes], [space=no])
966jm_AFS
967
958AC_PATH_PROG(PATH_TO_PING,ping) 968AC_PATH_PROG(PATH_TO_PING,ping)
959AC_PATH_PROG(PATH_TO_PING6,ping6) 969AC_PATH_PROG(PATH_TO_PING6,ping6)
960 970
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 @@
2 2
3noinst_LIBRARIES = libnagiosplug.a 3noinst_LIBRARIES = libnagiosplug.a
4 4
5noinst_HEADERS = getopt.h 5noinst_HEADERS = getopt.h fsusage.h mountlist.h
6 6
7libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c 7libnagiosplug_a_SOURCES = getopt.c getopt1.c getloadavg.c snprintf.c fsusage.c mountlist.c
8 8
9INCLUDES = -I$(srcdir) 9INCLUDES = -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 = "\
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. */
68static int inode_format;
69
70/* If nonzero, show even filesystems with zero size or
71 uninteresting types. */
72static int show_all_fs;
73
74/* If nonzero, show only local filesystems. */
75static 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. */
79static int show_listed_fs;
80
81/* If positive, the units to use when printing sizes;
82 if negative, the human-readable base. */
83static 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. */
89static int require_sync = 0;
90
91/* A filesystem type to display. */
92
93struct 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
110static 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
115static struct fs_type_list *fs_exclude_list;
116
117/* Linked list of mounted filesystems. */
118static 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. */
122enum
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
70int process_arguments (int, char **); 133int process_arguments (int, char **);
71int validate_arguments (void); 134int validate_arguments (void);
72int check_disk (int usp, int free_disk); 135int 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}