Add Systemd integration to aes67-daemon
This adds integration and especially watchdog support between aes67-daemon and systemd. A example service file is also included.
This commit is contained in:
parent
885dd7146e
commit
a28a6e148f
@ -11,6 +11,8 @@ option(WITH_AVAHI "Include mDNS support via Avahi" OFF)
|
|||||||
option(FAKE_DRIVER "Use fake driver instead of RAVENNA" OFF)
|
option(FAKE_DRIVER "Use fake driver instead of RAVENNA" OFF)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
option(WITH_SYSTEMD "Include systemd notify and watchdog support" OFF)
|
||||||
|
|
||||||
# ravena lkm _should_ be provided by the CLI. Nonetheless, we should be able
|
# ravena lkm _should_ be provided by the CLI. Nonetheless, we should be able
|
||||||
# to find it in system dirs too...
|
# to find it in system dirs too...
|
||||||
if (NOT RAVENNNA_ALSA_LKM_DIR)
|
if (NOT RAVENNNA_ALSA_LKM_DIR)
|
||||||
@ -54,3 +56,9 @@ if(WITH_AVAHI)
|
|||||||
include_directories(aes67-daemon ${AVAHI_INCLUDE_DIRS})
|
include_directories(aes67-daemon ${AVAHI_INCLUDE_DIRS})
|
||||||
target_link_libraries(aes67-daemon ${AVAHI_LIBRARIES})
|
target_link_libraries(aes67-daemon ${AVAHI_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_SYSTEMD)
|
||||||
|
MESSAGE(STATUS "WITH_SYSTEMD")
|
||||||
|
add_definitions(-D_USE_SYSTEMD_)
|
||||||
|
target_link_libraries(aes67-daemon systemd)
|
||||||
|
endif()
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
#include "rtsp_server.hpp"
|
#include "rtsp_server.hpp"
|
||||||
#include "session_manager.hpp"
|
#include "session_manager.hpp"
|
||||||
|
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
#include <systemd/sd-daemon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
namespace postyle = boost::program_options::command_line_style;
|
namespace postyle = boost::program_options::command_line_style;
|
||||||
namespace logging = boost::log;
|
namespace logging = boost::log;
|
||||||
@ -64,6 +68,11 @@ int main(int argc, char* argv[]) {
|
|||||||
int unix_style = postyle::unix_style | postyle::short_allow_next;
|
int unix_style = postyle::unix_style | postyle::short_allow_next;
|
||||||
bool driver_restart(true);
|
bool driver_restart(true);
|
||||||
|
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
// with which interval we should pet the dog
|
||||||
|
uint64_t current_watchdog_usec;
|
||||||
|
#endif
|
||||||
|
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
try {
|
try {
|
||||||
po::store(po::command_line_parser(argc, argv)
|
po::store(po::command_line_parser(argc, argv)
|
||||||
@ -98,6 +107,17 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::string filename = vm["config"].as<std::string>();
|
std::string filename = vm["config"].as<std::string>();
|
||||||
|
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
sd_watchdog_enabled(0, ¤t_watchdog_usec);
|
||||||
|
|
||||||
|
if (current_watchdog_usec > 0) {
|
||||||
|
// Inform systemd that if we're not petting the dog in 5s we're bust.
|
||||||
|
sd_notify(0, "WATCHDOG_USEC=5000000");
|
||||||
|
|
||||||
|
current_watchdog_usec = 5000000;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while (!is_terminated() && rc == EXIT_SUCCESS) {
|
while (!is_terminated() && rc == EXIT_SUCCESS) {
|
||||||
/* load configuration from file */
|
/* load configuration from file */
|
||||||
auto config = Config::parse(filename, driver_restart);
|
auto config = Config::parse(filename, driver_restart);
|
||||||
@ -112,6 +132,11 @@ int main(int argc, char* argv[]) {
|
|||||||
log_init(*config);
|
log_init(*config);
|
||||||
|
|
||||||
if (config->get_ip_addr_str().empty()) {
|
if (config->get_ip_addr_str().empty()) {
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
if (current_watchdog_usec > 0)
|
||||||
|
sd_notify(0, "WATCHDOG=1");
|
||||||
|
sd_notify(0, "STATUS=no IP address, waiting ...");
|
||||||
|
#endif
|
||||||
BOOST_LOG_TRIVIAL(info) << "main:: no IP address, waiting ...";
|
BOOST_LOG_TRIVIAL(info) << "main:: no IP address, waiting ...";
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
continue;
|
continue;
|
||||||
@ -159,7 +184,22 @@ int main(int argc, char* argv[]) {
|
|||||||
session_manager->load_status();
|
session_manager->load_status();
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "main:: init done, entering loop...";
|
BOOST_LOG_TRIVIAL(debug) << "main:: init done, entering loop...";
|
||||||
|
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
// To be able to use sd_notify at all have to set service NotifyAccess
|
||||||
|
// (e.g. to main)
|
||||||
|
sd_notify(0, "READY=1"); // If service Type=notify the service is only
|
||||||
|
// considered ready once we send this (this is
|
||||||
|
// independent of watchdog capability)
|
||||||
|
sd_notify(0, "STATUS=Working");
|
||||||
|
#endif
|
||||||
|
|
||||||
while (!is_terminated()) {
|
while (!is_terminated()) {
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
if (current_watchdog_usec > 0)
|
||||||
|
sd_notify(0, "WATCHDOG=1");
|
||||||
|
#endif
|
||||||
|
|
||||||
auto [ip_addr, ip_str] = get_interface_ip(config->get_interface_name());
|
auto [ip_addr, ip_str] = get_interface_ip(config->get_interface_name());
|
||||||
if (config->get_ip_addr_str() != ip_str) {
|
if (config->get_ip_addr_str() != ip_str) {
|
||||||
BOOST_LOG_TRIVIAL(warning)
|
BOOST_LOG_TRIVIAL(warning)
|
||||||
@ -175,6 +215,10 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
}
|
}
|
||||||
|
#ifdef _USE_SYSTEMD_
|
||||||
|
sd_notify(0, "STOPPING=1");
|
||||||
|
sd_notify(0, "STATUS=Stopping");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* save session status to file */
|
/* save session status to file */
|
||||||
session_manager->save_status();
|
session_manager->save_status();
|
||||||
|
2
systemd/aes67-daemon.conf
Normal file
2
systemd/aes67-daemon.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#Type Name ID GECOS Home directory Shell
|
||||||
|
u aes67-daemon - "AES67 daemon user"
|
60
systemd/aes67-daemon.service
Normal file
60
systemd/aes67-daemon.service
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=AES67 daemon service
|
||||||
|
Before=multi-user.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=notify
|
||||||
|
# Will be adjusted by service during startup
|
||||||
|
WatchdogSec=10
|
||||||
|
|
||||||
|
# Run as separate user created via sysusers.d
|
||||||
|
User=aes67-daemon
|
||||||
|
|
||||||
|
ExecStart=/usr/local/bin/aes67-daemon
|
||||||
|
|
||||||
|
# Security filters.
|
||||||
|
CapabilityBoundingSet=
|
||||||
|
DevicePolicy=closed
|
||||||
|
LockPersonality=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
PrivateMounts=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateUsers=yes
|
||||||
|
# interface::get_mac_from_arp_cache() reads from /proc/net/arp
|
||||||
|
ProcSubset=all
|
||||||
|
ProtectClock=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
ProtectHome=yes
|
||||||
|
ProtectHostname=yes
|
||||||
|
ProtectKernelLogs=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectProc=invisible
|
||||||
|
ProtectSystem=strict
|
||||||
|
RemoveIPC=yes
|
||||||
|
RestrictAddressFamilies=AF_INET AF_NETLINK AF_UNIX
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
RestrictRealtime=yes
|
||||||
|
RestrictSUIDSGID=yes
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallFilter=~@clock
|
||||||
|
SystemCallFilter=~@cpu-emulation
|
||||||
|
SystemCallFilter=~@debug
|
||||||
|
SystemCallFilter=~@module
|
||||||
|
SystemCallFilter=~@mount
|
||||||
|
SystemCallFilter=~@obsolete
|
||||||
|
SystemCallFilter=~@privileged
|
||||||
|
SystemCallFilter=~@raw-io
|
||||||
|
SystemCallFilter=~@reboot
|
||||||
|
SystemCallFilter=~@resources
|
||||||
|
SystemCallFilter=~@swap
|
||||||
|
UMask=077
|
||||||
|
# Paths matching daemon.conf
|
||||||
|
ReadWritePaths=/etc/daemon.conf
|
||||||
|
ReadWritePaths=/etc/status.json
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
x
Reference in New Issue
Block a user