[RFC/PATCH] watchdog_ioctl: Add decoding of WDIOC_GETSUPPORT and WDIOC_SETOPTIONS ioctls.

Sahil Siddiq icegambit91 at gmail.com
Sun Aug 4 06:58:00 UTC 2024


* src/watchdog_ioctl.c: Implement new ioctl decoders.
* src/xlat/watchdog_ioctl_cmds.in (WDIOC_GETSUPPORT): Add new constant.
* src/xlat/watchdog_ioctl_setoptions.in: New file.
* src/xlat/watchdog_ioctl_support_options.in: New file.
* NEWS: Mention this change.
* tests/ioctl_watchdog.c: Add tests for new decoders.

Signed-off-by: Sahil Siddiq <sahilcdq at proton.me>
---
Hi,

I am not sure how one adds a test for the constants
that are bitwise OR'd in the options field of "struct
watchdog_info". The struct is decoded when fd refers
to a watchdog device (eg.: /dev/watchdog) but one needs
to have the appropriate privileges to access such a
device. I have left this part out for the time being.

Thanks,
Sahil

 NEWS                                       |  2 ++
 src/watchdog_ioctl.c                       | 33 ++++++++++++++++++++++
 src/xlat/watchdog_ioctl_cmds.in            |  1 +
 src/xlat/watchdog_ioctl_setoptions.in      |  3 ++
 src/xlat/watchdog_ioctl_support_options.in | 12 ++++++++
 tests/ioctl_watchdog.c                     | 19 +++++++++++++
 6 files changed, 70 insertions(+)
 create mode 100644 src/xlat/watchdog_ioctl_setoptions.in
 create mode 100644 src/xlat/watchdog_ioctl_support_options.in

diff --git a/NEWS b/NEWS
index 32bf5d547..58fd890aa 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Noteworthy changes in release ?.?? (????-??-??)
   * Updated decoding of listmount, statmount, and statx syscalls.
   * Updated lists of ETHTOOL_*, IORING_*, IPPROTO_*, RWF_*, STATX_*, and V4L2_*
     constants.
+  * Implemented decoding of WDIOC_GETSUPPORT and WDIOC_SETOPTIONS ioctl
+    commands.
 
 Noteworthy changes in release 6.10 (2024-07-21)
 ===============================================
diff --git a/src/watchdog_ioctl.c b/src/watchdog_ioctl.c
index b88094f0d..379ddb4f9 100644
--- a/src/watchdog_ioctl.c
+++ b/src/watchdog_ioctl.c
@@ -9,6 +9,9 @@
 
 #include <linux/watchdog.h>
 
+#include "xlat/watchdog_ioctl_setoptions.h"
+#include "xlat/watchdog_ioctl_support_options.h"
+
 #define XLAT_MACROS_ONLY
 #include "xlat/watchdog_ioctl_cmds.h"
 #undef XLAT_MACROS_ONLY
