From fdb75ba5fe341454853c6335e349d348ba99d69b Mon Sep 17 00:00:00 2001 From: Tomasz Torcz Date: Wed, 8 Feb 2017 19:15:25 +0100 Subject: [PATCH] nghttpx: add systemd support Add systemd's Type=notify support by sending information about master process PID around forks. Add some hardening option to service unit. --- configure.ac | 13 +++++++++++++ contrib/nghttpx.service.in | 11 +++++++++-- src/Makefile.am | 1 + src/shrpx.cc | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9d216b60..1a5ca617 100644 --- a/configure.ac +++ b/configure.ac @@ -395,6 +395,18 @@ else AC_MSG_NOTICE($JANSSON_PKG_ERRORS) fi + +# libsystemd +PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 209], [have_libsystemd=yes], + [have_libsystemd=no]) +if test "x${have_libsystemd}" = "xyes"; then + AC_DEFINE([HAVE_LIBSYSTEMD], [1], + [Define to 1 if you have `libsystemd` library.]) +else + AC_MSG_NOTICE($SYSTEMD_PKG_ERRORS) +fi + + # libxml2 (for src/nghttp) PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.7.7], [have_libxml2=yes], [have_libxml2=no]) @@ -914,6 +926,7 @@ AC_MSG_NOTICE([summary of build options: Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}') Jemalloc: ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}') Zlib: ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}') + systemd: ${have_libsystemd} (LIBS='${SYSTEMD_LIBS}') Boost CPPFLAGS: ${BOOST_CPPFLAGS} Boost LDFLAGS: ${BOOST_LDFLAGS} Boost::ASIO: ${BOOST_ASIO_LIB} diff --git a/contrib/nghttpx.service.in b/contrib/nghttpx.service.in index 537f7c61..06fb736c 100644 --- a/contrib/nghttpx.service.in +++ b/contrib/nghttpx.service.in @@ -1,10 +1,17 @@ [Unit] Description=HTTP/2 proxy +Documentation=man:nghttpx After=network.target [Service] -Type=forking -ExecStart=@bindir@/nghttpx --conf=/etc/nghttpx/nghttpx.conf --pid-file=/run/nghttpx.pid --daemon +Type=notify +ExecStart=@bindir@/nghttpx --conf=/etc/nghttpx/nghttpx.conf +ExecReload=/bin/kill --signal HUP $MAINPID +KillSignal=SIGQUIT +PrivateTmp=yes +ProtectHome=yes +ProtectSystem=full +Restart=always [Install] WantedBy=multi-user.target diff --git a/src/Makefile.am b/src/Makefile.am index a35df85f..ea3f8a30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,6 +57,7 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \ @LIBEV_LIBS@ \ @OPENSSL_LIBS@ \ @LIBCARES_LIBS@ \ + @SYSTEMD_LIBS@ \ @JANSSON_LIBS@ \ @ZLIB_LIBS@ \ @APPLDFLAGS@ diff --git a/src/shrpx.cc b/src/shrpx.cc index 088eb23d..bdbe1c57 100644 --- a/src/shrpx.cc +++ b/src/shrpx.cc @@ -56,6 +56,9 @@ #include #endif // HAVE_SYS_TIME_H #include +#ifdef HAVE_LIBSYSTEMD +#include +#endif // HAVE_LIBSYSTEMD #include #include @@ -363,6 +366,18 @@ int save_pid() { } } // namespace +namespace { +void shrpx_sd_notifyf(int unset_environment, const char *format, ...) { +#ifdef HAVE_LIBSYSTEMD + va_list args; + + va_start(args, format); + sd_notifyf(unset_environment, format, va_arg(args, char *)); + va_end(args); +#endif // HAVE_LIBSYSTEMD +} +} // namespace + namespace { void exec_binary() { int rv; @@ -371,6 +386,8 @@ void exec_binary() { LOG(NOTICE) << "Executing new binary"; + shrpx_sd_notifyf(0, "RELOADING=1"); + rv = shrpx_signal_block_all(&oldset); if (rv != 0) { auto error = errno; @@ -386,6 +403,9 @@ void exec_binary() { if (pid == -1) { auto error = errno; LOG(ERROR) << "fork() failed errno=" << error; + } else { + // update PID tracking information in systemd + shrpx_sd_notifyf(0, "MAINPID=%d\n", pid); } rv = shrpx_signal_set(&oldset); @@ -489,6 +509,9 @@ void exec_binary() { // restores original stderr restore_original_fds(); + // reloading finished + shrpx_sd_notifyf(0, "READY=1"); + if (execve(argv[0], argv.get(), envp.get()) == -1) { auto error = errno; LOG(ERROR) << "execve failed: errno=" << error; @@ -1088,6 +1111,13 @@ int call_daemon() { #ifdef __sgi return _daemonize(0, 0, 0, 0); #else // !__sgi +#ifdef HAVE_LIBSYSTEMD + if (sd_booted() && (getenv("NOTIFY_SOCKET") != NULL)) { + LOG(NOTICE) << "Daemonising disabled under systemd"; + chdir("/"); + return 0; + } +#endif // HAVE_LIBSYSTEMD return daemon(0, 0); #endif // !__sgi } @@ -1245,6 +1275,9 @@ int event_loop() { redirect_stderr_to_errorlog(); } + // update systemd PID tracking + shrpx_sd_notifyf(0, "MAINPID=%d\n", config->pid); + { auto iaddrs = get_inherited_addr_from_env(config); @@ -1275,6 +1308,9 @@ int event_loop() { save_pid(); } + // ready to serve requests + shrpx_sd_notifyf(0, "READY=1"); + ev_run(loop, 0); return 0;