Skip to content

Commit

Permalink
Systemd watchdog notification (#57)
Browse files Browse the repository at this point in the history
* feat: feed systemd watchdog

* add libsystemd-dev as build dependency

* fix: put watchdog feed in the right place

* ci: install libsystemd-dev in ubuntu

* ci: don't run alpine build

* add watchdog parameter to systemd unit

* keep feeding watchdog during shutdown

* chore: update watchdog only when needed

* chore: remove unused CI definition completely
  • Loading branch information
potaito authored Apr 23, 2024
1 parent 5a01d7f commit f6124f8
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 20 deletions.
17 changes: 1 addition & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
apt install autoconf autogen libtool systemd -y
apt install autoconf autogen libtool systemd libsystemd-dev -y
- name: Build
run: |
./autogen.sh && ./configure CFLAGS='-g -O2' --sysconfdir=/etc --localstatedir=/var --libdir=/usr/lib64 --prefix=/usr
Expand All @@ -24,18 +24,3 @@ jobs:
run: |
make mainloop_test
./mainloop_test
alpine-linux:
name: alpine 3.18 (musl)
runs-on: ubuntu-22.04
container: alpine:3.18
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- name: install tools
run: apk update && apk add autoconf automake build-base git libtool linux-headers openssl-dev perl-extutils-pkgconfig python3 py3-future
- name: configure
run: ./autogen.sh && ./configure CFLAGS='-g -O2' --sysconfdir=/etc --localstatedir=/var --libdir=/usr/lib --disable-systemd --prefix=/usr
- name: build
run: make
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The following libraries need also to be installed :
$ sudo apt install libtool
$ sudo apt install autoconf
$ sudo apt install pkg-config
$ sudo apt install libsystemd-dev

#### Build ####

Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ AM_CONDITIONAL([HAVE_GTEST], [test x$HAVE_GTEST = xtrue])
AC_SUBST([GTEST_LIBS])
AC_SUBST([GTEST_CFLAGS])

AC_CHECK_LIB([systemd], [main], [], [AC_MSG_ERROR([systemd library not found])])
AC_SUBST([LIBS], ["-lsystemd"])

#####################################################################
# --with-
#####################################################################
Expand Down
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Build-Depends:
libgtest-dev,
libc6,
libstdc++6,
libsystemd-dev,
Standards-Version: 4.1.3
Homepage: https://github.com/Auterion/mavlink-router

Expand Down
1 change: 1 addition & 0 deletions mavlink-router.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Type=simple
ExecStart=@bindir@/mavlink-routerd
Restart=always
Nice=-20
WatchdogSec=5s

[Install]
WantedBy=multi-user.target
43 changes: 39 additions & 4 deletions src/mavlink-router/mainloop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
*/
#include "mainloop.h"

#include <chrono>
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <systemd/sd-daemon.h>

#include <memory>
#include <vector>
Expand Down Expand Up @@ -280,6 +282,10 @@ void Mainloop::handle_tcp_connection()

int Mainloop::loop()
{
sd_notify(0, "READY=1");
const int watchdog_interval_us = _watchdogIntervalUs();
auto last_watchdog_update = std::chrono::steady_clock::now();

if (epollfd < 0)
return EXIT_FAILURE;

Expand All @@ -290,6 +296,16 @@ int Mainloop::loop()

while (!_should_exit.load(std::memory_order_relaxed)) {
run_single(-1);

// Watchdog update
if (watchdog_interval_us > 0) {
const auto now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::microseconds>(now - last_watchdog_update)
.count() > watchdog_interval_us) {
last_watchdog_update = now;
sd_notify(0, "WATCHDOG=1");
}
}
}

// This is a bit weird, but models previous behavior: run event handling a
Expand All @@ -298,12 +314,22 @@ int Mainloop::loop()
if (_log_endpoint) {
_log_endpoint->stop();

usec_t now = now_usec();
usec_t deadline = now + TIMEOUT_LOG_SHUTDOWN_US;
auto now = std::chrono::steady_clock::now();
const auto deadline = now + std::chrono::microseconds(TIMEOUT_LOG_SHUTDOWN_US);

while (now < deadline) {
run_single((deadline - now) / 1000);
now = now_usec();
run_single(std::chrono::duration_cast<std::chrono::milliseconds>(deadline - now).count());

// Watchdog update
if (watchdog_interval_us > 0) {
if (std::chrono::duration_cast<std::chrono::microseconds>(now - last_watchdog_update)
.count() > watchdog_interval_us) {
last_watchdog_update = now;
sd_notify(0, "WATCHDOG=1");
}
}

now = std::chrono::steady_clock::now();
}

_log_endpoint->stop();
Expand Down Expand Up @@ -934,6 +960,15 @@ void Mainloop::_handle_pipe()
}
}

int Mainloop::_watchdogIntervalUs()
{
const char* watchdog_usec_env = getenv("WATCHDOG_USEC");
if (watchdog_usec_env) {
return atoi(watchdog_usec_env) / 2;
}
return 0;
}

MainloopSignalHandlers::MainloopSignalHandlers(Mainloop* mainloop)
{
if (mainloop_instance) {
Expand Down
1 change: 1 addition & 0 deletions src/mavlink-router/mainloop.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class Mainloop {
bool _log_aggregate_timeout(void *data);
void _init_pipe();
void _handle_pipe();
static int _watchdogIntervalUs();

static Mainloop* instance;
};
Expand Down

0 comments on commit f6124f8

Please sign in to comment.