diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f4be265..b9e9b5b9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 @@ -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 diff --git a/README.md b/README.md index 60bd404b..74b64c08 100644 --- a/README.md +++ b/README.md @@ -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 #### diff --git a/configure.ac b/configure.ac index 2f0b71e0..843f6d4a 100644 --- a/configure.ac +++ b/configure.ac @@ -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- ##################################################################### diff --git a/debian/control b/debian/control index 4c45ec8f..f1d15442 100644 --- a/debian/control +++ b/debian/control @@ -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 diff --git a/mavlink-router.service.in b/mavlink-router.service.in index bb11b6e3..4a90153f 100644 --- a/mavlink-router.service.in +++ b/mavlink-router.service.in @@ -6,6 +6,7 @@ Type=simple ExecStart=@bindir@/mavlink-routerd Restart=always Nice=-20 +WatchdogSec=5s [Install] WantedBy=multi-user.target diff --git a/src/mavlink-router/mainloop.cpp b/src/mavlink-router/mainloop.cpp index 642a8fad..6f37f249 100644 --- a/src/mavlink-router/mainloop.cpp +++ b/src/mavlink-router/mainloop.cpp @@ -17,6 +17,7 @@ */ #include "mainloop.h" +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include @@ -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; @@ -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(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 @@ -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(deadline - now).count()); + + // Watchdog update + if (watchdog_interval_us > 0) { + if (std::chrono::duration_cast(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(); @@ -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) { diff --git a/src/mavlink-router/mainloop.h b/src/mavlink-router/mainloop.h index 2359f375..b24e9f4b 100644 --- a/src/mavlink-router/mainloop.h +++ b/src/mavlink-router/mainloop.h @@ -151,6 +151,7 @@ class Mainloop { bool _log_aggregate_timeout(void *data); void _init_pipe(); void _handle_pipe(); + static int _watchdogIntervalUs(); static Mainloop* instance; };