From dedef6dee02661c9c28ba43f8cd398c587695a88 Mon Sep 17 00:00:00 2001 From: Micha Lenk Date: Mon, 1 Mar 2021 11:21:58 +0100 Subject: [PATCH] Add support for Systemd service type 'notify' By calling sd_notify() the smcroute daemon (smcrouted) can tell the systemd service manager when it is fully up and running. This allows systemd to manage services synchronously (i.e. use service type 'notify') so that dependent tasks can rely on smcrouted being fully up and running. This patch is already in use in Debian package smcroute/2.4.4-2. Related Debian bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=924361 --- .travis.yml | 1 + configure.ac | 11 +++++++++++ smcroute.service.in | 3 ++- src/Makefile.am | 4 ++++ src/smcrouted.c | 24 ++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0a2ca743..716d1230 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ addons: packages: - tree - libcap-dev + - libsystemd-dev coverity_scan: project: name: "troglobit/smcroute" diff --git a/configure.ac b/configure.ac index 89c79451..c60c270f 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,17 @@ AS_IF([test "x$with_systemd" != "xno"], [AC_SUBST([systemddir], [$with_systemd])]) AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemd" != "xno"]) +have_libsystemd=no +AS_IF([test "x$with_systemd" != "xno"], + [PKG_CHECK_MODULES(LIBSYSTEMD, libsystemd, + [AC_DEFINE(HAVE_LIBSYSTEMD, 1, [Enable libsystemd integration]) + have_libsystemd=yes])] +) +AS_IF([test "x$have_libsystemd" = "xyes"], + [AC_SUBST([systemd_service_type], [notify])], + [AC_SUBST([systemd_service_type], [simple])]) +AM_CONDITIONAL([HAVE_LIBSYSTEMD], [test "x$have_libsystemd" = "xyes"]) + # Check if we need -lpthread (building statically) and -lrt (older GLIBC) # Unset cached values when retrying with -lpthread and reset LIBS for each API need_librt=no diff --git a/smcroute.service.in b/smcroute.service.in index 910f4868..42fdb0ee 100644 --- a/smcroute.service.in +++ b/smcroute.service.in @@ -8,8 +8,9 @@ After=network-online.target Requires=network-online.target [Service] -Type=simple +Type=@systemd_service_type@ ExecStart=@SBINDIR@/smcrouted -n -s +NotifyAccess=main # Hardening settings NoNewPrivileges=true diff --git a/src/Makefile.am b/src/Makefile.am index ae2bcdcd..51d24afd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,3 +30,7 @@ if USE_DOTCONF smcrouted_SOURCES += conf.c conf.h endif +if HAVE_LIBSYSTEMD +smcrouted_CFLAGS += $(LIBSYSTEMD_CFLAGS) +smcrouted_LDADD += $(LIBSYSTEMD_LIBS) +endif diff --git a/src/smcrouted.c b/src/smcrouted.c index 6c74a33e..1082c8af 100644 --- a/src/smcrouted.c +++ b/src/smcrouted.c @@ -23,12 +23,17 @@ #include #include #include +#include #include #include #include #include /* gettimeofday() */ #include +#if HAVE_LIBSYSTEMD +#include +#endif + #include "cap.h" #include "ipc.h" #include "log.h" @@ -135,15 +140,34 @@ static void signal_init(void) static int server_loop(void) { +#if HAVE_LIBSYSTEMD + bool need_sd_notify_ready = true; +#endif + script_init(script); mrdisc_init(interval); while (running) { if (reloading) { +#if HAVE_LIBSYSTEMD + sd_notify(0, "RELOADING=1\n" + "STATUS=Reloading configuration...\n"); + need_sd_notify_ready = true; +#endif + reload(); reloading = 0; } + +#if HAVE_LIBSYSTEMD + if (need_sd_notify_ready) { + sd_notify(0, "READY=1\n" + "STATUS=Configuration loaded.\n"); + need_sd_notify_ready = false; + } +#endif + socket_poll(NULL); }