3 * Copyright (C) 2012-2014 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * Lassi Marttala <lassi.lm.marttala@partner.bmw.de>
17 * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 * Markus Klein <Markus.Klein@esk.fraunhofer.de>
19 * Mikko Rapeli <mikko.rapeli@bmw.de>
21 * \file dlt-system-logfile.c
22 * For further information see http://www.genivi.org/.
26 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
30 #include <sys/timerfd.h>
32 #include "dlt-system.h"
34 #include "sd-daemon.h"
37 DLT_DECLARE_CONTEXT(watchdogContext)
38 DLT_IMPORT_CONTEXT(dltsystem)
40 extern DltSystemThreads threads;
45 unsigned long long wakeups_missed;
48 void wait_period (PeriodicData *info)
50 unsigned long long missed;
52 if(read (info->timer_fd, &missed, sizeof (missed)) < 0)
54 DLT_LOG(watchdogContext, DLT_LOG_ERROR,
55 DLT_STRING("Could not read from timer file descriptor in watchdog.\n"));
60 info->wakeups_missed += (missed - 1);
64 int make_periodic(unsigned int period, PeriodicData *info)
69 struct itimerspec itval;
73 DLT_LOG(watchdogContext, DLT_LOG_ERROR,
74 DLT_STRING("Invalid function parameters used for function make_periodic.\n"));
78 /* Create the timer */
79 fd = timerfd_create (CLOCK_MONOTONIC, 0);
81 info->wakeups_missed = 0;
86 DLT_LOG(watchdogContext, DLT_LOG_ERROR,
87 DLT_STRING("Can't create timer filedescriptor.\n"));
91 /* Make the timer periodic */
93 ns = (period - (sec * 1000000)) * 1000;
94 itval.it_interval.tv_sec = sec;
95 itval.it_interval.tv_nsec = ns;
96 itval.it_value.tv_sec = sec;
97 itval.it_value.tv_nsec = ns;
99 return timerfd_settime (fd, 0, &itval, NULL);
103 void watchdog_thread(void *v_conf)
107 unsigned int watchdogTimeoutSeconds;
108 unsigned int notifiyPeriodNSec;
111 DLT_REGISTER_CONTEXT(watchdogContext, "DOG","dlt system watchdog context.");
115 DLT_LOG(watchdogContext, DLT_LOG_INFO,DLT_STRING("Watchdog thread started.\n"));
119 DLT_LOG(watchdogContext, DLT_LOG_ERROR,
120 DLT_STRING("Invalid function parameters used for function watchdog_thread.\n"));
125 watchdogUSec = getenv("WATCHDOG_USEC");
129 DLT_LOG(watchdogContext, DLT_LOG_DEBUG,DLT_STRING("watchdogusec: "),DLT_STRING(watchdogUSec));
131 watchdogTimeoutSeconds = atoi(watchdogUSec);
133 if( watchdogTimeoutSeconds > 0 ){
135 // Calculate half of WATCHDOG_USEC in ns for timer tick
136 notifiyPeriodNSec = watchdogTimeoutSeconds / 2 ;
138 sprintf(str,"systemd watchdog timeout: %u nsec - timer will be initialized: %u nsec\n", watchdogTimeoutSeconds, notifiyPeriodNSec );
139 DLT_LOG(watchdogContext, DLT_LOG_DEBUG,DLT_STRING(str));
141 if (make_periodic (notifiyPeriodNSec, &info) < 0 )
143 DLT_LOG(watchdogContext, DLT_LOG_ERROR,DLT_STRING("Could not initialize systemd watchdog timer\n"));
149 if(sd_notify(0, "WATCHDOG=1") < 0)
151 DLT_LOG(watchdogContext, DLT_LOG_ERROR,DLT_STRING("Could not reset systemd watchdog\n"));
154 DLT_LOG(watchdogContext, DLT_LOG_DEBUG,DLT_STRING("systemd watchdog waited periodic\n"));
156 /* Wait for next period */
162 sprintf(str,"systemd watchdog timeout incorrect: %u\n", watchdogTimeoutSeconds);
163 DLT_LOG(watchdogContext, DLT_LOG_DEBUG,DLT_STRING(str));
168 DLT_LOG(watchdogContext, DLT_LOG_ERROR,DLT_STRING("systemd watchdog timeout (WATCHDOG_USEC) is null\n"));
173 void start_systemd_watchdog(DltSystemConfiguration *conf)
175 DLT_LOG(dltsystem, DLT_LOG_DEBUG,DLT_STRING("Creating thread for systemd watchdog\n"));
177 static pthread_attr_t t_attr;
180 if (pthread_create(&pt, &t_attr, (void *)watchdog_thread, conf) == 0)
182 threads.threads[threads.count++] = pt;
186 DLT_LOG(dltsystem, DLT_LOG_ERROR,DLT_STRING("Could not create thread for systemd watchdog\n"));