mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented watchdog
This commit is contained in:
parent
a97fcd5221
commit
5e0ee042c7
4
HISTORY
4
HISTORY
@ -409,3 +409,7 @@ Video Disk Recorder Revision History
|
|||||||
that every timer may use the primary interface.
|
that every timer may use the primary interface.
|
||||||
- The 'active' field of a timer will now be explicitly set to '1' if the user
|
- The 'active' field of a timer will now be explicitly set to '1' if the user
|
||||||
modifies an active timer (see FORMATS for details).
|
modifies an active timer (see FORMATS for details).
|
||||||
|
- The new command line option -w can be used to activate a watchdog that makes
|
||||||
|
VDR exit in case the main program loop does not respond for more than the
|
||||||
|
given number of seconds. This is mainly useful in combination with the new
|
||||||
|
'runvdr' script that restarts VDR in case is has exited.
|
||||||
|
9
INSTALL
9
INSTALL
@ -15,7 +15,7 @@ If you have the DVB driver source in a different location
|
|||||||
you will have to change the definition of DVBDIR in the
|
you will have to change the definition of DVBDIR in the
|
||||||
Makefile.
|
Makefile.
|
||||||
|
|
||||||
This program requires the card driver version 0.8.1 or higher
|
This program requires the card driver version 0.8.2 or higher
|
||||||
to work properly. You need to load the dvb.o module *without* option
|
to work properly. You need to load the dvb.o module *without* option
|
||||||
'outstream=0' (previous versions of VDR required this option to have
|
'outstream=0' (previous versions of VDR required this option to have
|
||||||
the driver supply the data in AV_PES format; as of version 0.70 VDR
|
the driver supply the data in AV_PES format; as of version 0.70 VDR
|
||||||
@ -71,6 +71,13 @@ If the program shall run as a daemon, use the --daemon option. This
|
|||||||
will completely detach it from the terminal and will continue as a
|
will completely detach it from the terminal and will continue as a
|
||||||
background process.
|
background process.
|
||||||
|
|
||||||
|
Automatic restart in case of hangups:
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
If you run VDR using the 'runvdr' shell script it will use the built-in
|
||||||
|
watchdog timer to restart the program in case something happens that
|
||||||
|
causes a program hangup.
|
||||||
|
|
||||||
Command line options:
|
Command line options:
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
13
runvdr
Executable file
13
runvdr
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
DVBDIR='../DVB/driver'
|
||||||
|
VDRCMD='./vdr -w 60'
|
||||||
|
|
||||||
|
while test 1; do
|
||||||
|
# (cd $DVBDIR; make reload)
|
||||||
|
# sleep 3
|
||||||
|
if $VDRCMD; then exit; fi
|
||||||
|
date
|
||||||
|
echo "restarting VDR"
|
||||||
|
sleep 10
|
||||||
|
done
|
88
vdr.c
88
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 1.53 2001/02/11 14:51:44 kls Exp $
|
* $Id: vdr.c 1.54 2001/02/24 16:18:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -55,30 +55,41 @@ static void SignalHandler(int signum)
|
|||||||
signal(signum, SignalHandler);
|
signal(signum, SignalHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Watchdog(int signum)
|
||||||
|
{
|
||||||
|
// Something terrible must have happened that prevented the 'alarm()' from
|
||||||
|
// being called in time, so let's get out of here:
|
||||||
|
esyslog(LOG_ERR, "PANIC: watchdog timer expired - exiting!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Command line options:
|
// Command line options:
|
||||||
|
|
||||||
#define DEFAULTSVDRPPORT 2001
|
#define DEFAULTSVDRPPORT 2001
|
||||||
|
#define DEFAULTWATCHDOG 0 // seconds
|
||||||
|
|
||||||
int SVDRPport = DEFAULTSVDRPPORT;
|
int SVDRPport = DEFAULTSVDRPPORT;
|
||||||
const char *ConfigDirectory = NULL;
|
const char *ConfigDirectory = NULL;
|
||||||
bool DaemonMode = false;
|
bool DaemonMode = false;
|
||||||
|
int WatchdogTimeout = DEFAULTWATCHDOG;
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{ "config", required_argument, NULL, 'c' },
|
{ "config", required_argument, NULL, 'c' },
|
||||||
{ "daemon", no_argument, NULL, 'd' },
|
{ "daemon", no_argument, NULL, 'd' },
|
||||||
{ "device", required_argument, NULL, 'D' },
|
{ "device", required_argument, NULL, 'D' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "log", required_argument, NULL, 'l' },
|
{ "log", required_argument, NULL, 'l' },
|
||||||
{ "port", required_argument, NULL, 'p' },
|
{ "port", required_argument, NULL, 'p' },
|
||||||
{ "video", required_argument, NULL, 'v' },
|
{ "video", required_argument, NULL, 'v' },
|
||||||
|
{ "watchdog", required_argument, NULL, 'w' },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int c;
|
int c;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
while ((c = getopt_long(argc, argv, "c:dD:hl:p:v:", long_options, &option_index)) != -1) {
|
while ((c = getopt_long(argc, argv, "c:dD:hl:p:v:w:", long_options, &option_index)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c': ConfigDirectory = optarg;
|
case 'c': ConfigDirectory = optarg;
|
||||||
break;
|
break;
|
||||||
@ -94,23 +105,26 @@ int main(int argc, char *argv[])
|
|||||||
abort();
|
abort();
|
||||||
break;
|
break;
|
||||||
case 'h': printf("Usage: vdr [OPTION]\n\n" // for easier orientation, this is column 80|
|
case 'h': printf("Usage: vdr [OPTION]\n\n" // for easier orientation, this is column 80|
|
||||||
" -c DIR, --config=DIR read config files from DIR (default is to read them\n"
|
" -c DIR, --config=DIR read config files from DIR (default is to read them\n"
|
||||||
" from the video directory)\n"
|
" from the video directory)\n"
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -d, --daemon run in daemon mode\n"
|
" -d, --daemon run in daemon mode\n"
|
||||||
" -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
|
" -D NUM, --device=NUM use only the given DVB device (NUM = 0, 1, 2...)\n"
|
||||||
" there may be several -D options (default: all DVB\n"
|
" there may be several -D options (default: all DVB\n"
|
||||||
" devices will be used)\n"
|
" devices will be used)\n"
|
||||||
" -l LEVEL, --log=LEVEL set log level (default: 3)\n"
|
" -l LEVEL, --log=LEVEL set log level (default: 3)\n"
|
||||||
" 0 = no logging, 1 = errors only,\n"
|
" 0 = no logging, 1 = errors only,\n"
|
||||||
" 2 = errors and info, 3 = errors, info and debug\n"
|
" 2 = errors and info, 3 = errors, info and debug\n"
|
||||||
" -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n"
|
" -p PORT, --port=PORT use PORT for SVDRP (default: %d)\n"
|
||||||
" 0 turns off SVDRP\n"
|
" 0 turns off SVDRP\n"
|
||||||
" -v DIR, --video=DIR use DIR as video directory (default is %s)\n"
|
" -v DIR, --video=DIR use DIR as video directory (default is %s)\n"
|
||||||
|
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
|
||||||
|
" seconds (default: %d); '0' disables the watchdog\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Report bugs to <vdr-bugs@cadsoft.de>\n",
|
"Report bugs to <vdr-bugs@cadsoft.de>\n",
|
||||||
DEFAULTSVDRPPORT,
|
DEFAULTSVDRPPORT,
|
||||||
VideoDirectory
|
VideoDirectory,
|
||||||
|
DEFAULTWATCHDOG
|
||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
@ -135,6 +149,16 @@ int main(int argc, char *argv[])
|
|||||||
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
||||||
optarg[strlen(optarg) - 1] = 0;
|
optarg[strlen(optarg) - 1] = 0;
|
||||||
break;
|
break;
|
||||||
|
case 'w': if (isnumber(optarg)) {
|
||||||
|
int t = atoi(optarg);
|
||||||
|
if (t >= 0) {
|
||||||
|
WatchdogTimeout = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "vdr: invalid watchdog timeout: %s\n", optarg);
|
||||||
|
abort();
|
||||||
|
break;
|
||||||
default: abort();
|
default: abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +237,8 @@ int main(int argc, char *argv[])
|
|||||||
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
|
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
|
||||||
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
|
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
|
||||||
if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
|
if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
|
||||||
|
if (WatchdogTimeout > 0)
|
||||||
|
if (signal(SIGALRM, Watchdog) == SIG_IGN) signal(SIGALRM, SIG_IGN);
|
||||||
|
|
||||||
// Main program loop:
|
// Main program loop:
|
||||||
|
|
||||||
@ -221,8 +247,22 @@ int main(int argc, char *argv[])
|
|||||||
int LastChannel = -1;
|
int LastChannel = -1;
|
||||||
int PreviousChannel = cDvbApi::CurrentChannel();
|
int PreviousChannel = cDvbApi::CurrentChannel();
|
||||||
time_t LastActivity = time(NULL);
|
time_t LastActivity = time(NULL);
|
||||||
|
int MaxLatencyTime = 0;
|
||||||
|
|
||||||
|
if (WatchdogTimeout > 0) {
|
||||||
|
dsyslog(LOG_INFO, "setting watchdog timer to %d seconds", WatchdogTimeout);
|
||||||
|
alarm(WatchdogTimeout); // Initial watchdog timer start
|
||||||
|
}
|
||||||
|
|
||||||
while (!Interrupted) {
|
while (!Interrupted) {
|
||||||
|
// Restart the Watchdog timer:
|
||||||
|
if (WatchdogTimeout > 0) {
|
||||||
|
int LatencyTime = WatchdogTimeout - alarm(WatchdogTimeout);
|
||||||
|
if (LatencyTime > MaxLatencyTime) {
|
||||||
|
MaxLatencyTime = LatencyTime;
|
||||||
|
dsyslog(LOG_INFO, "max. latency time %d seconds", MaxLatencyTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Channel display:
|
// Channel display:
|
||||||
if (!EITScanner.Active() && cDvbApi::CurrentChannel() != LastChannel) {
|
if (!EITScanner.Active() && cDvbApi::CurrentChannel() != LastChannel) {
|
||||||
if (!Menu)
|
if (!Menu)
|
||||||
@ -344,6 +384,8 @@ int main(int argc, char *argv[])
|
|||||||
delete ReplayControl;
|
delete ReplayControl;
|
||||||
delete Interface;
|
delete Interface;
|
||||||
cDvbApi::Cleanup();
|
cDvbApi::Cleanup();
|
||||||
|
if (WatchdogTimeout > 0)
|
||||||
|
dsyslog(LOG_INFO, "max. latency time %d seconds", MaxLatencyTime);
|
||||||
isyslog(LOG_INFO, "exiting");
|
isyslog(LOG_INFO, "exiting");
|
||||||
if (SysLogLevel > 0)
|
if (SysLogLevel > 0)
|
||||||
closelog();
|
closelog();
|
||||||
|
Loading…
Reference in New Issue
Block a user