From f211c63925ea6d03cc1036b5e11061ec82d92ef8 Mon Sep 17 00:00:00 2001 From: Christian Muck Date: Wed, 30 May 2012 15:50:56 +0200 Subject: [GDLT-90] Implemented systemd watchdog concept Signed-off-by: Christian Muck --- src/daemon/CMakeLists.txt | 7 ++- src/daemon/dlt-daemon.c | 135 ++++++++++++++++++++++++++++++++++++++++++---- src/daemon/dlt-daemon.h | 3 ++ 3 files changed, 135 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index b868a0f..08c5767 100755 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -14,8 +14,13 @@ # @licence end@ ######## + +if(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) + message( STATUS "Added ${systemd_SRCS} to dlt-daemon") +endif(WITH_SYSTEMD_WATCHDOG OR WITH_SYSTEMD) + set(dlt_daemon_SRCS dlt-daemon dlt_daemon_common ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c) -add_executable(dlt-daemon ${dlt_daemon_SRCS}) +add_executable(dlt-daemon ${dlt_daemon_SRCS} ${systemd_SRCS}) target_link_libraries(dlt-daemon rt ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS dlt-daemon diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 6aa4a07..5a44f60 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -86,15 +86,14 @@ #include "dlt-daemon.h" #include "dlt-daemon_cfg.h" -/** \page Contents - * The package automotive-dlt includes the following items: - * - dlt daemon (dlt-daemon) - * - adptors to to interface the daemon (dlt-adaptor-stdin, dlt-adaptor-udp) - * - dlt client gui (dlt-viewer) - * - dlt console tools (dlt-receive, dlt-convert) - * - examples (dlt-example-user, dlt-example-user-func, dlt-example-ringbuffer) - * - a library including user-application, client and common functions - */ +#if defined(DLT_SYSTEMD_ENABLE) + #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) + #include + #include + #endif + +#include "sd-daemon.h" +#endif /** \defgroup daemon DLT Daemon @@ -110,6 +109,11 @@ static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data; static pthread_t dlt_daemon_timingpacket_thread_handle; static pthread_attr_t dlt_daemon_timingpacket_thread_attr; +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) +static DltDaemonTimingPacketThreadData dlt_daemon_systemd_watchdog_thread_data; +static pthread_t dlt_daemon_systemd_watchdog_thread_handle; +#endif + /** * Print usage information of tool. */ @@ -505,6 +509,11 @@ int main(int argc, char* argv[]) int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) + int ret; +#endif + + PRINT_FUNCTION_VERBOSE(verbose); if ((daemon==0) || (daemon_local==0)) @@ -513,6 +522,26 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE) + ret = sd_booted(); + + if(ret == 0){ + dlt_log(LOG_CRIT, "system not booted with systemd!\n"); + return -1; + } + else if(ret < 0) + { + dlt_log(LOG_CRIT, "sd_booted failed!\n"); + return -1; + } + else + { + dlt_log(LOG_INFO, "system booted with systemd\n"); + } +#endif + + + /* Check for daemon mode */ if (daemon_local->flags.dflag) { @@ -655,6 +684,24 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr); + + +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) + + dlt_daemon_systemd_watchdog_thread_data.daemon = daemon; + dlt_daemon_systemd_watchdog_thread_data.daemon_local = daemon_local; + + if (pthread_create(&(dlt_daemon_systemd_watchdog_thread_handle), + NULL, + (void *) &dlt_daemon_systemd_watchdog_thread, + (void *) &dlt_daemon_systemd_watchdog_thread_data)!=0) + { + dlt_log(LOG_ERR,"Could not initialize systemd watchdog thread\n"); + return -1; + } +#endif + + return 0; } @@ -2303,6 +2350,76 @@ void dlt_daemon_timingpacket_thread(void *ptr) dlt_daemon_wait_period (&info, daemon_local->flags.vflag); } } +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) +void dlt_daemon_systemd_watchdog_thread(void *ptr) +{ + char *watchdogUSec; + int watchdogTimeoutSeconds; + int notifiyPeriodNSec; + DltDaemonPeriodicData info; + DltDaemonTimingPacketThreadData *data; + DltDaemon *daemon; + DltDaemonLocal *daemon_local; + + if (ptr==0) + { + dlt_log(LOG_ERR, "No data pointer passed to systemd watchdog thread\n"); + return; + } + + data = (DltDaemonTimingPacketThreadData*)ptr; + daemon = data->daemon; + daemon_local = data->daemon_local; + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()"); + return; + } + + watchdogUSec = getenv("WATCHDOG_USEC"); + + if(watchdogUSec) + { + watchdogTimeoutSeconds = atoi(watchdogUSec); + + if( watchdogTimeoutSeconds > 0 ){ + + // Calculate half of WATCHDOG_USEC in ns for timer tick + notifiyPeriodNSec = watchdogTimeoutSeconds / 2 ; + + sprintf(str,"systemd watchdog timeout: %i nsec - timer will be initialized: %i nsec\n", watchdogTimeoutSeconds, notifiyPeriodNSec ); + dlt_log(LOG_INFO, str); + + if (dlt_daemon_make_periodic (notifiyPeriodNSec, &info, daemon_local->flags.vflag)<0) + { + dlt_log(LOG_CRIT, "Could not initialize systemd watchdog timer"); + return; + } + + while (1) + { + if(sd_notify(0, "WATCHDOG=1") < 0) + { + dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n"); + } + //dlt_log(LOG_INFO, "systemd watchdog waited periodic\n"); + /* Wait for next period */ + dlt_daemon_wait_period (&info, daemon_local->flags.vflag); + } + } + else + { + sprintf(str,"systemd watchdog timeout incorrect: %i\n", watchdogTimeoutSeconds); + dlt_log(LOG_CRIT, str); + } + } + else + { + dlt_log(LOG_CRIT, "systemd watchdog timeout (WATCHDOG_USEC) is null!\n"); + } +} +#endif int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose) { diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h index 36ad2ba..40159f4 100755 --- a/src/daemon/dlt-daemon.h +++ b/src/daemon/dlt-daemon.h @@ -166,6 +166,9 @@ int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal * int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose); void dlt_daemon_timingpacket_thread(void *ptr); +#if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) + void dlt_daemon_systemd_watchdog_thread(void *ptr); +#endif int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose); void dlt_daemon_wait_period(DltDaemonPeriodicData *info, int verbose); -- cgit v1.2.1