diff --git a/CHANGES b/CHANGES index 38228e37a2..da732a7ebb 100644 --- a/CHANGES +++ b/CHANGES @@ -347,6 +347,10 @@ Core in the context. If enabled a device state hint will be automatically created 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 ------------------ * The func_odbc global option "single_db_connection" default value has been diff --git a/configure b/configure index 51f0623282..a5da739c04 100755 --- a/configure +++ b/configure @@ -639,6 +639,11 @@ PBX_SYSLOG_FACILITY_LOG_DAEMON 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 @@ -1320,6 +1325,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -1460,7 +1466,9 @@ PYTHONDEV_LIBS GMIME_CFLAGS GMIME_LIBS GTK2_CFLAGS -GTK2_LIBS' +GTK2_LIBS +SYSTEMD_CFLAGS +SYSTEMD_LIBS' # Initialize some variables set by options. @@ -1499,6 +1507,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1751,6 +1760,15 @@ do | -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=* \ @@ -1888,7 +1906,7 @@ fi 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. @@ -2041,6 +2059,7 @@ Fine tuning of the installation directories: --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] @@ -2213,6 +2232,10 @@ Some influential environment variables: 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. @@ -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 if test "${ac_cv_header_syslog_h}" = "yes"; then diff --git a/configure.ac b/configure.ac index e7fc21c66e..17b887266f 100644 --- a/configure.ac +++ b/configure.ac @@ -2630,6 +2630,11 @@ AC_SUBST([GENERIC_ODBC_LIB]) 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 5e7ea7e2ae..e16b668615 100644 --- a/include/asterisk/autoconfig.h.in +++ b/include/asterisk/autoconfig.h.in @@ -1027,6 +1027,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H +/* Define if your system has the SYSTEMD libraries. */ +#undef HAVE_SYSTEMD + /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H diff --git a/include/asterisk/io.h b/include/asterisk/io.h index 2bddd3780b..6ee8450bd7 100644 --- a/include/asterisk/io.h +++ b/include/asterisk/io.h @@ -139,6 +139,16 @@ int ast_restore_tty(int fd, int oldstatus); 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 a6c3ab1b87..d41302a7fc 100644 --- a/main/Makefile +++ b/main/Makefile @@ -45,6 +45,7 @@ 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 linux-musl kfreebsd-gnu),) ifneq ($(findstring LOADABLE_MODULES,$(MENUSELECT_CFLAGS)),) diff --git a/main/asterisk.c b/main/asterisk.c index 7b1338c3dc..c9e3b59a5b 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -2039,6 +2039,9 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart) 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()) { @@ -4566,6 +4569,7 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou 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 ff5ca57f79..3441fbae9f 100644 --- a/main/io.c +++ b/main/io.c @@ -36,6 +36,9 @@ ASTERISK_REGISTER_FILE() #include "asterisk/io.h" #include "asterisk/utils.h" +#ifdef HAVE_SYSTEMD +#include +#endif #ifdef DEBUG_IO #define DEBUG DEBUG_M @@ -384,3 +387,10 @@ int ast_get_termcols(int fd) 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 f959221738..36a3d5f61b 100644 --- a/main/loader.c +++ b/main/loader.c @@ -891,6 +891,7 @@ enum ast_module_reload_result ast_module_reload(const char *name) res = AST_MODULE_RELOAD_IN_PROGRESS; goto module_reload_exit; } + ast_sd_notify("RELOAD=1"); ast_lastreloadtime = ast_tvnow(); 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) { 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; } } @@ -923,8 +923,7 @@ enum ast_module_reload_result ast_module_reload(const char *name) 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); @@ -966,7 +965,9 @@ enum ast_module_reload_result ast_module_reload(const char *name) 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 86b7f9d99a..b2b394b5f1 100644 --- a/makeopts.in +++ b/makeopts.in @@ -259,6 +259,10 @@ RT_LIB=@RT_LIB@ 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@