Quellcode durchsuchen

Merge branch 'handle-hanging-nfs'

* handle-hanging-nfs:
  NEWS: Mention check_disk enhancement
  Cosmetic change: s/THRLIBS/THREADLIBS/
  configure.ac: Don't let pthread check depend on OS
  check_disk: Seperate declarations from code
  check_disk: Remove unused status variable
  check_disk: Fix pthread start routine type
  Don't let check_disk hang on hanging file systems
Holger Weiss vor 11 Jahren
Ursprung
Commit
04e0a182ae
4 geänderte Dateien mit 51 neuen und 1 gelöschten Zeilen
  1. 1 0
      NEWS
  2. 6 0
      configure.ac
  3. 1 1
      plugins/Makefile.am
  4. 43 0
      plugins/check_disk.c

+ 1 - 0
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

+ 6 - 0
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)

+ 1 - 1
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)

+ 43 - 0
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;
 }