@@ -17,7 +20,30 @@ int
 watchdog_ioctl(struct tcb *const tcp, const unsigned int code,
 	   const kernel_ulong_t arg)
 {
+	struct watchdog_info ident;
+	int options;
+
 	switch (code) {
+	case WDIOC_GETSUPPORT:
+		if (entering(tcp))
+			return 0;
+		tprint_arg_next();
+		if (!umove_or_printaddr(tcp, arg, &ident)) {
+			tprint_struct_begin();
+			PRINT_FIELD_FLAGS(ident, options, watchdog_ioctl_support_options,
+					  "WDIOF_???");
+			tprint_struct_next();
+			if (abbrev(tcp))
+				tprint_more_data_follows();
+			else {
+				PRINT_FIELD_U(ident, firmware_version);
+				tprint_struct_next();
+				tprints_field_name("identity");
+				printstr(tcp, arg + offsetof(struct watchdog_info, identity));
+			}
+			tprint_struct_end();
+		}
+		break;
 	case WDIOC_GETSTATUS:
 	case WDIOC_GETBOOTSTATUS:
 	case WDIOC_GETTEMP:
@@ -32,6 +58,13 @@ watchdog_ioctl(struct tcb *const tcp, const unsigned int code,
 		tprint_arg_next();
 		printnum_int(tcp, arg, "%d");
 		break;
+	case WDIOC_SETOPTIONS:
+		if (!umove_or_printaddr(tcp, arg, &options)) {
+			tprint_arg_next();
+			tprint_indirect_begin();
+			printflags64(watchdog_ioctl_setoptions, options, "WDIOS_???");
+			tprint_indirect_end();
+		}
 
 	/*
 	 * linux/watchdog.h says that this takes an int, but in
diff --git a/src/xlat/watchdog_ioctl_cmds.in b/src/xlat/watchdog_ioctl_cmds.in
index b871cbd1e..d77f3d41c 100644
--- a/src/xlat/watchdog_ioctl_cmds.in
+++ b/src/xlat/watchdog_ioctl_cmds.in
@@ -1,3 +1,4 @@
+WDIOC_GETSUPPORT        _IOR('W', 0, struct watchdog_info)
 WDIOC_GETSTATUS         _IOR('W', 1, int)
 WDIOC_GETBOOTSTATUS     _IOR('W', 2, int)
 WDIOC_GETTEMP           _IOR('W', 3, int)
diff --git a/src/xlat/watchdog_ioctl_setoptions.in b/src/xlat/watchdog_ioctl_setoptions.in
new file mode 100644
index 000000000..5ef67714e
--- /dev/null
+++ b/src/xlat/watchdog_ioctl_setoptions.in
@@ -0,0 +1,3 @@
+WDIOS_DISABLECARD      0x0001
+WDIOS_ENABLECARD       0x0002
+WDIOS_TEMPPANIC        0x0004
diff --git a/src/xlat/watchdog_ioctl_support_options.in b/src/xlat/watchdog_ioctl_support_options.in
new file mode 100644
index 000000000..2030cf329
--- /dev/null
+++ b/src/xlat/watchdog_ioctl_support_options.in
@@ -0,0 +1,12 @@
+WDIOF_OVERHEAT          0x0001
+WDIOF_FANFAULT          0x0002
+WDIOF_EXTERN1           0x0004
+WDIOF_EXTERN2           0x0008
+WDIOF_POWERUNDER        0x0010
+WDIOF_CARDRESET         0x0020
+WDIOF_POWEROVER         0x0040
+WDIOF_SETTIMEOUT        0x0080
+WDIOF_MAGICCLOSE        0x0100
+WDIOF_PRETIMEOUT        0x0200
+WDIOF_ALARMONLY         0x0400
+WDIOF_KEEPALIVEPING     0x8000
diff --git a/tests/ioctl_watchdog.c b/tests/ioctl_watchdog.c
index 744947e87..26974afa2 100644
--- a/tests/ioctl_watchdog.c
+++ b/tests/ioctl_watchdog.c
@@ -22,6 +22,13 @@ int
 main(void)
 {
 	int val = 123;
+	struct watchdog_info ident;
+	int single_option = 1;
+	int multiple_options = 6;
+	int unknown_option = 0xfed8;
+
+	ioctl(-1, WDIOC_GETSUPPORT, &ident);
+	printf("ioctl(-1, WDIOC_GETSUPPORT, %p)" RVAL_EBADF, &ident);
 
 	ioctl(-1, WDIOC_GETSTATUS, &val);
 	printf("ioctl(-1, WDIOC_GETSTATUS, %p)" RVAL_EBADF, &val);
@@ -47,6 +54,18 @@ main(void)
 	ioctl(-1, WDIOC_SETPRETIMEOUT, &val);
 	printf("ioctl(-1, WDIOC_SETPRETIMEOUT, [123])" RVAL_EBADF);
 
+	ioctl(-1, WDIOC_SETOPTIONS, &single_option);
+	printf("ioctl(-1, WDIOC_SETOPTIONS, [%s])" RVAL_EBADF,
+	       XLAT_KNOWN(0x1, "WDIOS_DISABLECARD"));
+
+	ioctl(-1, WDIOC_SETOPTIONS, &multiple_options);
+	printf("ioctl(-1, WDIOC_SETOPTIONS, [%s])" RVAL_EBADF,
+	       XLAT_KNOWN(0x6, "WDIOS_ENABLECARD|WDIOS_TEMPPANIC"));
+
+	ioctl(-1, WDIOC_SETOPTIONS, &unknown_option);
+	printf("ioctl(-1, WDIOC_SETOPTIONS, [%s])" RVAL_EBADF,
+	       XLAT_UNKNOWN(0xfed8, "WDIOS_???"));
+
 	ioctl(-1, WDIOC_KEEPALIVE);
 	printf("ioctl(-1, WDIOC_KEEPALIVE)" RVAL_EBADF);
 
-- 
2.45.2



More information about the Strace-devel mailing list