summaryrefslogtreecommitdiff
path: root/src/system/dlt-system-watchdog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/system/dlt-system-watchdog.c')
-rw-r--r--src/system/dlt-system-watchdog.c166
1 files changed, 63 insertions, 103 deletions
diff --git a/src/system/dlt-system-watchdog.c b/src/system/dlt-system-watchdog.c
index fd6bcac..a2b01de 100644
--- a/src/system/dlt-system-watchdog.c
+++ b/src/system/dlt-system-watchdog.c
@@ -29,135 +29,95 @@
#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
#include <stdio.h>
#include <stdlib.h>
-#include <pthread.h>
+#include <string.h>
#include <sys/timerfd.h>
#include "dlt.h"
#include "dlt-system.h"
-
-#include "sd-daemon.h"
-
+#include <poll.h>
+#include <systemd/sd-daemon.h>
DLT_DECLARE_CONTEXT(watchdogContext)
DLT_IMPORT_CONTEXT(dltsystem)
-extern DltSystemThreads threads;
-
-typedef struct
-{
- int timer_fd;
- unsigned long long wakeups_missed;
-} PeriodicData;
-
-void wait_period (PeriodicData *info)
-{
- unsigned long long missed;
-
- if (read (info->timer_fd, &missed, sizeof (missed)) < 0)
- DLT_LOG(watchdogContext, DLT_LOG_ERROR,
- DLT_STRING("Could not read from timer file descriptor in watchdog.\n"));
-
- if (missed > 0)
- info->wakeups_missed += (missed - 1);
-}
-
-int make_periodic(unsigned int period, PeriodicData *info)
+int calculate_period(struct itimerspec *itval)
{
unsigned int ns;
unsigned int sec;
- int fd;
- struct itimerspec itval;
+ char str[512];
+ char *watchdogUSec;
+ unsigned int watchdogTimeoutSeconds;
+ unsigned int notifiyPeriodNSec;
+
+ watchdogUSec = getenv("WATCHDOG_USEC");
- if (info == 0) {
- DLT_LOG(watchdogContext, DLT_LOG_ERROR,
- DLT_STRING("Invalid function parameters used for function make_periodic.\n"));
+ if (watchdogUSec == NULL) {
+ DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("systemd watchdog timeout (WATCHDOG_USEC) is null\n"));
return -1;
}
+
+ DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("watchdogusec: "), DLT_STRING(watchdogUSec));
+ watchdogTimeoutSeconds = atoi(watchdogUSec);
- /* Create the timer */
- fd = timerfd_create (CLOCK_MONOTONIC, 0);
-
- info->wakeups_missed = 0;
- info->timer_fd = fd;
-
- if (fd == -1) {
- DLT_LOG(watchdogContext, DLT_LOG_ERROR,
- DLT_STRING("Can't create timer filedescriptor.\n"));
+ if (watchdogTimeoutSeconds <= 0) {
+ snprintf(str, 512, "systemd watchdog timeout incorrect: %u\n", watchdogTimeoutSeconds);
+ DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING(str));
return -1;
}
+ /* Calculate half of WATCHDOG_USEC in ns for timer tick */
+ notifiyPeriodNSec = watchdogTimeoutSeconds / 2;
+
+ snprintf(str,
+ 512,
+ "systemd watchdog timeout: %u nsec - timer will be initialized: %u nsec\n",
+ watchdogTimeoutSeconds,
+ notifiyPeriodNSec);
+ DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING(str));
+
/* Make the timer periodic */
- sec = period / 1000000;
- ns = (period - (sec * 1000000)) * 1000;
- itval.it_interval.tv_sec = sec;
- itval.it_interval.tv_nsec = ns;
- itval.it_value.tv_sec = sec;
- itval.it_value.tv_nsec = ns;
-
- return timerfd_settime (fd, 0, &itval, NULL);
+ sec = notifiyPeriodNSec / 1000000;
+ ns = (notifiyPeriodNSec - (sec * 1000000)) * 1000;
+ itval->it_interval.tv_sec = sec;
+ itval->it_interval.tv_nsec = ns;
+ itval->it_value.tv_sec = sec;
+ itval->it_value.tv_nsec = ns;
+
+ return 0;
}
-
-void watchdog_thread(void *v_conf)
+int register_watchdog_fd(struct pollfd *pollfd, int fdcnt)
{
- char str[512];
- char *watchdogUSec;
- unsigned int watchdogTimeoutSeconds;
- unsigned int notifiyPeriodNSec;
- PeriodicData info;
-
DLT_REGISTER_CONTEXT(watchdogContext, "DOG", "dlt system watchdog context.");
+ struct itimerspec timerValue;
+ if (calculate_period(&timerValue) != 0)
+ return -1;
- sleep(1);
-
- DLT_LOG(watchdogContext, DLT_LOG_INFO, DLT_STRING("Watchdog thread started.\n"));
-
- if (v_conf == 0) {
- DLT_LOG(watchdogContext, DLT_LOG_ERROR,
- DLT_STRING("Invalid function parameters used for function watchdog_thread.\n"));
- return;
+ int timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
+ if (timerfd < 0) {
+ DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Failed to create timer fd\n"));
+ return -1;
}
+ pollfd[fdcnt].fd = timerfd;
+ pollfd[fdcnt].events = POLLIN;
- watchdogUSec = getenv("WATCHDOG_USEC");
-
- if (watchdogUSec) {
- DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("watchdogusec: "), DLT_STRING(watchdogUSec));
-
- watchdogTimeoutSeconds = atoi(watchdogUSec);
-
- if (watchdogTimeoutSeconds > 0) {
-
- /* Calculate half of WATCHDOG_USEC in ns for timer tick */
- notifiyPeriodNSec = watchdogTimeoutSeconds / 2;
-
- snprintf(str,
- 512,
- "systemd watchdog timeout: %u nsec - timer will be initialized: %u nsec\n",
- watchdogTimeoutSeconds,
- notifiyPeriodNSec);
- DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING(str));
-
- if (make_periodic (notifiyPeriodNSec, &info) < 0) {
- DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not initialize systemd watchdog timer\n"));
- return;
- }
+ if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
+ DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not start timer\n"));
+ return -1;
+ }
+ return 0;
+}
- while (1) {
- if (sd_notify(0, "WATCHDOG=1") < 0)
- DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not reset systemd watchdog\n"));
+void watchdog_fd_handler(int fd)
+{
+ long int timersElapsed = 0;
+ int r = read(fd, &timersElapsed, 8); // only needed to reset fd event
+ if(r < 0)
+ DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not reset systemd watchdog. Exit with: "),
+ DLT_STRING(strerror(r)));
- DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("systemd watchdog waited periodic\n"));
+ if (sd_notify(0, "WATCHDOG=1") < 0)
+ DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("Could not reset systemd watchdog\n"));
- /* Wait for next period */
- wait_period(&info);
- }
- }
- else {
- snprintf(str, 512, "systemd watchdog timeout incorrect: %u\n", watchdogTimeoutSeconds);
- DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING(str));
- }
- }
- else {
- DLT_LOG(watchdogContext, DLT_LOG_ERROR, DLT_STRING("systemd watchdog timeout (WATCHDOG_USEC) is null\n"));
- }
+ DLT_LOG(watchdogContext, DLT_LOG_DEBUG, DLT_STRING("systemd watchdog waited periodic\n"));
}
-#endif
+#endif \ No newline at end of file