From nobody Tue Aug 19 19:25:18 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4c600b5Qpbz65Q77; Tue, 19 Aug 2025 19:25:19 +0000 (UTC) (envelope-from mhorne@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4c600b57ygz4GpV; Tue, 19 Aug 2025 19:25:19 +0000 (UTC) (envelope-from mhorne@freebsd.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755631519; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3ny8YO7XE1FCFleLqrWm6775oJw7CVr9pIrKxlNd3/Q=; b=MYbtlCz3oSA8wJcnIOODHTfJdRy3xGggkH3WGIbAnFajvzjEIHqKJZR8ez3E54YGC+uO4s Fy5dMQcfqbE5fASXgL253lom6RHo97WC3RRNtK23J1HbjpHZ+zj9ZexJTj+H6btYYCWDJn Ax5F6kEc1Jo5nhZ72YrnmXrqZnKuYQJsCo05XS9HVLB3rjH+RhyjJ9UgthFyI3ojVUCQRG 70h9e0rpf2jo26LdSVPMABjA3thTqIl3kr2PqBQw0nXy8vEgqBwHarRK3TYITtrhlfFnK4 TpqgBFPjTPcnZEY1M4Aga31g2p2gS99SavEuCTyxZFbugPne/CWNztbw7XRn7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1755631519; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3ny8YO7XE1FCFleLqrWm6775oJw7CVr9pIrKxlNd3/Q=; b=TzoePLZ7koQGolu/ms2nEmfuXfBQOPrbSPVAwj28lTkg+4q4PoPin5TvnWNR5RAXkP/wBa zXj3Y3SaQCr5/zBRk/2/SwykWkZI1cIwvgkUmbLUbINurilo6vblcMbyVfq1Yoed86PZsn uJrVYX3rNDBMNyUDme0dxSR1udh2R+4pHtWJhSMLI3nwRwfag//4PQFnd9RuyPKLaWfR95 Mni6e/bRfkCEB/eD49Dg+YgOogxKYZ8oSz3mme97U5ZT+qnU0JAzTSIL1HtkaJ2p+MQ5Lq FOITeAIhuTcRdFzmXjJgUX8Icapd4Il5DIL1EGl+8iLyBq6VUyMojv66884L0Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1755631519; a=rsa-sha256; cv=none; b=pBs9WL0lXznl+pjr86ja6vwx3vht9dgGP97EU98wIzCxUx2Wk/l1qO+Hakc77UfiAmwPot 9xnEPmX0dZvT1oflOOafaHvFxIG6f+y9nxFs2PMJkYitqBiQ0RIF8kD4tC3niF6Kbd84JS yk/NcWMhmt5v26p3zwcEvgw/vXvuu7Ao0FOxVzAvRH0K5C451Zy7s6nXnduYb4W342x10U GuELRLqJPiftpMOYizhmaSMegLf5XLTowcFFnxuqWal8fuCAQOFGYm/X903+1Ycd0m4G7V tNbHPcOdTutNT9QVeCO/FONx1ygcjTV7x7etc44XNRiuss2zCASSyzHP8yObAQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from [192.168.1.217] (hlfxns018gw-134-41-175-217.dhcp-dynamic.fibreop.ns.bellaliant.net [134.41.175.217]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: mhorne) by smtp.freebsd.org (Postfix) with ESMTPSA id 4c600b360qz4J6; Tue, 19 Aug 2025 19:25:19 +0000 (UTC) (envelope-from mhorne@freebsd.org) Message-ID: <7704c59a-5ca1-4493-b362-ee81e78fab0f@freebsd.org> Date: Tue, 19 Aug 2025 16:25:18 -0300 List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Mitchell Horne Subject: Re: git: 26d6617f3e54 - main - watchdog: Convert to using sbintime_t format To: Justin Hibbits , src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org References: <202508141903.57EJ39C9018272@gitrepo.freebsd.org> Content-Language: en-CA In-Reply-To: <202508141903.57EJ39C9018272@gitrepo.freebsd.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 > AuthorDate: 2025-02-26 20:25:36 +0000 > Commit: Justin Hibbits > 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 > > 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 /* 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 > +#include > > #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 > > 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;