From aabaed6f497335b81f18347e626ff3d9ae7799d5 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Fri, 21 Feb 2014 00:24:25 +0100 Subject: [PATCH 1/4] add support for systemd notification protocol This permit for now to signal readiness in a cleaner way to systemd. --- configure.ac | 35 ++++++++++++++++++++++++++++++++++- src/or/include.am | 4 ++-- src/or/main.c | 9 +++++++++ src/test/include.am | 6 ++++-- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 88b4da006d..bec6196fab 100644 --- a/configure.ac +++ b/configure.ac @@ -12,6 +12,8 @@ AC_CONFIG_HEADERS([orconfig.h]) AC_CANONICAL_HOST +PKG_PROG_PKG_CONFIG + if test -f /etc/redhat-release ; then if test -f /usr/kerberos/include ; then CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" @@ -105,6 +107,37 @@ AC_ARG_ENABLE(upnp, * ) AC_MSG_ERROR(bad value for --enable-upnp) ;; esac], [upnp=false]) +# systemd notify support +AC_ARG_ENABLE(systemd, + AS_HELP_STRING(--enable-systemd, enable systemd notification support), + [case "${enableval}" in + yes) systemd=true ;; + no) systemd=false ;; + * ) AC_MSG_ERROR(bad value for --enable-systemd) ;; + esac], [systemd=auto]) + + + +# systemd support +if test x$enable_systemd = xfalse ; then + have_systemd=no; +else + PKG_CHECK_MODULES(SYSTEMD, + [libsystemd-daemon], + have_systemd=yes, + have_systemd=no) +fi + +if test x$have_systemd = xyes; then + AC_DEFINE(HAVE_SYSTEMD,1,[Have systemd]) + TOR_SYSTEMD_LIBS="-lsystemd-daemon" +fi +AC_SUBST(TOR_SYSTEMD_LIBS) + +if test x$enable_systemd = xyes -a x$have_systemd != xyes ; then + AC_MSG_ERROR([Explicitly requested systemd support, but systemd not found]) +fi + case $host in *-*-solaris* ) AC_DEFINE(_REENTRANT, 1, [Define on some platforms to activate x_r() functions in time.h]) @@ -618,7 +651,7 @@ dnl since sometimes the linker will like an option but not be willing to dnl use it with a build of a library. all_ldflags_for_check="$TOR_LDFLAGS_zlib $TOR_LDFLAGS_openssl $TOR_LDFLAGS_libevent" -all_libs_for_check="$TOR_ZLIB_LIBS $TOR_LIB_MATH $TOR_LIBEVENT_LIBS $TOR_OPENSSL_LIBS $TOR_LIB_WS32 $TOR_LIB_GDI" +all_libs_for_check="$TOR_ZLIB_LIBS $TOR_LIB_MATH $TOR_LIBEVENT_LIBS $TOR_OPENSSL_LIBS $TOR_SYSTEMD_LIBS $TOR_LIB_WS32 $TOR_LIB_GDI" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ #if !defined(__clang__) diff --git a/src/or/include.am b/src/or/include.am index 643f7ce001..fb1581c463 100644 --- a/src/or/include.am +++ b/src/or/include.am @@ -111,7 +111,7 @@ src_or_tor_LDADD = src/or/libtor.a src/common/libor.a \ src/common/libor-crypto.a $(LIBDONNA) \ src/common/libor-event.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ if COVERAGE_ENABLED src_or_tor_cov_SOURCES = src/or/tor_main.c @@ -122,7 +122,7 @@ src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ src/common/libor-event-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \ - @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@ endif ORHEADERS = \ diff --git a/src/or/main.c b/src/or/main.c index 160bfa00e0..9fa62f89ef 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -75,6 +75,10 @@ #include #endif +#ifdef HAVE_SYSTEMD +#include +#endif + void evdns_shutdown(int); /********* PROTOTYPES **********/ @@ -2043,6 +2047,11 @@ do_main_loop(void) } #endif +#ifdef HAVE_SYSTEMD + log_notice(LD_GENERAL, "Signaling readyness to systemd"); + sd_notify(0, "READY=1"); +#endif + for (;;) { if (nt_service_is_stopping()) return 0; diff --git a/src/test/include.am b/src/test/include.am index d7a647940b..9db1587da7 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -68,7 +68,8 @@ src_test_test_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \ src/common/libor-crypto-testing.a $(LIBDONNA) \ src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \ @TOR_LDFLAGS_libevent@ @@ -76,7 +77,8 @@ src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \ src/common/libor-crypto.a $(LIBDONNA) \ src/common/libor-event.a \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ noinst_HEADERS+= \ src/test/fakechans.h \ From 29ac883606d6d5ebfdcc2efceb2b4b60ee6a8916 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Tue, 23 Dec 2014 11:22:42 -0500 Subject: [PATCH 2/4] 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; From 2f46e5e7558ca3b7dab16fb970d16c1a3dfd190c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 23 Dec 2014 11:27:16 -0500 Subject: [PATCH 3/4] Adjust systemd watchdog support Document why we divide it by two. Check for > 0 instead of nonzero for success, since that's what the manpage says. Allow watchdog timers greater than 1 second. --- src/or/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/or/main.c b/src/or/main.c index 5a17212da6..58e3ad3e4d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2045,11 +2045,15 @@ do_main_loop(void) #ifdef HAVE_SYSTEMD_209 uint64_t watchdog_delay; /* set up systemd watchdog notification. */ - if (sd_watchdog_enabled(1, &watchdog_delay)) { + if (sd_watchdog_enabled(1, &watchdog_delay) > 0) { if (! systemd_watchdog_timer) { struct timeval watchdog; - watchdog.tv_sec = 0; - watchdog.tv_usec = watchdog_delay/2; + /* The manager will "act on" us if we don't send them a notification + * every 'watchdog_delay' microseconds. So, send notifications twice + * that often. */ + watchdog_delay /= 2; + watchdog.tv_sec = watchdog_delay / 1000000; + watchdog.tv_usec = watchdog_delay % 1000000; systemd_watchdog_timer = periodic_timer_new(tor_libevent_get_base(), &watchdog, From 7e1289b3eca37d72c87cc9a4a4a623e36095553e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 23 Dec 2014 11:32:10 -0500 Subject: [PATCH 4/4] changes file for ticket11016 --- changes/ticket11016 | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changes/ticket11016 diff --git a/changes/ticket11016 b/changes/ticket11016 new file mode 100644 index 0000000000..98d5d49697 --- /dev/null +++ b/changes/ticket11016 @@ -0,0 +1,6 @@ + o Minor features (systemd): + - Where supported, when running with systemd, report successful + startup to systemd. Part of ticket 11016. Patch by Michael + Scherer. + - When running with systemd, support systemd watchdog messages. + Part of ticket 11016. Patch by Michael Scherer.