diff options
Diffstat (limited to 'src/system/dlt-system-watchdog.c')
-rw-r--r-- | src/system/dlt-system-watchdog.c | 166 |
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 |