Skip to content

Commit a5e57fe

Browse files
committed
Add systemd notification support to olad v2
Changes from v1: - Systemd support is now switched in via a flag to the configure script. - Failures to notify systemd are logged, but only when the notification socket is actually passed. - If the socket is not passed, a warning is displayed. - Added a utility library for the sd_notify calls.
1 parent a30e440 commit a5e57fe

File tree

6 files changed

+135
-22
lines changed

6 files changed

+135
-22
lines changed

configure.ac

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,6 @@ esac
387387
have_libftd2xx="no"
388388
AM_CONDITIONAL([HAVE_LIBFTD2XX], [test "x$have_libftd2xx" = xyes])
389389

390-
# libsystemd
391-
AC_SEARCH_LIBS([sd_notify], [systemd], [have_libsystemd="yes"])
392-
AC_CHECK_HEADER([systemd/sd-daemon.h], [], [have_libsystemd="no"])
393-
394-
AS_IF([test "x$have_libsystemd" = xyes],
395-
[AC_DEFINE([HAVE_LIBSYSTEMD], [1], [define if libsystemd is installed])])
396-
397390
# ncurses
398391
AC_CHECK_LIB([ncurses], [initscr], [have_ncurses="yes"])
399392
AM_CONDITIONAL([HAVE_NCURSES], [test "x$have_ncurses" = xyes])
@@ -751,6 +744,21 @@ AC_ARG_ENABLE(
751744
[AS_HELP_STRING([--disable-doxygen-version],
752745
[Substitute the Doxygen version with latest, for the website])])
753746

