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
changes/94/3094/4
Tzafrir Cohen 9 years ago
parent 95cf4f8d31
commit 07b95f7c65

@ -347,6 +347,10 @@ Core
in the context. If enabled a device state hint will be automatically created in the context. If enabled a device state hint will be automatically created
with the name of the device. with the name of the device.
* 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.
Functions Functions
------------------ ------------------
* The func_odbc global option "single_db_connection" default value has been * The func_odbc global option "single_db_connection" default value has been

119
configure vendored

@ -639,6 +639,11 @@ PBX_SYSLOG_FACILITY_LOG_DAEMON
PBX_SYSLOG_FACILITY_LOG_CRON PBX_SYSLOG_FACILITY_LOG_CRON
PBX_SYSLOG_FACILITY_LOG_AUTHPRIV PBX_SYSLOG_FACILITY_LOG_AUTHPRIV
PBX_SYSLOG_FACILITY_LOG_AUTH PBX_SYSLOG_FACILITY_LOG_AUTH
SYSTEMD_LIBS
SYSTEMD_CFLAGS
SYSTEMD_INCLUDE
SYSTEMD_LIB
PBX_SYSTEMD
PBX_GENERIC_ODBC PBX_GENERIC_ODBC
GENERIC_ODBC_INCLUDE GENERIC_ODBC_INCLUDE
GENERIC_ODBC_LIB GENERIC_ODBC_LIB
@ -1320,6 +1325,7 @@ infodir
docdir docdir
oldincludedir oldincludedir
includedir includedir
runstatedir
localstatedir localstatedir
sharedstatedir sharedstatedir
sysconfdir sysconfdir
@ -1460,7 +1466,9 @@ PYTHONDEV_LIBS
GMIME_CFLAGS GMIME_CFLAGS
GMIME_LIBS GMIME_LIBS
GTK2_CFLAGS GTK2_CFLAGS
GTK2_LIBS' GTK2_LIBS
SYSTEMD_CFLAGS
SYSTEMD_LIBS'
# Initialize some variables set by options. # Initialize some variables set by options.
@ -1499,6 +1507,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc' sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com' sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var' localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include' includedir='${prefix}/include'
oldincludedir='/usr/include' oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1751,6 +1760,15 @@ do
| -silent | --silent | --silen | --sile | --sil) | -silent | --silent | --silen | --sile | --sil)
silent=yes ;; 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) -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;; ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1888,7 +1906,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \ datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir libdir localedir mandir runstatedir
do do
eval ac_val=\$$ac_var eval ac_val=\$$ac_var
# Remove trailing slashes. # Remove trailing slashes.
@ -2041,6 +2059,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var] --localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib] --libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include] --includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include] --oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -2213,6 +2232,10 @@ Some influential environment variables:
GMIME_LIBS linker flags for GMIME, overriding pkg-config GMIME_LIBS linker flags for GMIME, overriding pkg-config
GTK2_CFLAGS C compiler flags for GTK2, overriding pkg-config GTK2_CFLAGS C compiler flags for GTK2, overriding pkg-config
GTK2_LIBS linker 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 Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations. it to find libraries and programs with nonstandard names/locations.
@ -34811,6 +34834,98 @@ fi
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 PBX_SYSLOG=0
if test "${ac_cv_header_syslog_h}" = "yes"; then if test "${ac_cv_header_syslog_h}" = "yes"; then

@ -2630,6 +2630,11 @@ AC_SUBST([GENERIC_ODBC_LIB])
AC_SUBST([GENERIC_ODBC_INCLUDE]) AC_SUBST([GENERIC_ODBC_INCLUDE])
AC_SUBST([PBX_GENERIC_ODBC]) 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 PBX_SYSLOG=0
if test "${ac_cv_header_syslog_h}" = "yes"; then if test "${ac_cv_header_syslog_h}" = "yes"; then

@ -1027,6 +1027,9 @@
/* Define to 1 if you have the <syslog.h> header file. */ /* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H #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'. /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/ */
#undef HAVE_SYS_DIR_H #undef HAVE_SYS_DIR_H

@ -139,6 +139,16 @@ int ast_restore_tty(int fd, int oldstatus);
int ast_get_termcols(int fd); 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) #if defined(__cplusplus) || defined(c_plusplus)
} }
#endif #endif

