Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a30e440
Add functionality to notify systemd on olad startup and config reload
shenghaoyang Jul 12, 2018
a5e57fe
Add systemd notification support to olad v2
shenghaoyang Jul 14, 2018
183ac8d
Fix license and doxygen warnings.
shenghaoyang Jul 14, 2018
693fe33
Merge branch 'master' into add_notify
shenghaoyang Jul 15, 2018
0257949
Merge branch 'master' into add_notify
shenghaoyang Jul 16, 2018
50c9bda
Style fixups for commits to add systemd notification functionality
shenghaoyang Jul 16, 2018
29556d0
Add additional checks and error messages when configuring for systemd
shenghaoyang Jul 16, 2018
b7afd38
Style changes for function names and log messages
shenghaoyang Jul 25, 2018
83807d4
Enable systemd support by default on supported build systems
shenghaoyang Jul 25, 2018
469361d
Add comment clarifying usage of strerror_r
shenghaoyang Jul 25, 2018
f15b385
Add a declaration for XSI-compliant strerror_r
shenghaoyang Jul 25, 2018
d674930
Fix formatting issues in log messages
shenghaoyang Jul 28, 2018
bf8deff
Move strerror_r wrapper into utility library
shenghaoyang Jul 28, 2018
175b393
Add new wrapper function for strerror_r and update naming
shenghaoyang Aug 9, 2018
17d917c
Merge branch 'master' into add_notify
shenghaoyang Aug 9, 2018
1cd1202
Refactor StrError_R() and fix doxygen references.
shenghaoyang Aug 10, 2018
64400b8
Merge branch 'master' into add_notify
shenghaoyang Aug 11, 2018
d62a8f6
Fix formatting, style, and spelling, refactor StrError_R
shenghaoyang Aug 12, 2018
ff34724
Add config error on being unable to explicitly enable systemd support
shenghaoyang Aug 12, 2018
f6f5813
Switch to internal ola library function for int to string conversion
shenghaoyang Aug 12, 2018
15efd6f
Merge branch 'master' into add_notify
shenghaoyang Aug 19, 2018
18735c4
Merge branch 'master' into add_notify
shenghaoyang Aug 25, 2018
a21f0a4
Add systemd unit file for running olad with systemd in user mode
shenghaoyang Aug 25, 2018
c714ee8
Add more documentation URLs to the unit file for the user instance.
shenghaoyang Sep 10, 2018
527b115
Merge branch 'master' into add_notify
shenghaoyang Sep 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions common/base/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ common_libolacommon_la_SOURCES += \
common/base/SysExits.cpp \
common/base/Version.cpp

if HAVE_STRERROR_R
common_libolacommon_la_SOURCES += common/base/StrError_R.cpp \
common/base/StrError_R_XSI.cpp
endif

# TESTS
##################################################

Expand Down
50 changes: 50 additions & 0 deletions common/base/StrError_R.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* StrError_R.cpp
* Helper function for StrError_R_XSI().
* Copyright (C) 2018 Shenghao Yang
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#include <stdio.h>
#include <string.h>

#include <limits>
#include <string>
#include <sstream>

#include "ola/base/StrError_R.h"
#include "ola/strings/Format.h"

namespace ola {

const int StrError_R_BufSize = 1024;

std::string StrError_R(int errnum) {
// Pre-allocate to prevent re-allocation.
std::string out(StrError_R_BufSize, '\0');
if (StrError_R_XSI(errnum, &(out[0]), out.size())) {
out.assign(std::string("errno = ") + ola::strings::IntToString(errnum));
} else {
out.resize(strlen(&(out[0])));
}
return out;
}

} // namespace ola
51 changes: 51 additions & 0 deletions common/base/StrError_R_XSI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* StrError_R_XSI.cpp
* Definition of strerror_r() that is XSI-compliant.
* This extra file is required because the header declaring the symbols
* for the C++ string library conflicts with the macros used to expose
* the XSI-compliant declaration of strerror_r().
* Copyright (C) 2018 Shenghao Yang
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

// Required for string.h to declare the standards-compliant version of
// strerror_r(), when compiling under glibc. Must come before the inclusion
// of string.h.
// These are conditional to avoid errors when not compiling with glibc, or
// when compiling with a compiler that does not define _POSIX_C_SOURCE.
// See strerror(3) as to why the macros are defined this way.
#ifdef _GNU_SOURCE
#undef _GNU_SOURCE
#endif

#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200112L

#include <string.h>

