main: add optional support for sd_notify via libsystemd

If libsystemd is available, and it's not disabled via --without-libsystemd,
link to it and call sd_notify() before and after the main loop.

This allows systemd to track the exact moment when all the setup is completed
and the unit is considered activated (with Type=notify), in a race-free manner.
This commit is contained in:
Luca Boccassi 2024-08-22 15:44:13 +01:00
parent 1ab5b88939
commit af2177c372
3 changed files with 44 additions and 1 deletions

21
configure vendored
View file

@ -140,6 +140,7 @@ For better control, use the options below.
--with-rtcdevice=PATH Specify default path to RTC device [/dev/rtc]
--with-sendmail=PATH Path to sendmail binary [/usr/lib/sendmail]
--enable-debug Enable debugging support
--without-libsystemd Don't use libsystemd even if it is available
Fine tuning of the installation directories:
--sysconfdir=DIR chrony.conf location [/etc]
@ -259,6 +260,7 @@ default_hwclockfile=""
default_pidfile="/var/run/chrony/chronyd.pid"
default_rtcdevice="/dev/rtc"
mail_program="/usr/lib/sendmail"
try_libsystemd=1
for option
do
@ -395,6 +397,9 @@ do
--without-gnutls )
try_gnutls=0
;;
--without-libsystemd )
try_libsystemd=0
;;
--host-system=* )
OPERATINGSYSTEM=`echo $option | sed -e 's/^.*=//;'`
;;
@ -589,6 +594,7 @@ if ! test_executable "pkg-config" $PKG_CONFIG --version; then
try_nettle=0
try_nss=0
try_gnutls=0
try_libsystemd=0
fi
if test_code '64-bit time_t' 'time.h' '' '' '
@ -1045,6 +1051,19 @@ if [ $feat_ntp = "1" ] && [ $feat_nts = "1" ] && [ $try_gnutls = "1" ]; then
fi
fi
if [ $try_libsystemd = "1" ]; then
test_cflags="`pkg_config --cflags libsystemd`"
test_link="`pkg_config --libs libsystemd`"
if test_code 'libsystemd' 'systemd/sd-daemon.h' \
"$test_cflags" "$test_link" \
'sd_notify(0, "READY=1");'
then
LIBS="$LIBS $test_link"
MYCPPFLAGS="$MYCPPFLAGS $test_cflags"
add_def FEAT_LIBSYSTEMD
fi
fi
if [ $use_pthread = "1" ]; then
MYCFLAGS="$MYCFLAGS -pthread"
fi
@ -1114,7 +1133,7 @@ add_def MAIL_PROGRAM "\"$mail_program\""
common_features="`get_features SECHASH IPV6 DEBUG`"
chronyc_features="`get_features READLINE`"
chronyd_features="`get_features CMDMON NTP REFCLOCK RTC PRIVDROP SCFILTER SIGND ASYNCDNS NTS`"
chronyd_features="`get_features CMDMON NTP REFCLOCK RTC PRIVDROP SCFILTER SIGND ASYNCDNS NTS LIBSYSTEMD`"
add_def CHRONYC_FEATURES "\"$chronyc_features $common_features\""
add_def CHRONYD_FEATURES "\"$chronyd_features $common_features\""
echo "Features : $chronyd_features $chronyc_features $common_features"

View file

@ -35,6 +35,7 @@ to enable optional features:
* timepps.h header: PPS reference clock
* Asciidoctor: documentation in HTML format
* Bash: test suite
* libsystemd: signal readiness to systemd via `sd_notify()` (`LIBSYSTEMD`)
The following programs are needed when building `chrony` from the git
repository instead of a released tar file:
@ -104,6 +105,15 @@ If development files for the editline library are available,
`chronyc` will be built with line editing support. If you don't want this,
specify the `--disable-readline` flag to `configure`.
If development files for the libsystemd library are available, `chronyd` will
be built with support for signaling readiness to systemd via `sd_notify()`.
When this is enabled, `chronyd` in a systemd unit file can be called with the
`-n` option to avoid forking in the background, and with `pidfile /` set in the
`chronyd` configuration file to avoid writing/checking the PID file. This will
let systemd do the full lifecycle tracking and management of `chronyd`, without
race conditions. If you don't want to enable the support, specify the
`--without-libsystemd` flag to `configure`.
If a `timepps.h` header is available (e.g. from the
http://linuxpps.org[LinuxPPS project]), `chronyd` will be built with PPS API
reference clock driver. If the header is installed in a location that isn't

14
main.c
View file

@ -59,6 +59,10 @@
#include "tempcomp.h"
#include "util.h"
#ifdef FEAT_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif
/* ================================================== */
/* Set when the initialisation chain has been completed. Prevents finalisation
@ -698,10 +702,20 @@ int main
post_init_rtc_hook(NULL);
}
#ifdef FEAT_LIBSYSTEMD
if (nofork)
sd_notify(0, "READY=1");
#endif
/* The program normally runs under control of the main loop in
the scheduler. */
SCH_MainLoop();
#ifdef FEAT_LIBSYSTEMD
if (nofork)
sd_notify(0, "STOPPING=1");
#endif
LOG(LOGS_INFO, "chronyd exiting");
MAI_CleanupAndExit();