aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--configure.ac6
-rw-r--r--plugins/Makefile.am2
-rw-r--r--plugins/check_disk.c43
4 files changed, 51 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 70ee6591..a923e824 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ This file documents the major additions and syntax changes between releases.
thresholds
New check_snmp "-N" option to specify SNMPv3 context name
New check_nt "-l" parameters: seconds|minutes|hours|days
+ Make sure check_disk won't hang on hanging (network) file systems
FIXES
Let check_real terminate lines with CRLF when talking to the server, as
diff --git a/configure.ac b/configure.ac
index a6c9e79a..fb8f9500 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,12 @@ AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket")
AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv")
AC_SUBST(SOCKETLIBS)
+dnl Check for POSIX thread libraries
+AC_CHECK_HEADERS(pthread.h)
+AC_CHECK_LIB(pthread,pthread_create,THREADLIBS="-lpthread",
+ AC_CHECK_LIB(pthread,pthread_create,THREADLIBS="-lpthread -lrt",-lrt))
+AC_SUBST(THREADLIBS)
+
dnl
dnl check for math-related functions needing -lm
AC_CHECK_HEADERS(math.h)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 0ddf9bd1..41906c53 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -71,7 +71,7 @@ check_apt_LDADD = $(BASEOBJS)
check_cluster_LDADD = $(BASEOBJS)
check_dbi_LDADD = $(NETLIBS) $(DBILIBS)
check_dig_LDADD = $(NETLIBS)
-check_disk_LDADD = $(BASEOBJS)
+check_disk_LDADD = $(BASEOBJS) $(THREADLIBS)
check_dns_LDADD = $(NETLIBS)
check_dummy_LDADD = $(BASEOBJS)
check_fping_LDADD = $(NETLIBS)
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 0d73a4f1..eb573f5f 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -51,6 +51,9 @@ const char *email = "devel@monitoring-plugins.org";
# include <limits.h>
#endif
#include "regex.h"
+#if HAVE_PTHREAD_H
+# include <pthread.h>
+#endif
#ifdef __CYGWIN__
# include <windows.h>
@@ -130,6 +133,7 @@ void print_help (void);
void print_usage (void);
double calculate_percent(uintmax_t, uintmax_t);
void stat_path (struct parameter_list *p);
+void *do_stat_path (void *p);
void get_stats (struct parameter_list *p, struct fs_usage *fsp);
void get_path_stats (struct parameter_list *p, struct fs_usage *fsp);
@@ -968,6 +972,44 @@ print_usage (void)
void
stat_path (struct parameter_list *p)
{
+#ifdef HAVE_PTHREAD_H
+ pthread_t stat_thread;
+ int statdone = 0;
+ int timer = timeout_interval;
+ struct timespec req, rem;
+
+ req.tv_sec = 0;
+ pthread_create(&stat_thread, NULL, do_stat_path, p);
+ while (timer-- > 0) {
+ req.tv_nsec = 10000000;
+ nanosleep(&req, &rem);
+ if (pthread_kill(stat_thread, 0)) {
+ statdone = 1;
+ break;
+ } else {
+ req.tv_nsec = 990000000;
+ nanosleep(&req, &rem);
+ }
+ }
+ if (statdone == 1) {
+ pthread_join(stat_thread, NULL);
+ } else {
+ pthread_detach(stat_thread);
+ if (verbose >= 3)
+ printf("stat did not return within %ds on %s\n", timeout_interval, p->name);
+ printf("DISK %s - ", _("CRITICAL"));
+ die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("hangs"), _("Timeout"));
+ }
+#else
+ do_stat_path(p);
+#endif
+}
+
+void *
+do_stat_path (void *in)
+{
+ struct parameter_list *p = in;
+
/* Stat entry to check that dir exists and is accessible */
if (verbose >= 3)
printf("calling stat on %s\n", p->name);
@@ -977,6 +1019,7 @@ stat_path (struct parameter_list *p)
printf("DISK %s - ", _("CRITICAL"));
die (STATE_CRITICAL, _("%s %s: %s\n"), p->name, _("is not accessible"), strerror(errno));
}
+ return NULL;
}