Browse Source

Add support for systemd watchdog protocol

It work by notifying systemd on a regular basis. If
there is no notification, the daemon is restarted.
This requires a version newer than the 209 version
of systemd, as it is not supported before.
Michael Scherer 9 years ago
parent
commit
29ac883606
2 changed files with 49 additions and 0 deletions
  1. 20 0
      configure.ac
  2. 29 0
      src/or/main.c

+ 20 - 0
configure.ac

@@ -138,6 +138,26 @@ if test x$enable_systemd = xyes -a x$have_systemd != xyes ; then
     AC_MSG_ERROR([Explicitly requested systemd support, but systemd not found])
 fi
 
+AC_ARG_ENABLE(threads,
+     AS_HELP_STRING(--disable-threads, disable multi-threading support))
+
+if test x$enable_threads = x; then
+   case $host in
+    *-*-solaris* )
+     # Don't try multithreading on solaris -- cpuworkers seem to lock.
+     AC_MSG_NOTICE([You are running Solaris; Sometimes threading makes
+cpu workers lock up here, so I will disable threads.])
+     enable_threads="no";;
+    *)
+     enable_threads="yes";;
+   esac
+fi
+
+ifdef([HAVE_SYSTEMD], [
+AC_SEARCH_LIBS([sd_watchdog_enabled], [systemd-daemon],
+    [AC_DEFINE(HAVE_SYSTEMD_209,1,[Have systemd v209 or more])], [])
+])
+
 case $host in
    *-*-solaris* )
      AC_DEFINE(_REENTRANT, 1, [Define on some platforms to activate x_r() functions in time.h])

+ 29 - 0
src/or/main.c

@@ -1763,6 +1763,17 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
   current_second = now; /* remember which second it is, for next time */
 }
 
+#ifdef HAVE_SYSTEMD_209
+static periodic_timer_t *systemd_watchdog_timer = NULL;
+
+/** Libevent callback: invoked to reset systemd watchdog. */
+static void
+systemd_watchdog_callback(periodic_timer_t *timer, void *arg)
+{
+  sd_notify(1, "WATCHDOG=1");
+}
+#endif
+
 #ifndef USE_BUFFEREVENTS
 /** Timer: used to invoke refill_callback(). */
 static periodic_timer_t *refill_timer = NULL;
@@ -2031,6 +2042,24 @@ do_main_loop(void)
     tor_assert(second_timer);
   }
 
+#ifdef HAVE_SYSTEMD_209
+  uint64_t watchdog_delay;
+  /* set up systemd watchdog notification. */
+  if (sd_watchdog_enabled(1, &watchdog_delay)) {
+    if (! systemd_watchdog_timer) {
+      struct timeval watchdog;
+      watchdog.tv_sec = 0;
+      watchdog.tv_usec = watchdog_delay/2;
+
+      systemd_watchdog_timer = periodic_timer_new(tor_libevent_get_base(),
+                                                  &watchdog,
+                                                  systemd_watchdog_callback,
+                                                  NULL);
+      tor_assert(systemd_watchdog_timer);
+    }
+  }
+#endif
+
 #ifndef USE_BUFFEREVENTS
   if (!refill_timer) {
     struct timeval refill_interval;