[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