@ -45,6 +45,7 @@ AST_LIBS+=$(UUID_LIB)
AST_LIBS+=$(CRYPT_LIB) AST_LIBS+=$(CRYPT_LIB)
AST_LIBS+=$(AST_CLANG_BLOCKS_LIBS) AST_LIBS+=$(AST_CLANG_BLOCKS_LIBS)
AST_LIBS+=$(RT_LIB) AST_LIBS+=$(RT_LIB)
AST_LIBS+=$(SYSTEMD_LIB)
ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc linux-musl kfreebsd-gnu),) ifneq ($(findstring $(OSARCH), linux-gnu uclinux linux-uclibc linux-musl kfreebsd-gnu),)
ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),) ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),)

@ -1999,6 +1999,9 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
ast_module_shutdown(); ast_module_shutdown();
} }
if (!restart) {
ast_sd_notify("STOPPING=1");
}
if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) { if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) {
ast_el_write_default_histfile(); ast_el_write_default_histfile();
if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) { if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) {
@ -4526,6 +4529,7 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou
ast_register_cleanup(main_atexit); ast_register_cleanup(main_atexit);
run_startup_commands(); run_startup_commands();
ast_sd_notify("READY=1");
ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready.")); ast_verb(0, COLORIZE_FMT "\n", COLORIZE(COLOR_BRGREEN, 0, "Asterisk Ready."));

@ -36,6 +36,9 @@ ASTERISK_REGISTER_FILE()
#include "asterisk/io.h" #include "asterisk/io.h"
#include "asterisk/utils.h" #include "asterisk/utils.h"
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#ifdef DEBUG_IO #ifdef DEBUG_IO
#define DEBUG DEBUG_M #define DEBUG DEBUG_M
@ -384,3 +387,10 @@ int ast_get_termcols(int fd)
return cols; return cols;
} }
int ast_sd_notify(const char *state) {
#ifdef HAVE_SYSTEMD
return sd_notify(0, state);
#else
return 0;
#endif
}

@ -891,6 +891,7 @@ enum ast_module_reload_result ast_module_reload(const char *name)
res = AST_MODULE_RELOAD_IN_PROGRESS; res = AST_MODULE_RELOAD_IN_PROGRESS;
goto module_reload_exit; goto module_reload_exit;
} }
ast_sd_notify("RELOAD=1");
ast_lastreloadtime = ast_tvnow(); ast_lastreloadtime = ast_tvnow();
if (ast_opt_lock_confdir) { if (ast_opt_lock_confdir) {
@ -904,9 +905,8 @@ enum ast_module_reload_result ast_module_reload(const char *name)
} }
if (res != AST_LOCK_SUCCESS) { if (res != AST_LOCK_SUCCESS) {
ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR); 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; res = AST_MODULE_RELOAD_ERROR;
goto module_reload_exit; goto module_reload_done;
} }
} }
@ -923,8 +923,7 @@ enum ast_module_reload_result ast_module_reload(const char *name)
if (ast_opt_lock_confdir) { if (ast_opt_lock_confdir) {
ast_unlock_path(ast_config_AST_CONFIG_DIR); ast_unlock_path(ast_config_AST_CONFIG_DIR);
} }
ast_mutex_unlock(&reloadlock); goto module_reload_done;
goto module_reload_exit;
} }
AST_DLLIST_LOCK(&module_list); AST_DLLIST_LOCK(&module_list);
@ -966,7 +965,9 @@ enum ast_module_reload_result ast_module_reload(const char *name)
if (ast_opt_lock_confdir) { if (ast_opt_lock_confdir) {
ast_unlock_path(ast_config_AST_CONFIG_DIR); ast_unlock_path(ast_config_AST_CONFIG_DIR);
} }
module_reload_done:
ast_mutex_unlock(&reloadlock); ast_mutex_unlock(&reloadlock);
ast_sd_notify("READY=1");
module_reload_exit: module_reload_exit:
publish_reload_message(name, res); publish_reload_message(name, res);

@ -259,6 +259,10 @@ RT_LIB=@RT_LIB@
SS7_INCLUDE=@SS7_INCLUDE@ SS7_INCLUDE=@SS7_INCLUDE@
SS7_LIB=@SS7_LIB@ SS7_LIB=@SS7_LIB@
HAVE_SYSTEMD=@PBX_SYSTEMD@
SYSTEMD_INCLUDE=@SYSTEMD_INCLUDE@
SYSTEMD_LIB=@SYSTEMD_LIB@
OPENR2_INCLUDE=@OPENR2_INCLUDE@ OPENR2_INCLUDE=@OPENR2_INCLUDE@
OPENR2_LIB=@OPENR2_LIB@ OPENR2_LIB=@OPENR2_LIB@

Loading…
Cancel
Save