Ejemplo n.º 1
0
static int
pow2ns_to_ticks(int pow2ns)
{
	struct timeval tv;
	struct timespec ts;

	pow2ns_to_ts(pow2ns, &ts);
	TIMESPEC_TO_TIMEVAL(&tv, &ts);
	return (tvtohz(&tv));
}
Ejemplo n.º 2
0
/*
 * Called to manage timeouts.
 * newtimeout needs to be in the range of 0 to actual watchdog timeout.
 * if 0, we disable the pre-timeout.
 * otherwise we set the pre-timeout provided it's not greater than the
 * current actual watchdog timeout.
 */
static int
wd_set_pretimeout(int newtimeout, int disableiftoolong)
{
	u_int utime;
	struct timespec utime_ts;
	int timeout_ticks;

	utime = wdog_kern_last_timeout();
	pow2ns_to_ts(utime, &utime_ts);
	/* do not permit a pre-timeout >= than the timeout. */
	if (newtimeout >= utime_ts.tv_sec) {
		/*
		 * If 'disableiftoolong' then just fall through
		 * so as to disable the pre-watchdog
		 */
		if (disableiftoolong)
			newtimeout = 0;
		else
			return EINVAL;
	}

	/* disable the pre-timeout */
	if (newtimeout == 0) {
		wd_pretimeout = 0;
		callout_stop(&wd_pretimeo_handle);
		return 0;
	}

	timeout_ticks = pow2ns_to_ticks(utime) - (hz*newtimeout);
#if 0
	printf("wd_set_pretimeout: "
	    "newtimeout: %d, "
	    "utime: %d -> utime_ticks: %d, "
	    "hz*newtimeout: %d, "
	    "timeout_ticks: %d -> sec: %d\n",
	    newtimeout,
	    utime, pow2ns_to_ticks(utime),
	    hz*newtimeout,
	    timeout_ticks, timeout_ticks / hz);
#endif

	/* We determined the value is sane, so reset the callout */
	(void) callout_reset(&wd_pretimeo_handle,
	    timeout_ticks,
	    wd_timeout_cb, "pre-timeout");
	wd_pretimeout = newtimeout;
	return 0;
}
Ejemplo n.º 3
0
/*
 * Convert a timeout in seconds to N where 2^N nanoseconds is close to
 * "seconds".
 *
 * The kernel expects the timeouts for watchdogs in "2^N nanosecond format".
 */
static u_int
parse_timeout_to_pow2ns(char opt, const char *longopt, const char *myoptarg)
{
	double a;
	u_int rv;
	struct timespec ts;
	struct timeval tv;
	int ticks;
	char shortopt[] = "- ";

	if (!longopt)
		shortopt[1] = opt;

	a = fetchtimeout(opt, longopt, myoptarg, 1);

	if (a == 0)
		rv = WD_TO_NEVER;
	else
		rv = seconds_to_pow2ns(a);
	pow2ns_to_ts(rv, &ts);
	tstotv(&tv, &ts);
	ticks = tvtohz(&tv);
	if (debugging) {
		printf("Timeout for %s%s "
		    "is 2^%d nanoseconds "
		    "(in: %s sec -> out: %jd sec %ld ns -> %d ticks)\n",
		    longopt ? "-" : "", longopt ? longopt : shortopt,
		    rv,
		    myoptarg, (intmax_t)ts.tv_sec, ts.tv_nsec, ticks);
	}
	if (ticks <= 0) {
		errx(1, "Timeout for %s%s is too small, please choose a higher timeout.", longopt ? "-" : "", longopt ? longopt : shortopt);
	}

	return (rv);
}
Ejemplo n.º 4
0
/*
 * Handle the few command line arguments supported.
 */
static void
parseargs(int argc, char *argv[])
{
	struct timespec ts;
	int longindex;
	int c;
	const char *lopt;

	/* Get the default value of timeout_sec from the default timeout. */
	pow2ns_to_ts(timeout, &ts);
	timeout_sec = ts.tv_sec;

	/*
	 * if we end with a 'd' aka 'watchdogd' then we are the daemon program,
	 * otherwise run as a command line utility.
	 */
	c = strlen(argv[0]);
	if (argv[0][c - 1] == 'd')
		is_daemon = 1;

	if (is_daemon)
		getopt_shortopts = "I:de:ns:t:ST:wx:?";
	else
		getopt_shortopts = "dt:?";

	while ((c = getopt_long(argc, argv, getopt_shortopts, longopts,
		    &longindex)) != -1) {
		switch (c) {
		case 'I':
			pidfile = optarg;
			break;
		case 'd':
			debugging = 1;
			break;
		case 'e':
			test_cmd = strdup(optarg);
			break;
		case 'n':
			is_dry_run = 1;
			break;
#ifdef notyet
		case 'p':
			passive = 1;
			break;
#endif
		case 's':
			nap = fetchtimeout(c, NULL, optarg, 0);
			break;
		case 'S':
			do_syslog = 0;
			break;
		case 't':
			timeout_sec = atoi(optarg);
			timeout = parse_timeout_to_pow2ns(c, NULL, optarg);
			if (debugging)
				printf("Timeout is 2^%d nanoseconds\n",
				    timeout);
			break;
		case 'T':
			carp_thresh_seconds =
			    fetchtimeout(c, "NULL", optarg, 0);
			break;
		case 'w':
			do_timedog = 1;
			break;
		case 'x':
			exit_timeout = parse_timeout_to_pow2ns(c, NULL, optarg);
			if (exit_timeout != 0)
				exit_timeout |= WD_ACTIVE;
			break;
		case 0:
			lopt = longopts[longindex].name;
			if (!strcmp(lopt, "pretimeout")) {
				pretimeout = fetchtimeout(0, lopt, optarg, 0);
			} else if (!strcmp(lopt, "pretimeout-action")) {
				pretimeout_act = timeout_act_str2int(lopt,
				    optarg);
			} else if (!strcmp(lopt, "softtimeout-action")) {
				softtimeout_act = timeout_act_str2int(lopt,
				    optarg);
			} else {
		/*		warnx("bad option at index %d: %s", optind,
				    argv[optind]);
				usage();
				*/
			}
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (nap > timeout_sec / 2)
		nap = timeout_sec / 2;

	if (carp_thresh_seconds == -1)
		carp_thresh_seconds = nap;

	if (argc != optind)
		errx(EX_USAGE, "extra arguments.");
	if (is_daemon && timeout < WD_TO_1SEC)
		errx(EX_USAGE, "-t argument is less than one second.");
	if (pretimeout_set) {
		if (pretimeout >= timeout_sec) {
			errx(EX_USAGE,
			    "pretimeout (%d) >= timeout (%d -> %ld)\n"
			    "see manual section TIMEOUT RESOLUTION",
			    pretimeout, timeout_sec, (long)ts.tv_sec);
		}
	}
}