[Asterisk-code-review] sd notify (systemd status notifications) support (asterisk[13])

Joshua Colp asteriskteam at digium.com
Tue Sep 20 14:03:15 CDT 2016


Joshua Colp has submitted this change and it was merged.

Change subject: sd_notify (systemd status notifications) support
......................................................................


sd_notify (systemd status notifications) support

sd_notify() is used to notify systemd of changes to the status of the
process. This allows the systemd daemon to know when the process
finished loading (and thus only start another program after Asterisk has
finished loading).

To use this, use a systemd unit with 'Type=notify' for Asterisk.

This commit also adds the function ast_sd_notify(), a wrapper around
sd_notify that does nothing if not built with systemd support.

Also adds support for libsystemd detection in the configure script.

Change-Id: Ied6a59dafd5ef331c5c7ae8f3ccd2dfc94be7811
(cherry picked from commit 07b95f7c65b7c083724f1af2b26f93cc22cad58c)
---
M CHANGES
M configure
M configure.ac
M include/asterisk/autoconfig.h.in
M include/asterisk/io.h
M main/Makefile
M main/asterisk.c
M main/io.c
M main/loader.c
M makeopts.in
10 files changed, 166 insertions(+), 6 deletions(-)

Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved; Verified
  Corey Farrell: Looks good to me, but someone else must approve



diff --git a/CHANGES b/CHANGES
index 8974158..4a86682 100644
--- a/CHANGES
+++ b/CHANGES
@@ -77,6 +77,12 @@
     instance, allows a channel to immediately exit the ConfBridge without having
     to wait for a leave announcement to play.
 
+Core
+------------------
+  * If Asterisk is built with systemd support, and run under systemd, it will
+    notify systemd of its state using sd_notify. Use 'Type=notify' in
+    asterisk.service.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.10.0 to Asterisk 13.11.0 ----------
 ------------------------------------------------------------------------------
diff --git a/configure b/configure
index e3c537a..6f40dcc 100755
--- a/configure
+++ b/configure
@@ -639,6 +639,11 @@
 PBX_SYSLOG_FACILITY_LOG_CRON
 PBX_SYSLOG_FACILITY_LOG_AUTHPRIV
 PBX_SYSLOG_FACILITY_LOG_AUTH
+SYSTEMD_LIBS
+SYSTEMD_CFLAGS
+SYSTEMD_INCLUDE
+SYSTEMD_LIB
+PBX_SYSTEMD
 PBX_GENERIC_ODBC
 GENERIC_ODBC_INCLUDE
 GENERIC_ODBC_LIB
@@ -1296,6 +1301,7 @@
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -1434,7 +1440,9 @@
 GMIME_CFLAGS
 GMIME_LIBS
 GTK2_CFLAGS
-GTK2_LIBS'
+GTK2_LIBS
+SYSTEMD_CFLAGS
+SYSTEMD_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1473,6 +1481,7 @@
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1725,6 +1734,15 @@
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1862,7 +1880,7 @@
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -2015,6 +2033,7 @@
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -2185,6 +2204,10 @@
   GMIME_LIBS  linker flags for GMIME, overriding pkg-config
   GTK2_CFLAGS C compiler flags for GTK2, overriding pkg-config
   GTK2_LIBS   linker flags for GTK2, overriding pkg-config
+  SYSTEMD_CFLAGS
+              C compiler flags for SYSTEMD, overriding pkg-config
+  SYSTEMD_LIBS
+              linker flags for SYSTEMD, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -33984,6 +34007,98 @@
 
 
 
+
+
+
+
+   if test "x${PBX_SYSTEMD}" != "x1" -a "${USE_SYSTEMD}" != "no"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
+$as_echo_n "checking for SYSTEMD... " >&6; }
+
+if test -n "$SYSTEMD_CFLAGS"; then
+    pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$SYSTEMD_LIBS"; then
+    pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
+        else
+	        SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$SYSTEMD_PKG_ERRORS" >&5
+
+
+            PBX_SYSTEMD=0
+
+
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+            PBX_SYSTEMD=0
+
+
+else
+	SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
+	SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+            PBX_SYSTEMD=1
+            SYSTEMD_INCLUDE="$SYSTEMD_CFLAGS"
+            SYSTEMD_LIB="$SYSTEMD_LIBS"
+
+$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
+
+
+fi
+   fi
+
+
 PBX_SYSLOG=0
 
 if test "${ac_cv_header_syslog_h}" = "yes"; then
diff --git a/configure.ac b/configure.ac
index 1ba86bb..521f02a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2601,6 +2601,11 @@
 AC_SUBST([GENERIC_ODBC_INCLUDE])
 AC_SUBST([PBX_GENERIC_ODBC])
 
+AC_SUBST([PBX_SYSTEMD])
+AC_SUBST([SYSTEMD_LIB])
+AC_SUBST([SYSTEMD_INCLUDE])
+AST_PKG_CONFIG_CHECK([SYSTEMD], [libsystemd])
+
 PBX_SYSLOG=0
 
 if test "${ac_cv_header_syslog_h}" = "yes"; then
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 337878c..0fc13cf 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -1012,6 +1012,9 @@
 /* Define to 1 if you have the <syslog.h> header file. */
 #undef HAVE_SYSLOG_H
 