namespace ola {

int StrError_R_XSI(int errnum, char* buf, size_t buflen) {
return strerror_r(errnum, buf, buflen);
}

} // namespace ola
32 changes: 30 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ AC_FUNC_CLOSEDIR_VOID
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([bzero gettimeofday memmove memset mkdir strdup strrchr \
if_nametoindex inet_ntoa inet_ntop inet_aton inet_pton select \
socket strerror getifaddrs getloadavg getpwnam_r getpwuid_r \
getgrnam_r getgrgid_r secure_getenv])
socket strerror strerror_r getifaddrs getloadavg getpwnam_r \
getpwuid_r getgrnam_r getgrgid_r secure_getenv])

AC_MSG_CHECKING(for readdir_r deprecation)
old_cxxflags=$CXXFLAGS
Expand Down Expand Up @@ -234,6 +234,9 @@ AM_CONDITIONAL(HAVE_EPOLL, test "${ax_cv_have_epoll}" = "yes")
AC_CHECK_FUNCS([kqueue])
AM_CONDITIONAL(HAVE_KQUEUE, test "${ac_cv_func_kqueue}" = "yes")

# strerror_r
AM_CONDITIONAL([HAVE_STRERROR_R], [test "x$ac_cv_func_strerror_r" = "xyes"])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can drop the x's and square brackets here, looking at HAVE_KQUEUE just above, which will have had broader OS testing.


# check if the compiler supports -rdynamic
AC_MSG_CHECKING(for -rdynamic support)
old_cppflags=$CPPFLAGS
Expand Down Expand Up @@ -756,6 +759,31 @@ AC_ARG_ENABLE(
[AS_HELP_STRING([--disable-doxygen-version],
[Substitute the Doxygen version with latest, for the website])])

# systemd support
AC_ARG_ENABLE(
[systemd],
[AS_HELP_STRING([--disable-systemd], [Disable systemd support])])

