view 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 source

#include <stdio.h>
#include <stdlib.h>
#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 timeout, int unit) {
    struct vordog_cfg cfg;
    int intval;
    int r;
    int fd;

    fd = open(DEVNAME, O_RDWR);
    if(fd == -1) {
	perror(PROG);
	exit(1);
    }

    cfg.init_val = timeout;
    cfg.unit = unit;
    r = ioctl(fd, VDCTL_ENABLE, &cfg);
    if(r == -1) {
	perror(PROG);
	exit(1);
    }

    /* reset timer periodically */
    intval = timeout * unit_factors[unit];
    while(1) {
	sleep(intval);
	r = ioctl(fd, VDCTL_RESET);
	if(r == -1) {
	    perror(PROG);
	    exit(1);
	}
    }
}

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, 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;
}