Re: git: 26d6617f3e54 - main - watchdog: Convert to using sbintime_t format
- In reply to: Mitchell Horne : "Re: git: 26d6617f3e54 - main - watchdog: Convert to using sbintime_t format"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 19 Aug 2025 19:31:55 UTC
On Tue, 19 Aug 2025 16:25:18 -0300
Mitchell Horne <mhorne@freebsd.org> wrote:
> On 8/14/25 16:03, Justin Hibbits wrote:
> > The branch main has been updated by jhibbits:
> >
> > URL:
> > https://cgit.FreeBSD.org/src/commit/?id=26d6617f3e5406d9f92d87674f1667dd856828a3
> >
> > commit 26d6617f3e5406d9f92d87674f1667dd856828a3
> > Author: Justin Hibbits <jhibbits@FreeBSD.org>
> > AuthorDate: 2025-02-26 20:25:36 +0000
> > Commit: Justin Hibbits <jhibbits@FreeBSD.org>
> > CommitDate: 2025-08-14 19:02:46 +0000
> >
> > watchdog: Convert to using sbintime_t format
> >
> > Summary:
> > Some watchdogs are now based on a countdown timer instead of a
> > bit check. To deal with these, convert the watchdog framework to
> > use sbintime_t instead of power-of-2-nanoseconds. This allows more
> > precision, and more variety of watchdog timeouts. Keep the old
> > method as a compatibility layer, so that drivers can be migrated
> > slowly, as needed.
>
> Hi Justin,
>
> The watchdog(4) man page needs to be updated for the new ioctl API.
> Can you please handle this?
>
> There is also the watchdog(9) page, which is of lower quality and
> detail. I would not insist on changes here, but I do note that it is
> affected.
>
> Best,
> Mitchell
Hi Mitchell,
Sure, I'll fix the man page. I have a bad habit of forgetting about
those.
- Justin
>
> >
> > Reviewed by: jhb
> > Sponsored by: Juniper Networks, Inc.
> > Differential Revision: https://reviews.freebsd.org/D49183
> > ---
> > sys/dev/watchdog/watchdog.c | 202
> > ++++++++++++++++++++++------------------- sys/sys/watchdog.h
> > | 17 ++-- usr.sbin/watchdogd/watchdogd.c | 99
> > +++++--------------- 3 files changed, 143 insertions(+), 175
> > deletions(-)
> >
> > diff --git a/sys/dev/watchdog/watchdog.c
> > b/sys/dev/watchdog/watchdog.c index c0babef1b29b..e1b2e08c3f10
> > 100644 --- a/sys/dev/watchdog/watchdog.c
> > +++ b/sys/dev/watchdog/watchdog.c
> > @@ -50,11 +50,20 @@
> >
> > #include <sys/syscallsubr.h> /* kern_clock_gettime() */
> >
> > -static int wd_set_pretimeout(int newtimeout, int disableiftoolong);
> > +#ifdef COMPAT_FREEBSD14
> > +#define WDIOCPATPAT_14 _IOW('W', 42, u_int) /* pat
> > the watchdog */ +#define WDIOC_SETTIMEOUT_14 _IOW('W', 43,
> > int) /* set/reset the timer */ +#define WDIOC_GETTIMEOUT_14
> > _IOR('W', 44, int) /* get total timeout */ +#define
> > WDIOC_GETTIMELEFT_14 _IOR('W', 45, int) /* get time left
> > */ +#define WDIOC_GETPRETIMEOUT_14 _IOR('W', 46, int) /* get
> > the pre-timeout */ +#define WDIOC_SETPRETIMEOUT_14 _IOW('W', 47,
> > int) /* set the pre-timeout */ +#endif +
> > +static int wd_set_pretimeout(sbintime_t newtimeout, int
> > disableiftoolong); static void wd_timeout_cb(void *arg);
> >
> > static struct callout wd_pretimeo_handle;
> > -static int wd_pretimeout;
> > +static sbintime_t wd_pretimeout;
> > static int wd_pretimeout_act = WD_SOFT_LOG;
> >
> > static struct callout wd_softtimeo_handle;
> > @@ -63,6 +72,8 @@ static int wd_softtimer; /* true = use
> > softtimer instead of hardware static int wd_softtimeout_act =
> > WD_SOFT_LOG; /* action for the software timeout */
> > static struct cdev *wd_dev;
> > +static volatile sbintime_t wd_last_sbt; /* last timeout
> > value (sbt) */ +static sbintime_t wd_last_sbt_sysctl; /*
> > last timeout value (sbt) */ static volatile u_int wd_last_u; /*
> > last timeout value set by kern_do_pat */ static u_int
> > wd_last_u_sysctl; /* last timeout value set by kern_do_pat */
> > static u_int wd_last_u_sysctl_secs; /* wd_last_u in seconds */
> > @@ -73,6 +84,8 @@ SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u,
> > CTLFLAG_RD, &wd_last_u_sysctl, 0, "Watchdog last update time");
> > SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u_secs, CTLFLAG_RD,
> > &wd_last_u_sysctl_secs, 0, "Watchdog last update time");
> > +SYSCTL_SBINTIME_MSEC(_hw_watchdog, OID_AUTO, wd_last_msecs,
> > CTLFLAG_RD,
> > + &wd_last_sbt_sysctl, "Watchdog last update time
> > (milliseconds)");
> > static int wd_lastpat_valid = 0;
> > static time_t wd_lastpat = 0; /* when the watchdog was last
> > patted */ @@ -80,41 +93,26 @@ static time_t wd_lastpat = 0;
> > /* when the watchdog was last patted */ /* Hook for external
> > software watchdog to register for use if needed */ void
> > (*wdog_software_attach)(void);
> > -static void
> > -pow2ns_to_ts(int pow2ns, struct timespec *ts)
> > +/* Legacy interface to watchdog. */
> > +int
> > +wdog_kern_pat(u_int utim)
> > {
> > - uint64_t ns;
> > + sbintime_t sbt;
> >
> > - ns = 1ULL << pow2ns;
> > - ts->tv_sec = ns / 1000000000ULL;
> > - ts->tv_nsec = ns % 1000000000ULL;
> > -}
> > + if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0)
> > + return (EINVAL);
> >
> > -static int
> > -pow2ns_to_ticks(int pow2ns)
> > -{
> > - struct timeval tv;
> > - struct timespec ts;
> > + if ((utim & WD_LASTVAL) != 0) {
> > + return (wdog_control(WD_CTRL_RESET));
> > + }
> >
> > - pow2ns_to_ts(pow2ns, &ts);
> > - TIMESPEC_TO_TIMEVAL(&tv, &ts);
> > - return (tvtohz(&tv));
> > -}
> > + utim &= WD_INTERVAL;
> > + if (utim == WD_TO_NEVER)
> > + sbt = 0;
> > + else
> > + sbt = nstosbt(1 << utim);
> >
> > -static int
> > -seconds_to_pow2ns(int seconds)
> > -{
> > - uint64_t power;
> > - uint64_t ns;
> > - uint64_t shifted;
> > -
> > - ns = ((uint64_t)seconds) * 1000000000ULL;
> > - power = flsll(ns);
> > - shifted = 1ULL << power;
> > - if (shifted <= ns) {
> > - power++;
> > - }
> > - return (power);
> > + return (wdog_kern_pat_sbt(sbt));
> > }
> >
> > int
> > @@ -126,76 +124,63 @@ wdog_control(int ctrl)
> > }
> >
> > if ((ctrl & WD_CTRL_RESET) != 0) {
> > - wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
> > + wdog_kern_pat_sbt(wd_last_sbt);
> > } else if ((ctrl & WD_CTRL_ENABLE) != 0) {
> > - wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
> > + wdog_kern_pat_sbt(wd_last_sbt);
> > }
> >
> > return (0);
> > }
> >
> > int
> > -wdog_kern_pat(u_int utim)
> > +wdog_kern_pat_sbt(sbintime_t sbt)
> > {
> > - int error;
> > - static int first = 1;
> > -
> > - if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0)
> > - return (EINVAL);
> > -
> > - if ((utim & WD_LASTVAL) != 0) {
> > - /*
> > - * if WD_LASTVAL is set, fill in the bits for
> > timeout
> > - * from the saved value in wd_last_u.
> > - */
> > - MPASS((wd_last_u & ~WD_INTERVAL) == 0);
> > - utim &= ~WD_LASTVAL;
> > - utim |= wd_last_u;
> > - } else {
> > - /*
> > - * Otherwise save the new interval.
> > - * This can be zero (to disable the watchdog)
> > - */
> > - wd_last_u = (utim & WD_INTERVAL);
> > + sbintime_t error_sbt = 0;
> > + int pow2ns = 0;
> > + int error = 0;
> > + static bool first = true;
> > +
> > + /* legacy uses power-of-2-nanoseconds time. */
> > + if (sbt != 0) {
> > + pow2ns = flsl(sbttons(sbt));
> > + }
> > + if (wd_last_sbt != sbt) {
> > + wd_last_u = pow2ns;
> > wd_last_u_sysctl = wd_last_u;
> > - wd_last_u_sysctl_secs = pow2ns_to_ticks(wd_last_u)
> > / hz;
> > + wd_last_u_sysctl_secs = sbt / SBT_1S;
> > +
> > + wd_last_sbt = sbt;
> > }
> > - if ((utim & WD_INTERVAL) == WD_TO_NEVER) {
> > - utim = 0;
> >
> > - /* Assume all is well; watchdog signals failure. */
> > - error = 0;
> > - } else {
> > - /* Assume no watchdog available; watchdog flags
> > success */
> > + if (sbt != 0)
> > error = EOPNOTSUPP;
> > - }
> > +
> > if (wd_softtimer) {
> > - if (utim == 0) {
> > + if (sbt == 0) {
> > callout_stop(&wd_softtimeo_handle);
> > } else {
> > - (void) callout_reset(&wd_softtimeo_handle,
> > - pow2ns_to_ticks(utim), wd_timeout_cb,
> > "soft");
> > + (void)
> > callout_reset_sbt(&wd_softtimeo_handle,
> > + sbt, 0, wd_timeout_cb, "soft", 0);
> > }
> > error = 0;
> > } else {
> > - EVENTHANDLER_INVOKE(watchdog_list, utim, &error);
> > + EVENTHANDLER_INVOKE(watchdog_sbt_list, sbt,
> > &error_sbt, &error);
> > + EVENTHANDLER_INVOKE(watchdog_list, pow2ns, &error);
> > }
> > /*
> > - * If we no hardware watchdog responded, we have not tried
> > to
> > + * If no hardware watchdog responded, we have not tried to
> > * attach an external software watchdog, and one is
> > available,
> > * attach it now and retry.
> > */
> > - if (error == EOPNOTSUPP && first && *wdog_software_attach
> > != NULL) {
> > + if (error == EOPNOTSUPP && first && wdog_software_attach
> > != NULL) { (*wdog_software_attach)();
> > - EVENTHANDLER_INVOKE(watchdog_list, utim, &error);
> > + EVENTHANDLER_INVOKE(watchdog_sbt_list, sbt,
> > &error_sbt, &error);
> > + EVENTHANDLER_INVOKE(watchdog_list, pow2ns, &error);
> > }
> > - first = 0;
> > + first = false;
> >
> > + /* TODO: Print a (rate limited?) warning if error_sbt is
> > too far away */ wd_set_pretimeout(wd_pretimeout, true);
> > - /*
> > - * If we were able to arm/strobe the watchdog, then
> > - * update the last time it was strobed for
> > WDIOC_GETTIMELEFT
> > - */
> > if (!error) {
> > struct timespec ts;
> >
> > @@ -206,6 +191,7 @@ wdog_kern_pat(u_int utim)
> > wd_lastpat_valid = 1;
> > }
> > }
> > +
> > return (error);
> > }
> >
> > @@ -282,16 +268,14 @@ wd_timeout_cb(void *arg)
> > * current actual watchdog timeout.
> > */
> > static int
> > -wd_set_pretimeout(int newtimeout, int disableiftoolong)
> > +wd_set_pretimeout(sbintime_t newtimeout, int disableiftoolong)
> > {
> > - u_int utime;
> > - struct timespec utime_ts;
> > - int timeout_ticks;
> > + sbintime_t utime;
> > + sbintime_t timeout_left;
> >
> > - utime = wdog_kern_last_timeout();
> > - pow2ns_to_ts(utime, &utime_ts);
> > + utime = wdog_kern_last_timeout_sbt();
> > /* do not permit a pre-timeout >= than the timeout. */
> > - if (newtimeout >= utime_ts.tv_sec) {
> > + if (newtimeout >= utime) {
> > /*
> > * If 'disableiftoolong' then just fall through
> > * so as to disable the pre-watchdog
> > @@ -309,7 +293,7 @@ wd_set_pretimeout(int newtimeout, int
> > disableiftoolong) return 0;
> > }
> >
> > - timeout_ticks = pow2ns_to_ticks(utime) - (hz*newtimeout);
> > + timeout_left = utime - newtimeout;
> > #if 0
> > printf("wd_set_pretimeout: "
> > "newtimeout: %d, "
> > @@ -323,8 +307,8 @@ wd_set_pretimeout(int newtimeout, int
> > disableiftoolong) #endif
> >
> > /* We determined the value is sane, so reset the callout */
> > - (void) callout_reset(&wd_pretimeo_handle,
> > - timeout_ticks, wd_timeout_cb, "pre");
> > + (void) callout_reset_sbt(&wd_pretimeo_handle,
> > + timeout_left, 0, wd_timeout_cb, "pre", 0);
> > wd_pretimeout = newtimeout;
> > return 0;
> > }
> > @@ -333,6 +317,7 @@ static int
> > wd_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
> > int flags __unused, struct thread *td)
> > {
> > + sbintime_t sb;
> > u_int u;
> > time_t timeleft;
> > int error;
> > @@ -368,32 +353,55 @@ wd_ioctl(struct cdev *dev __unused, u_long
> > cmd, caddr_t data, error = EINVAL;
> > }
> > break;
> > - case WDIOC_GETPRETIMEOUT:
> > - *(int *)data = (int)wd_pretimeout;
> > +#ifdef COMPAT_FREEBSD14
> > + case WDIOC_GETPRETIMEOUT_14:
> > + *(int *)data = (int)(wd_pretimeout / SBT_1S);
> > break;
> > - case WDIOC_SETPRETIMEOUT:
> > - error = wd_set_pretimeout(*(int *)data, false);
> > + case WDIOC_SETPRETIMEOUT_14:
> > + error = wd_set_pretimeout(*(int *)data * SBT_1S,
> > false); break;
> > - case WDIOC_GETTIMELEFT:
> > + case WDIOC_GETTIMELEFT_14:
> > error = wd_get_time_left(td, &timeleft);
> > if (error)
> > break;
> > *(int *)data = (int)timeleft;
> > break;
> > - case WDIOC_SETTIMEOUT:
> > + case WDIOC_SETTIMEOUT_14:
> > u = *(u_int *)data;
> > - error = wdog_kern_pat(seconds_to_pow2ns(u));
> > + error = wdog_kern_pat_sbt(mstosbt(u * 1000ULL));
> > break;
> > - case WDIOC_GETTIMEOUT:
> > + case WDIOC_GETTIMEOUT_14:
> > u = wdog_kern_last_timeout();
> > *(u_int *)data = u;
> > break;
> > - case WDIOCPATPAT:
> > + case WDIOCPATPAT_14:
> > error = wd_ioctl_patpat(data);
> > break;
> > +#endif
> > +
> > + /* New API */
> > case WDIOC_CONTROL:
> > wdog_control(*(int *)data);
> > break;
> > + case WDIOC_SETTIMEOUT:
> > + sb = *(sbintime_t *)data;
> > + error = wdog_kern_pat_sbt(sb);
> > + break;
> > + case WDIOC_GETTIMEOUT:
> > + *(sbintime_t *)data = wdog_kern_last_timeout_sbt();
> > + break;
> > + case WDIOC_GETTIMELEFT:
> > + error = wd_get_time_left(td, &timeleft);
> > + if (error)
> > + break;
> > + *(sbintime_t *)data = (sbintime_t)timeleft *
> > SBT_1S;
> > + break;
> > + case WDIOC_GETPRETIMEOUT:
> > + *(sbintime_t *)data = wd_pretimeout;
> > + break;
> > + case WDIOC_SETPRETIMEOUT:
> > + error = wd_set_pretimeout(*(sbintime_t *)data,
> > false);
> > + break;
> > default:
> > error = ENOIOCTL;
> > break;
> > @@ -412,6 +420,12 @@ wdog_kern_last_timeout(void)
> > return (wd_last_u);
> > }
> >
> > +sbintime_t
> > +wdog_kern_last_timeout_sbt(void)
> > +{
> > + return (wd_last_sbt);
> > +}
> > +
> > static struct cdevsw wd_cdevsw = {
> > .d_version = D_VERSION,
> > .d_ioctl = wd_ioctl,
> > diff --git a/sys/sys/watchdog.h b/sys/sys/watchdog.h
> > index 3c9d31eb577b..8401d343a6b7 100644
> > --- a/sys/sys/watchdog.h
> > +++ b/sys/sys/watchdog.h
> > @@ -32,15 +32,16 @@
> > #define _SYS_WATCHDOG_H
> >
> > #include <sys/ioccom.h>
> > +#include <sys/_types.h>
> >
> > #define _PATH_WATCHDOG "fido"
> >
> > -#define WDIOCPATPAT _IOW('W', 42, u_int) /* pat the
> > watchdog */ -#define WDIOC_SETTIMEOUT _IOW('W', 43, int)
> > /* set/reset the timer */ -#define WDIOC_GETTIMEOUT _IOR('W',
> > 44, int) /* get total timeout */ -#define WDIOC_GETTIMELEFT
> > _IOR('W', 45, int) /* get time left */ -#define
> > WDIOC_GETPRETIMEOUT _IOR('W', 46, int) /* get the
> > pre-timeout */ -#define WDIOC_SETPRETIMEOUT _IOW('W', 47,
> > int) /* set the pre-timeout */ +#define WDIOC_PATPAT
> > _IOW('W', 52, sbintime_t) /* pat the watchdog */ +#define
> > WDIOC_SETTIMEOUT _IOW('W', 53, sbintime_t) /* set/reset
> > the timer */ +#define WDIOC_GETTIMEOUT _IOR('W', 54,
> > sbintime_t) /* get total timeout */ +#define
> > WDIOC_GETTIMELEFT _IOR('W', 55, sbintime_t) /* get time
> > left */ +#define WDIOC_GETPRETIMEOUT _IOR('W', 56,
> > sbintime_t) /* get the pre-timeout */ +#define
> > WDIOC_SETPRETIMEOUT _IOW('W', 57, sbintime_t) /* set the
> > pre-timeout */ /* set the action when a pre-timeout occurs see:
> > WD_SOFT_* */ #define WDIOC_SETPRETIMEOUTACT _IOW('W', 48, int) @@
> > -112,11 +113,15 @@ #include <sys/_eventhandler.h> typedef void
> > (*watchdog_fn)(void *, u_int, int *); +typedef void
> > (*watchdog_sbt_fn)(void *, sbintime_t, sbintime_t *, int *);
> > EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn);
> > +EVENTHANDLER_DECLARE(watchdog_sbt_list, watchdog_sbt_fn);
> >
> > u_int wdog_kern_last_timeout(void);
> > int wdog_kern_pat(u_int utim);
> > +sbintime_t wdog_kern_last_timeout_sbt(void);
> > +int wdog_kern_pat_sbt(sbintime_t utim);
> > int wdog_control(int ctrl);
> >
> > /*
> > diff --git a/usr.sbin/watchdogd/watchdogd.c
> > b/usr.sbin/watchdogd/watchdogd.c index 228438955006..27123f2143d0
> > 100644 --- a/usr.sbin/watchdogd/watchdogd.c
> > +++ b/usr.sbin/watchdogd/watchdogd.c
> > @@ -63,25 +63,25 @@
> > static long fetchtimeout(int opt,
> > const char *longopt, const char *myoptarg, int zero_ok);
> > static void parseargs(int, char *[]);
> > -static int seconds_to_pow2ns(int);
> > static void sighandler(int);
> > static void watchdog_loop(void);
> > static int watchdog_init(void);
> > static int watchdog_onoff(int onoff);
> > -static int watchdog_patpat(u_int timeout);
> > +static int watchdog_patpat(sbintime_t);
> > static void usage(void);
> > -static int tstotv(struct timeval *tv, struct timespec *ts);
> > static int tvtohz(struct timeval *tv);
> >
> > static int debugging = 0;
> > static int end_program = 0;
> > static const char *pidfile = _PATH_VARRUN "watchdogd.pid";
> > -static u_int timeout = WD_TO_128SEC;
> > +static sbintime_t timeout = 128 * SBT_1S;
> > static u_int exit_timeout = WD_TO_NEVER;
> > static u_int pretimeout = 0;
> > static u_int timeout_sec;
> > static u_int nap = 10;
> > +#ifdef notyet
> > static int passive = 0;
> > +#endif
> > static int is_daemon = 0;
> > static int is_dry_run = 0; /* do not arm the watchdog, only
> > report on timing of the watch
> > @@ -174,38 +174,23 @@ main(int argc, char *argv[])
> > pidfile_remove(pfh);
> > return (EX_OK);
> > } else {
> > - if (passive)
> > - timeout |= WD_PASSIVE;
> > - else
> > - timeout |= WD_ACTIVE;
> > if (watchdog_patpat(timeout) < 0)
> > err(EX_OSERR, "patting the dog");
> > return (EX_OK);
> > }
> > }
> >
> > -static void
> > -pow2ns_to_ts(int pow2ns, struct timespec *ts)
> > -{
> > - uint64_t ns;
> > -
> > - ns = 1ULL << pow2ns;
> > - ts->tv_sec = ns / 1000000000ULL;
> > - ts->tv_nsec = ns % 1000000000ULL;
> > -}
> > -
> > /*
> > * 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) +static sbintime_t
> > +parse_timeout_to_sbt(char opt, const char *longopt, const char
> > *myoptarg) {
> > - double a;
> > - u_int rv;
> > - struct timespec ts;
> > + long a;
> > + sbintime_t rv;
> > struct timeval tv;
> > int ticks;
> > char shortopt[] = "- ";
> > @@ -216,19 +201,17 @@ parse_timeout_to_pow2ns(char opt, const char
> > *longopt, const char *myoptarg) a = fetchtimeout(opt, longopt,
> > myoptarg, 1);
> > if (a == 0)
> > - rv = WD_TO_NEVER;
> > + rv = 0;
> > else
> > - rv = seconds_to_pow2ns(a);
> > - pow2ns_to_ts(rv, &ts);
> > - tstotv(&tv, &ts);
> > + rv = a * SBT_1S;
> > + tv = sbttotv(rv);
> > 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",
> > + "is "
> > + "(in: %s sec -> out: %jd sec %ld us -> %d
> > ticks)\n", longopt ? "-" : "", longopt ? longopt : shortopt,
> > - rv,
> > - myoptarg, (intmax_t)ts.tv_sec, ts.tv_nsec,
> > ticks);
> > + myoptarg, (intmax_t)tv.tv_sec, tv.tv_usec,
> > ticks); }
> > if (ticks <= 0) {
> > errx(1, "Timeout for %s%s is too small, please
> > choose a higher timeout.", longopt ? "-" : "", longopt ? longopt :
> > shortopt); @@ -364,7 +347,7 @@ watchdog_loop(void) }
> >
> > if (failed == 0)
> > - watchdog_patpat(timeout|WD_ACTIVE);
> > + watchdog_patpat(timeout);
> >
> > waited =
> > watchdog_check_dogfunction_time(&ts_start, &ts_end); if (nap -
> > waited > 0) @@ -387,13 +370,13 @@ try_end:
> > * to keep the watchdog from firing.
> > */
> > static int
> > -watchdog_patpat(u_int t)
> > +watchdog_patpat(sbintime_t sbt)
> > {
> >
> > if (is_dry_run)
> > return 0;
> >
> > - return ioctl(fd, WDIOCPATPAT, &t);
> > + return ioctl(fd, WDIOC_SETTIMEOUT, &sbt);
> > }
> >
> > static int
> > @@ -429,7 +412,7 @@ watchdog_onoff(int onoff)
> > warn("setting WDIOC_SETSOFT %d",
> > softtimeout_set); return (error);
> > }
> > - error = watchdog_patpat((timeout|WD_ACTIVE));
> > + error = watchdog_patpat(timeout);
> > if (error) {
> > warn("watchdog_patpat failed");
> > goto failsafe;
> > @@ -461,7 +444,7 @@ watchdog_onoff(int onoff)
> > }
> > }
> > /* pat one more time for good measure */
> > - return watchdog_patpat((timeout|WD_ACTIVE));
> > + return watchdog_patpat(timeout);
> > } else {
> > return watchdog_control(WD_CTRL_DISABLE);
> > }
> > @@ -576,15 +559,6 @@ timeout_act_str2int(const char *lopt, const
> > char *acts) return rv;
> > }
> >
> > -int
> > -tstotv(struct timeval *tv, struct timespec *ts)
> > -{
> > -
> > - tv->tv_sec = ts->tv_sec;
> > - tv->tv_usec = ts->tv_nsec / 1000;
> > - return 0;
> > -}
> > -
> > /*
> > * Convert a timeval to a number of ticks.
> > * Mostly copied from the kernel.
> > @@ -656,30 +630,6 @@ tvtohz(struct timeval *tv)
> > return ((int)ticks);
> > }
> >
> > -static int
> > -seconds_to_pow2ns(int seconds)
> > -{
> > - uint64_t power;
> > - uint64_t ns;
> > - uint64_t shifted;
> > -
> > - if (seconds <= 0)
> > - errx(1, "seconds %d < 0", seconds);
> > - ns = ((uint64_t)seconds) * 1000000000ULL;
> > - power = flsll(ns);
> > - shifted = 1ULL << power;
> > - if (shifted <= ns) {
> > - power++;
> > - }
> > - if (debugging) {
> > - printf("shifted %lld\n", (long long)shifted);
> > - printf("seconds_to_pow2ns: seconds: %d, ns %lld,
> > power %d\n",
> > - seconds, (long long)ns, (int)power);
> > - }
> > - return (power);
> > -}
> > -
> > -
> > /*
> > * Handle the few command line arguments supported.
> > */
> > @@ -692,8 +642,7 @@ parseargs(int argc, char *argv[])
> > const char *lopt;
> >
> > /* Get the default value of timeout_sec from the default
> > timeout. */
> > - pow2ns_to_ts(timeout, &ts);
> > - timeout_sec = ts.tv_sec;
> > + timeout_sec = sbintime_getsec(timeout);
> >
> > /*
> > * if we end with a 'd' aka 'watchdogd' then we are the
> > daemon program, @@ -736,10 +685,10 @@ parseargs(int argc, char
> > *argv[]) break;
> > case 't':
> > timeout_sec = atoi(optarg);
> > - timeout = parse_timeout_to_pow2ns(c, NULL,
> > optarg);
> > + timeout = parse_timeout_to_sbt(c, NULL,
> > optarg); if (debugging)
> > - printf("Timeout is 2^%d
> > nanoseconds\n",
> > - timeout);
> > + printf("Timeout is %d\n",
> > + (int)(timeout / SBT_1S));
> > break;
> > case 'T':
> > carp_thresh_seconds =
> > @@ -749,7 +698,7 @@ parseargs(int argc, char *argv[])
> > do_timedog = 1;
> > break;
> > case 'x':
> > - exit_timeout = parse_timeout_to_pow2ns(c,
> > NULL, optarg);
> > + exit_timeout = parse_timeout_to_sbt(c,
> > NULL, optarg); if (exit_timeout != 0)
> > exit_timeout |= WD_ACTIVE;
> > break;
>