git: 69f7d6912a24 - main - watchdog: Add a new "Control" ioctl
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 14 Aug 2025 19:03:08 UTC
The branch main has been updated by jhibbits:
URL: https://cgit.FreeBSD.org/src/commit/?id=69f7d6912a24d3caab4957a33e07529275cf4d09
commit 69f7d6912a24d3caab4957a33e07529275cf4d09
Author: Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2025-02-26 20:17:24 +0000
Commit: Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2025-08-14 19:02:46 +0000
watchdog: Add a new "Control" ioctl
Summary:
In preparation for a new watchdog timeout interface using sbintime_t,
add a new control ioctl to arm, pat, and disarm the watchdog.
Reviewed by: jhb, phk
Sponsored by: Juniper Networks, Inc.
Differential Revision: https://reviews.freebsd.org/D49182
---
sys/dev/watchdog/watchdog.c | 20 ++++++++++++++++++++
sys/sys/watchdog.h | 8 ++++++++
usr.sbin/watchdogd/watchdogd.c | 13 +++++++++++--
3 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/sys/dev/watchdog/watchdog.c b/sys/dev/watchdog/watchdog.c
index e6b6dc1eac70..c0babef1b29b 100644
--- a/sys/dev/watchdog/watchdog.c
+++ b/sys/dev/watchdog/watchdog.c
@@ -117,6 +117,23 @@ seconds_to_pow2ns(int seconds)
return (power);
}
+int
+wdog_control(int ctrl)
+{
+ /* Disable takes precedence */
+ if (ctrl == WD_CTRL_DISABLE) {
+ wdog_kern_pat(0);
+ }
+
+ if ((ctrl & WD_CTRL_RESET) != 0) {
+ wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
+ } else if ((ctrl & WD_CTRL_ENABLE) != 0) {
+ wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
+ }
+
+ return (0);
+}
+
int
wdog_kern_pat(u_int utim)
{
@@ -374,6 +391,9 @@ wd_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
case WDIOCPATPAT:
error = wd_ioctl_patpat(data);
break;
+ case WDIOC_CONTROL:
+ wdog_control(*(int *)data);
+ break;
default:
error = ENOIOCTL;
break;
diff --git a/sys/sys/watchdog.h b/sys/sys/watchdog.h
index 4a16b18509f5..3c9d31eb577b 100644
--- a/sys/sys/watchdog.h
+++ b/sys/sys/watchdog.h
@@ -48,6 +48,8 @@
#define WDIOC_SETSOFT _IOW('W', 49, int)
#define WDIOC_SETSOFTTIMEOUTACT _IOW('W', 50, int)
+#define WDIOC_CONTROL _IOW('W', 51, int) /* configure watchdog */
+
#define WD_ACTIVE 0x8000000
/*
* Watchdog reset, timeout set to value in WD_INTERVAL field.
@@ -93,6 +95,11 @@
#define WD_TO_64SEC 36
#define WD_TO_128SEC 37
+/* Control options for WDIOC_CONTROL */
+#define WD_CTRL_DISABLE 0x00000000
+#define WD_CTRL_ENABLE 0x00000001
+#define WD_CTRL_RESET 0x00000002
+
/* action on pre-timeout trigger */
#define WD_SOFT_PANIC 0x01 /* panic */
#define WD_SOFT_DDB 0x02 /* enter debugger */
@@ -110,6 +117,7 @@ EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn);
u_int wdog_kern_last_timeout(void);
int wdog_kern_pat(u_int utim);
+int wdog_control(int ctrl);
/*
* The following function pointer is used to attach a software watchdog
diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c
index 88b467486da1..228438955006 100644
--- a/usr.sbin/watchdogd/watchdogd.c
+++ b/usr.sbin/watchdogd/watchdogd.c
@@ -396,6 +396,15 @@ watchdog_patpat(u_int t)
return ioctl(fd, WDIOCPATPAT, &t);
}
+static int
+watchdog_control(u_int control)
+{
+ if (is_dry_run)
+ return (0);
+
+ return ioctl(fd, WDIOC_CONTROL, &control);
+}
+
/*
* Toggle the kernel's watchdog. This routine is used to enable and
* disable the watchdog.
@@ -454,10 +463,10 @@ watchdog_onoff(int onoff)
/* pat one more time for good measure */
return watchdog_patpat((timeout|WD_ACTIVE));
} else {
- return watchdog_patpat(exit_timeout);
+ return watchdog_control(WD_CTRL_DISABLE);
}
failsafe:
- watchdog_patpat(exit_timeout);
+ watchdog_control(WD_CTRL_DISABLE);
return (error);
}