diff vd_watchdog/vd_watchdog.c @ 1:0b9854adb86c

Remove tedious messages and daemonize vd_watchdog.
author Thinker K.F. Li <thinker@branda.to>
date Tue, 08 Jul 2008 11:07:31 +0800
parents 71475f5afa92
children 89e9d591748d
line wrap: on
line diff
--- a/vd_watchdog/vd_watchdog.c	Tue Jul 08 09:57:54 2008 +0800
+++ b/vd_watchdog/vd_watchdog.c	Tue Jul 08 11:07:31 2008 +0800
@@ -3,13 +3,16 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include "vordog.h"
 
 #define DEVNAME "/dev/vordog0"
 #define PROG "vd_watchdog"
 
+static int unit_factors[] = {0, 1, 60, 3600};
+
 static void
-watchdog(int min) {
+watchdog(int timeout, int unit) {
     struct vordog_cfg cfg;
     int intval;
     int r;
@@ -20,15 +23,17 @@
 	perror(PROG);
 	exit(1);
     }
-    cfg.init_val = min;
-    cfg.unit = VDT_1M;
+
+    cfg.init_val = timeout;
+    cfg.unit = unit;
     r = ioctl(fd, VDCTL_ENABLE, &cfg);
     if(r == -1) {
 	perror(PROG);
 	exit(1);
     }
-    
-    intval = min * 60 * 3 / 4;
+
+    /* reset timer periodically */
+    intval = timeout * unit_factors[unit];
     while(1) {
 	sleep(intval);
 	r = ioctl(fd, VDCTL_RESET);
@@ -36,13 +41,100 @@
 	    perror(PROG);
 	    exit(1);
 	}
-	printf("reset\n");
+    }
+}
+
+static void
+daemonize(void) {
+    pid_t pid;
+
+    pid = fork();
+    if(pid == -1) {
+	perror("fork");
+	exit(1);
     }
+
+    if(pid != 0)
+	exit(0);		/* parent */
+
+    /* child process */
+    pid = setsid();
+    if(pid == -1) {
+	perror("setsid");
+	exit(1);
+    }
+
+    close(STDOUT_FILENO);
+    close(STDOUT_FILENO);
+    /* close(STDERR_FILENO); */
+}
+
+static void
+usage(const char *prog) {
+    fprintf(stderr, "Usage: %s [-msMH] <timeout>\n");
+    fprintf(stderr, "\t-s\tcount in seconds.\n");
+    fprintf(stderr, "\t-M\tcount in minutes.\n");
+    fprintf(stderr, "\t-m\tcount in hours.\n");
+    fprintf(stderr,
+	    "\t<timeout> is interval between periodically reset of\n"
+	    "\t\twatchdog timer, or the system would be reseted without\n"
+	    "\t\treseting timer for 4 times. (default: 30s)\n"
+	    "\t\t(note: 1~255)\n");
 }
 
 
+static char *unit_names[] = {
+    "* 4ms",
+    "seconds",
+    "minutes",
+    "hours"
+};
+
 int
-main(int argc, const char *argv[]) {
-    watchdog(1);
+main(int argc, char * const argv[]) {
+    int timeout, unit;
+    int ch;
+    const char *prog = argv[0];
+    
+    timeout = 30;		/* default: 30s */
+    unit = VDT_1S;
+    
+    while((ch = getopt(argc, argv, "")) != -1) {
+	switch(ch) {
+	case 's':
+	    unit = VDT_1S;
+	    break;
+	case 'M':
+	    unit = VDT_1M;
+	    break;
+	case 'H':
+	    unit = VDT_1H;
+	    break;
+	case '?':
+	default:
+	    usage(prog);
+	    exit(1);
+	}
+    }
+    argc -= optind;
+    argv += optind;
+
+    if(argc != 1 && argc != 0) {
+	usage(prog);
+	return 1;
+    }
+
+    if(argc == 1)
+	timeout = atoi(argv[0]);
+    if(timeout < 1 || timeout > 255) {
+	usage(prog);
+	return 1;
+    }
+    
+    printf("Reset watchdog timer every %d %s\n",
+	   timeout, unit_names[unit]);
+
+    daemonize();
+    watchdog(timeout, unit);
     return 0;
 }