+/* Define if your system has the SYSTEMD libraries. */
+#undef HAVE_SYSTEMD
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #undef HAVE_SYS_DIR_H
diff --git a/include/asterisk/io.h b/include/asterisk/io.h
index 2bddd37..6ee8450 100644
--- a/include/asterisk/io.h
+++ b/include/asterisk/io.h
@@ -139,6 +139,16 @@
 
 int ast_get_termcols(int fd);
 
+/*!
+ * \brief a wrapper for sd_notify(): notify systemd of any state changes.
+ * \param state a string that states the changes. See sd_notify(3).
+ * The wrapper does nothing if systemd ('s development headers) was not
+ * detected on the system.
+ * \returns >=0 on success, negative value on error.
+ */
+int ast_sd_notify(const char *state);
+
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/Makefile b/main/Makefile
index 13f1c9c..e476969 100644
--- a/main/Makefile
+++ b/main/Makefile
@@ -44,6 +44,8 @@
 AST_LIBS+=$(UUID_LIB)
 AST_LIBS+=$(CRYPT_LIB)
 AST_LIBS+=$(AST_CLANG_BLOCKS_LIBS)
+AST_LIBS+=$(RT_LIB)
+AST_LIBS+=$(SYSTEMD_LIB)
 
 ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc kfreebsd-gnu),)
   ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)
diff --git a/main/asterisk.c b/main/asterisk.c
index 69f1d71..9ac9c46 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -2124,6 +2124,9 @@
 		ast_module_shutdown();
 	}
 
+	if (!restart) {
+		ast_sd_notify("STOPPING=1");
+	}
 	if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
 		ast_el_write_default_histfile();
 		if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
@@ -4612,6 +4615,7 @@
 	ast_register_cleanup(main_atexit);
 
 	run_startup_commands();
+	ast_sd_notify("READY=1");
 
 	ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));
 
diff --git a/main/io.c b/main/io.c
index cd35995..c2d2f9d 100644
--- a/main/io.c
+++ b/main/io.c
@@ -36,6 +36,9 @@
 
 #include "asterisk/io.h"
 #include "asterisk/utils.h"
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
 
 #ifdef DEBUG_IO
 #define DEBUG DEBUG_M
@@ -384,3 +387,10 @@
 	return cols;
 }
 
+int ast_sd_notify(const char *state) {
+#ifdef HAVE_SYSTEMD
+	return sd_notify(0, state);
+#else
+	return 0;
+#endif
+}
diff --git a/main/loader.c b/main/loader.c
index f660a62..85aeb24 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -897,6 +897,7 @@
 		res = AST_MODULE_RELOAD_IN_PROGRESS;
 		goto module_reload_exit;
 	}
+	ast_sd_notify("RELOAD=1");
 	ast_lastreloadtime = ast_tvnow();
 
 	if (ast_opt_lock_confdir) {
@@ -910,9 +911,8 @@
 		}
 		if (res != AST_LOCK_SUCCESS) {
 			ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
-			ast_mutex_unlock(&reloadlock);
 			res = AST_MODULE_RELOAD_ERROR;
-			goto module_reload_exit;
+			goto module_reload_done;
 		}
 	}
 
@@ -929,8 +929,7 @@
 		if (ast_opt_lock_confdir) {
 			ast_unlock_path(ast_config_AST_CONFIG_DIR);
 		}
-		ast_mutex_unlock(&reloadlock);
-		goto module_reload_exit;
+		goto module_reload_done;
 	}
 
 	AST_DLLIST_LOCK(&module_list);
@@ -972,7 +971,9 @@
 	if (ast_opt_lock_confdir) {
 		ast_unlock_path(ast_config_AST_CONFIG_DIR);
 	}
+module_reload_done:
 	ast_mutex_unlock(&reloadlock);
+	ast_sd_notify("READY=1");
 
 module_reload_exit:
 	publish_reload_message(name, res);
diff --git a/makeopts.in b/makeopts.in
index 9bd523d..20cbade 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -254,6 +254,10 @@
 SS7_INCLUDE=@SS7_INCLUDE@
 SS7_LIB=@SS7_LIB@
 
+HAVE_SYSTEMD=@PBX_SYSTEMD@
+SYSTEMD_INCLUDE=@SYSTEMD_INCLUDE@
+SYSTEMD_LIB=@SYSTEMD_LIB@
+
 OPENR2_INCLUDE=@OPENR2_INCLUDE@
 OPENR2_LIB=@OPENR2_LIB@
 

-- 
To view, visit https://gerrit.asterisk.org/3928
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ied6a59dafd5ef331c5c7ae8f3ccd2dfc94be7811
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Corey Farrell <git at cfware.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Tzafrir Cohen <tzafrir.cohen at xorcom.com>



More information about the asterisk-code-review mailing list