[PATCH] Add support for /dev/watchdog ioctls

Rasmus Villemoes rasmus.villemoes at prevas.dk
Wed Aug 21 11:35:23 UTC 2019


* watchdog_ioctl.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* defs.h (DECL_IOCTL): Add watchdog.
* ioctl.c (ioctl_decode): Add 'W' case.
* xlat/watchdog_ioctl_cmds.in: New file.
* tests/ioctl_watchdog.c: New file.
* tests/.gitignore: Add ioctl_watchdog.
* tests/pure_executables.list: Likewise.
* tests/gen_tests.in (ioctl_watchdog): New entry.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
---
 Makefile.am                 |  1 +
 defs.h                      |  1 +
 ioctl.c                     |  2 ++
 tests/.gitignore            |  1 +
 tests/gen_tests.in          |  1 +
 tests/ioctl_watchdog.c      | 57 +++++++++++++++++++++++++++++++++++++
 tests/pure_executables.list |  1 +
 watchdog_ioctl.c            | 47 ++++++++++++++++++++++++++++++
 xlat/watchdog_ioctl_cmds.in | 10 +++++++
 9 files changed, 121 insertions(+)
 create mode 100644 tests/ioctl_watchdog.c
 create mode 100644 watchdog_ioctl.c
 create mode 100644 xlat/watchdog_ioctl_cmds.in

diff --git a/Makefile.am b/Makefile.am
index 8ce2147f..b4f31568 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -357,6 +357,7 @@ strace_SOURCES =	\
 	v4l2.c		\
 	wait.c		\
 	wait.h		\
+	watchdog_ioctl.c \
 	xattr.c		\
 	xfs_quota_stat.h \
 	xlat.c		\
diff --git a/defs.h b/defs.h
index 3cccdac1..67467c12 100644
--- a/defs.h
+++ b/defs.h
@@ -944,6 +944,7 @@ DECL_IOCTL(scsi);
 DECL_IOCTL(term);
 DECL_IOCTL(ubi);
 DECL_IOCTL(uffdio);
+DECL_IOCTL(watchdog);
 # undef DECL_IOCTL
 
 extern int decode_sg_io_v4(struct tcb *, const kernel_ulong_t arg);
diff --git a/ioctl.c b/ioctl.c
index b80292cb..75c31e8b 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -309,6 +309,8 @@ ioctl_decode(struct tcb *tcp)
 		return nbd_ioctl(tcp, code, arg);
 	case 'R':
 		return random_ioctl(tcp, code, arg);
+	case 'W':
+		return watchdog_ioctl(tcp, code, arg);
 	default:
 		break;
 	}
diff --git a/tests/.gitignore b/tests/.gitignore
index afb932d8..4c854db8 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -186,6 +186,7 @@ ioctl_sg_io_v4
 ioctl_sock_gifconf
 ioctl_uffdio
 ioctl_v4l2
+ioctl_watchdog
 ioperm
 iopl
 ioprio
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 7ef5af6a..ab844128 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -155,6 +155,7 @@ ioctl_sg_io_v4	+ioctl.test
 ioctl_sock_gifconf	+ioctl.test -a28 -s1
 ioctl_uffdio	+ioctl.test
 ioctl_v4l2	+ioctl.test
+ioctl_watchdog	+ioctl.test
 ioperm	-a27
 iopl	-a8
 ioprio	-a18 -e trace=ioprio_get,ioprio_set