have_libsystemd="no"
AS_IF([test "x$enable_systemd" != xno],
[PKG_CHECK_MODULES([libsystemd], [libsystemd >= 38], [have_libsystemd=yes],
[AC_MSG_WARN([disabling systemd support: can't find libsystemd])])
AC_CHECK_HEADER([systemd/sd-daemon.h], [],
[have_libsystemd=no
AC_MSG_WARN([disabling systemd support: can't find systemd/sd-daemon.h])])
AS_IF([test "x$ac_cv_func_strerror_r" = xno],
[have_libsystemd=no
AC_MSG_WARN([disabling systemd support: can't find strerror_r])])])

AS_IF([test "x$have_libsystemd" = xyes],
[AC_DEFINE([HAVE_LIBSYSTEMD], [1],
[define if systemd support is wanted and libsystemd is present])])

AM_CONDITIONAL([HAVE_LIBSYSTEMD], [test "x$have_libsystemd" = xyes])

AS_IF([test "x$enable_systemd" = xyes && test "x$have_libsystemd" = xno],
[AC_MSG_ERROR([could not enable systemd support])])

# UUCP Lock directory
AC_ARG_WITH([uucp-lock],
[AS_HELP_STRING([--with-uucp-lock],
Expand Down
4 changes: 4 additions & 0 deletions include/ola/base/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ olabaseinclude_HEADERS = \
include/ola/base/Macro.h \
include/ola/base/SysExits.h

if HAVE_STRERROR_R
olabaseinclude_HEADERS += include/ola/base/StrError_R.h
endif

nodist_olabaseinclude_HEADERS = \
include/ola/base/Version.h
79 changes: 79 additions & 0 deletions include/ola/base/StrError_R.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* StrError_R.h
* Helper functions for strerror_r and a declaration of strerror_r that is
* XSI-compliant.
* Copyright (C) 2018 Shenghao Yang
*/

/**
* @defgroup strerror Description of system error codes
* @brief Error descriptions
* @details Convenience functions to obtain descriptions of system error codes.
* The functions and variables in this group are only defined if \c strerror_r()
* is available.
*/

/**
* @addtogroup strerror
* @{
* @file StrError_R.h
* @}
*/

#ifndef INCLUDE_OLA_BASE_STRERROR_R_H_
#define INCLUDE_OLA_BASE_STRERROR_R_H_

#include <string>

namespace ola {

/**
* @addtogroup strerror
* @{
*/

/**
* @brief Length of the internal buffer used for @ref StrError_R().
*
* If the length of the system-provided error description exceeds the length
* of this buffer minus one, then the output of @ref StrError_R() will only
* include the numerical error value provided.
*/
extern const int StrError_R_BufSize;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually static const, is there a reason you need extern?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we static const here - then every compilation unit that includes this header file would have their own copy of StrError_R_BufSize. extern here just lets me allocate storage for it in that one unit and have the other units referencing this variable link to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could #define stuff.... but I'd want to avoid that route - maybe future refactoring to constexpr or inline constexpr in future?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One for @nomis52 then as to why we've gone for static const over extern const?


/**
* @brief XSI-compliant version of \c strerror_r().
*
* @see https://linux.die.net/man/3/strerror for more details.
*/
int StrError_R_XSI(int errnum, char* buf, size_t buflen);

/**
* @brief Convenience function that wraps @ref StrError_R_XSI().
*
* @param errnum error value to generate the textual description for.
* @return Textual description of the error value. If the description is
* truncated due to an insufficient buffer length, the description will
* be in the form: "errno = errnum".
* @sa StrError_R_BufSize for information regarding truncation.
*/
std::string StrError_R(int errnum);

/**@}*/
} // namespace ola

#endif // INCLUDE_OLA_BASE_STRERROR_R_H_
5 changes: 5 additions & 0 deletions olad/Makefile.mk
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ ola_server_sources += olad/HttpServerActions.cpp \
ola_server_additional_libs += common/http/libolahttp.la
endif

if HAVE_LIBSYSTEMD
ola_server_sources += olad/Systemd.cpp olad/Systemd.h
ola_server_additional_libs += $(libsystemd_LIBS)
endif

# lib olaserver
lib_LTLIBRARIES += olad/libolaserver.la

Expand Down
10 changes: 10 additions & 0 deletions olad/OlaServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
#include "olad/OladHTTPServer.h"
#endif // HAVE_LIBMICROHTTPD

#ifdef HAVE_LIBSYSTEMD
#include "olad/Systemd.h"
#endif // HAVE_LIBSYSTEMD

DEFINE_s_uint16(rpc_port, r, ola::OlaServer::DEFAULT_RPC_PORT,
"The port to listen for RPCs on. Defaults to 9010.");
DEFINE_default_bool(register_with_dns_sd, true,
Expand Down Expand Up @@ -472,9 +476,15 @@ bool OlaServer::InternalNewConnection(
}

void OlaServer::ReloadPluginsInternal() {
#ifdef HAVE_LIBSYSTEMD
ola::SystemdNotify(0, "RELOADING=1\nSTATUS=Reloading plugins\n");
#endif // HAVE_LIBSYSTEMD
OLA_INFO << "Reloading plugins";
StopPlugins();
m_plugin_manager->LoadAll();
#ifdef HAVE_LIBSYSTEMD
ola::SystemdNotify(0, "READY=1\nSTATUS=Plugin reload complete\n");
#endif // HAVE_LIBSYSTEMD
}

void OlaServer::UpdatePidStore(const RootPidStore *pid_store) {
Expand Down
16 changes: 16 additions & 0 deletions olad/Olad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
// which needs to be after WinSock2.h, hence this order
#include "olad/OlaDaemon.h"

#if HAVE_LIBSYSTEMD
#include "olad/Systemd.h"
#endif // HAVE_LIBSYSTEMD

#include "ola/Logging.h"
#include "ola/base/Credentials.h"
#include "ola/base/Flags.h"
Expand Down Expand Up @@ -172,6 +176,18 @@ int main(int argc, char *argv[]) {
ola::NewCallback(olad->GetOlaServer(), &ola::OlaServer::ReloadPlugins));
#endif // _WIN32

#if HAVE_LIBSYSTEMD
if (ola::SystemdNotifyAvailable()) {
OLA_INFO << "Systemd notification socket address present, "
<< "sending notifications.";
} else {
OLA_WARN << "Systemd notification socket address not present, "
<< "not sending notifications.";
}
// Does not need to be guarded. sd_notify does its own internal check on
// the socket's presence, as well.
ola::SystemdNotify(0, "READY=1\nSTATUS=Startup complete\n");
#endif // HAVE_LIBSYSTEMD
olad->Run();
return ola::EXIT_OK;
}
49 changes: 49 additions & 0 deletions olad/Systemd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Systemd.cpp
* Provides wrapped access to systemd interfaces.
* Copyright (C) 2018 Shenghao Yang
*/

#if HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#if HAVE_LIBSYSTEMD
#include <systemd/sd-daemon.h>
#endif // HAVE_LIBSYSTEMD

#include "ola/Logging.h"
#include "ola/base/StrError_R.h"

#include "olad/Systemd.h"

namespace ola {

int SystemdNotify(int unset_environment, const char *state) {
int rtn = sd_notify(unset_environment, state);
if (rtn < 0) {
OLA_WARN << "Error sending notification to systemd: "
<< ola::StrError_R(-rtn);
}
return rtn;
}

bool SystemdNotifyAvailable() {
return (sd_notify(0, "") != 0);
}

} // namespace ola
Loading