747+
# systemd support
748+
AC_ARG_ENABLE(
749+
[systemd],
750+
[AS_HELP_STRING([--enable-systemd], [Enable systemd support])])
751+
752+
have_libsystemd="no"
753+
AS_IF([test "x$enable_systemd" = "xyes"],
754+
[PKG_CHECK_MODULES([libsystemd], [libsystemd >= 38], [have_libsystemd="yes"])
755+
AC_CHECK_HEADER([systemd/sd-daemon.h], [], [have_libsystemd="no"])])
756+
757+
AS_IF([test "x$have_libsystemd" = xyes],
758+
[AC_DEFINE([HAVE_LIBSYSTEMD], [1], [define if systemd support wanted])])
759+
760+
AM_CONDITIONAL([HAVE_LIBSYSTEMD], [test "x$have_libsystemd" = xyes])
761+
754762
# UUCP Lock directory
755763
AC_ARG_WITH([uucp-lock],
756764
[AS_HELP_STRING([--with-uucp-lock],

olad/Makefile.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ ola_server_sources += olad/HttpServerActions.cpp \
4242
ola_server_additional_libs += common/http/libolahttp.la
4343
endif
4444

45+
if HAVE_LIBSYSTEMD
46+
ola_server_sources += olad/NotifySystemd.cpp olad/Systemd.h
47+
ola_server_additional_libs += $(libsystemd_LIBS)
48+
endif
49+
4550
# lib olaserver
4651
lib_LTLIBRARIES += olad/libolaserver.la
4752

olad/NotifySystemd.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* This library is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 2.1 of the License, or (at your option) any later version.
6+
*
7+
* This library is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public
13+
* License along with this library; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15+
*
16+
* NotifySystemd.cpp
17+
* Provides wrapped access to the systemd notification interface.
18+
* Copyright (C) 2018 Shenghao Yang
19+
*/
20+
21+
#if HAVE_CONFIG_H
22+
#include <config.h>
23+
#endif // HAVE_CONFIG_H
24+
25+
#if HAVE_LIBSYSTEMD
26+
#include <systemd/sd-daemon.h>
27+
#include <errno.h>
28+
#include <string.h>
29+
#endif // HAVE_LIBSYSTEMD
30+
31+
#include "ola/Logging.h"
32+
33+
#include "olad/Systemd.h"
34+
35+
namespace ola {
36+
37+
int notify_systemd(int unset_environment, const char *state) {
38+
int rtn = sd_notify(unset_environment, state);
39+
if (rtn < 0) {
40+
char buf[1024];
41+
OLA_WARN << "Error sending notification to systemd: " <<
42+
strerror_r(-rtn, buf, sizeof(buf));
43+
}
44+
return rtn;
45+
}
46+
47+
bool notify_available() {
48+
return (sd_notify(0, "") != 0);
49+
}
50+
51+
} // namespace ola

olad/OlaServer.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
#include <config.h>
2323
#endif // HAVE_CONFIG_H
2424

25-
#ifdef HAVE_LIBSYSTEMD
26-
#include <systemd/sd-daemon.h>
27-
#endif // HAVE_LIBSYSTEMD
28-
2925
#include <errno.h>
3026
#include <signal.h>
3127
#include <stdio.h>
@@ -67,6 +63,10 @@
6763
#include "olad/OladHTTPServer.h"
6864
#endif // HAVE_LIBMICROHTTPD
6965

66+
#ifdef HAVE_LIBSYSTEMD
67+
#include "olad/Systemd.h"
68+
#endif // HAVE_LIBSYSTEMD
69+
7070
DEFINE_s_uint16(rpc_port, r, ola::OlaServer::DEFAULT_RPC_PORT,
7171
"The port to listen for RPCs on. Defaults to 9010.");
7272
DEFINE_default_bool(register_with_dns_sd, true,
@@ -477,15 +477,13 @@ bool OlaServer::InternalNewConnection(
477477

478478
void OlaServer::ReloadPluginsInternal() {
479479
#ifdef HAVE_LIBSYSTEMD
480-
// Return value is intentionally not checked for both calls.
481-
// See return value section under sd_notify(3).
482-
sd_notify(0, "RELOADING=1\nSTATUS=Reloading plugins\n");
480+
ola::notify_systemd(0, "RELOADING=1\nSTATUS=Reloading plugins\n");
483481
#endif // HAVE_LIBSYSTEMD
484482
OLA_INFO << "Reloading plugins";
485483
StopPlugins();
486484
m_plugin_manager->LoadAll();
487485
#ifdef HAVE_LIBSYSTEMD
488-
sd_notify(0, "READY=1\nSTATUS=Plugin reload complete\n");
486+
ola::notify_systemd(0, "READY=1\nSTATUS=Plugin reload complete\n");
489487
#endif // HAVE_LIBSYSTEMD
490488
}
491489

olad/Olad.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424
#include <config.h>
2525
#endif // HAVE_CONFIG_H
2626

27-
#if HAVE_LIBSYSTEMD
28-
#include <systemd/sd-daemon.h>
29-
#endif // HAVE_LIBSYSTEMD
30-
3127
#include <signal.h>
3228
#include <stdio.h>
3329
#include <stdlib.h>
@@ -40,6 +36,10 @@
4036
// which needs to be after WinSock2.h, hence this order
4137
#include "olad/OlaDaemon.h"
4238

39+
#if HAVE_LIBSYSTEMD
40+
#include "olad/Systemd.h"
41+
#endif // HAVE_LIBSYSTEMD
42+
4343
#include "ola/Logging.h"
4444
#include "ola/base/Credentials.h"
4545
#include "ola/base/Flags.h"
@@ -176,9 +176,14 @@ int main(int argc, char *argv[]) {
176176
#endif // _WIN32
177177

178178
#if HAVE_LIBSYSTEMD
179-
// Return value is intentionally not checked. See return value section
180-
// under sd_notify(3).
181-
sd_notify(0, "READY=1\nSTATUS=Startup complete\n");
179+
if (ola::notify_available()) {
180+
OLA_INFO << "Systemd notification socket present. Sending notifications.";
181+
} else {
182+
OLA_WARN << "Systemd notification socket not present";
183+
}
184+
// Does not need to be guarded. sd_notify does its own internal check on
185+
// the socket's presence, as well.
186+
ola::notify_systemd(0, "READY=1\nSTATUS=Startup complete\n");
182187
#endif // HAVE_LIBSYSTEMD
183188
olad->Run();
184189
return ola::EXIT_OK;

olad/Systemd.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This library is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 2.1 of the License, or (at your option) any later version.
6+
*
7+
* This library is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public
13+
* License along with this library; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15+
*
16+
* Systemd.h
17+
* Interface to systemd functionality.
18+
* Copyright (C) 2018 Shenghao Yang
19+
*/
20+
21+
#ifndef OLAD_SYSTEMD_H_
22+
#define OLAD_SYSTEMD_H_
23+
24+
namespace ola {
25+
26+
/*
27+
* @brief Notify systemd about daemon state changes.
28+
*
29+
* This function logs on failures to queue notifications, but only if the
30+
* notification socket environment variable is set.
31+
*
32+
* @param unset_environment whether to unset the notification socket environment
33+
* variable so child processes cannot utilize it.
34+
* @param state state block to pass to systemd.
35+
* @return value returned from \ref sd_notify()
36+
*/
37+
int notify_systemd(int unset_environment, const char *state);
38+
39+
/*
40+
* @brief Tests whether the systemd notification socket is available.
41+
* @return @code true if the socket is available, @code false if not.
42+
*/
43+
bool notify_available();
44+
45+
} // namespace ola
46+
#endif // OLAD_SYSTEMD_H_

0 commit comments

Comments
 (0)