diff --git a/tests/ioctl_watchdog.c b/tests/ioctl_watchdog.c
new file mode 100644
index 00000000..48b4acba
--- /dev/null
+++ b/tests/ioctl_watchdog.c
@@ -0,0 +1,57 @@
+/*
+ * Check decoding of WDIOC* commands of ioctl syscall.
+ *
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <linux/watchdog.h>
+
+#define XLAT_MACROS_ONLY
+#include "xlat/watchdog_ioctl_cmds.h"
+#undef XLAT_MACROS_ONLY
+
+#define RVAL_EBADF " = -1 EBADF (%m)\n"
+
+int
+main(void)
+{
+	int val = 123;
+
+	ioctl(-1, WDIOC_GETSTATUS, &val);
+	printf("ioctl(-1, WDIOC_GETSTATUS, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_GETBOOTSTATUS, &val);
+	printf("ioctl(-1, WDIOC_GETBOOTSTATUS, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_GETTEMP, &val);
+	printf("ioctl(-1, WDIOC_GETTEMP, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_GETTIMEOUT, &val);
+	printf("ioctl(-1, WDIOC_GETTIMEOUT, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_GETPRETIMEOUT, &val);
+	printf("ioctl(-1, WDIOC_GETPRETIMEOUT, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_GETTIMELEFT, &val);
+	printf("ioctl(-1, WDIOC_GETTIMELEFT, %p)" RVAL_EBADF, &val);
+
+	ioctl(-1, WDIOC_SETTIMEOUT, &val);
+	printf("ioctl(-1, WDIOC_SETTIMEOUT, [123])" RVAL_EBADF);
+
+	ioctl(-1, WDIOC_SETPRETIMEOUT, &val);
+	printf("ioctl(-1, WDIOC_SETPRETIMEOUT, [123])" RVAL_EBADF);
+
+	ioctl(-1, WDIOC_KEEPALIVE);
+	printf("ioctl(-1, WDIOC_KEEPALIVE)" RVAL_EBADF);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index e0e8cc99..b565eb9c 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -154,6 +154,7 @@ ioctl_sg_io_v4
 ioctl_sock_gifconf
 ioctl_uffdio
 ioctl_v4l2
+ioctl_watchdog
 ioperm
 iopl
 ioprio
diff --git a/watchdog_ioctl.c b/watchdog_ioctl.c
new file mode 100644
index 00000000..179ed8b2
--- /dev/null
+++ b/watchdog_ioctl.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#include "print_fields.h"
+
+#include <linux/watchdog.h>
+
+#define XLAT_MACROS_ONLY
+#include "xlat/watchdog_ioctl_cmds.h"
+#undef XLAT_MACROS_ONLY
+
+int
+watchdog_ioctl(struct tcb *const tcp, const unsigned int code,
+	   const kernel_ulong_t arg)
+{
+	switch (code) {
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+	case WDIOC_GETTEMP:
+	case WDIOC_GETTIMEOUT:
+	case WDIOC_GETPRETIMEOUT:
+	case WDIOC_GETTIMELEFT:
+		if (entering(tcp))
+			return 0;
+		ATTRIBUTE_FALLTHROUGH;
+	case WDIOC_SETTIMEOUT:
+	case WDIOC_SETPRETIMEOUT:
+		tprints(", ");
+		printnum_int(tcp, arg, "%d");
+		break;
+
+	/*
+	 * linux/watchdog.h says that this takes an int, but in
+	 * practice the argument is ignored.
+	 */
+	case WDIOC_KEEPALIVE:
+		break;
+	default:
+		return RVAL_DECODED;
+	}
+	return RVAL_IOCTL_DECODED;
+}
diff --git a/xlat/watchdog_ioctl_cmds.in b/xlat/watchdog_ioctl_cmds.in
new file mode 100644
index 00000000..b871cbd1
--- /dev/null
+++ b/xlat/watchdog_ioctl_cmds.in
@@ -0,0 +1,10 @@
+WDIOC_GETSTATUS         _IOR('W', 1, int)
+WDIOC_GETBOOTSTATUS     _IOR('W', 2, int)
+WDIOC_GETTEMP           _IOR('W', 3, int)
+WDIOC_GETTIMEOUT        _IOR('W', 7, int)
+WDIOC_GETPRETIMEOUT     _IOR('W', 9, int)
+WDIOC_GETTIMELEFT       _IOR('W', 10, int)
+WDIOC_SETOPTIONS        _IOR('W', 4, int)
+WDIOC_KEEPALIVE         _IOR('W', 5, int)
+WDIOC_SETTIMEOUT        _IOWR('W', 6, int)
+WDIOC_SETPRETIMEOUT     _IOWR('W', 8, int)
-- 
2.20.1



More information about the Strace-devel mailing list