]> granicus.if.org Git - strace/commitdiff
Add support for /dev/watchdog ioctls
authorRasmus Villemoes <rasmus.villemoes@prevas.dk>
Wed, 21 Aug 2019 11:35:23 +0000 (11:35 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 23 Aug 2019 17:05:51 +0000 (17:05 +0000)
* 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@prevas.dk>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Makefile.am
defs.h
ioctl.c
tests/.gitignore
tests/gen_tests.in
tests/ioctl_watchdog.c [new file with mode: 0644]
tests/pure_executables.list
watchdog_ioctl.c [new file with mode: 0644]
xlat/watchdog_ioctl_cmds.in [new file with mode: 0644]

index 8ce2147f75dbe2ec33e239ad3d966201c9da8f18..b4f31568fddf957f8d3c8df413706c9cec75bb32 100644 (file)
@@ -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 3cccdac188e709e9ed9be0e7ec79b0f5b5e2a9af..67467c12e42088338f3192d1859f5c61b307e30f 100644 (file)
--- 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 b80292cb859cc0f7c6ab1a7c0b11edb60463a469..75c31e8b1e3f638a19ef668d941f28d5ece72566 100644 (file)
--- 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;
        }
index afb932d807124ab3a0dd7ec0e594449411b64679..4c854db8394f1fcfaac7d92a467d256aff698aa4 100644 (file)
@@ -186,6 +186,7 @@ ioctl_sg_io_v4
 ioctl_sock_gifconf
 ioctl_uffdio
 ioctl_v4l2
+ioctl_watchdog
 ioperm
 iopl
 ioprio
index 7ef5af6ac64fb0fe662b603a039c32f793b493a1..ab844128a34fd69f17ff382172eba558ef5f714c 100644 (file)
@@ -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 (file)
index 0000000..d1af836
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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);
+
+       ioctl(-1, _IOC(_IOC_NONE, 'W', 0xff, 0), &val);
+       printf("ioctl(-1, _IOC(_IOC_NONE, %#x, 0xff, 0), %p)" RVAL_EBADF,
+              'W', &val);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
index e0e8cc99021bf83769b5cd91aa4741b7d6bb30e7..b565eb9c6378973e822022446623ecd159590ac5 100755 (executable)
@@ -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 (file)
index 0000000..179ed8b
--- /dev/null
@@ -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 (file)
index 0000000..b871cbd
--- /dev/null
@@ -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)