view vd_watchdog/vd_watchdog.c @ 7:5a281ce7453c

Add comments
author Thinker K.F. Li <thinker@branda.to>
date Tue, 08 Jul 2008 16:06:24 +0800
parents 5fa5e5199d1a
children
line wrap: on
line source

/*-
 * Copyright (c) 2008 Kueifong Li <thinker@branda.to>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <libgen.h>
#include "vordog.h"

#define DEVNAME "/dev/vordog0"
#define PROG prog

static int unit_factors[] = {0, 1, 60, 3600};
static const char *prog = NULL;

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", prog);
    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;

    prog = basename(argv[0]);	/* name of binary file. */
    prog = strdup(prog);
    
    timeout = 30;		/* default: 30s */
    unit = VDT_1S;
    
    while((ch = getopt(argc, argv, "")) != -1) {
	switch(ch) {
	    /* 4ms unit is not used for too short to sleep. */
	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);

    free((void *)prog);
    return 0;
}