From 29ac883606d6d5ebfdcc2efceb2b4b60ee6a8916 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Tue, 23 Dec 2014 11:22:42 -0500 Subject: [PATCH] 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. --- configure.ac | 20 ++++++++++++++++++++ src/or/main.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/configure.ac b/configure.ac index bec6196fab..666478f920 100644 --- a/configure.ac +++ b/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]) diff --git a/src/or/main.c b/src/or/main.c index 9fa62f89ef..5a17212da6 100644 --- a/src/or/main.c +++ b/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;