]> granicus.if.org Git - strace/commitdiff
Implement decoding of NBD_* ioctl commands
authorElvira Khabirova <lineprinter@altlinux.org>
Sat, 22 Sep 2018 13:09:50 +0000 (15:09 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 25 Oct 2018 20:50:32 +0000 (20:50 +0000)
* nbd_ioctl.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* defs.h (DECL_IOCTL): Add nbd.
* ioctl.c (ioctl_decode): Add 0xab (nbd) case.
* xlat/nbd_ioctl_cmds.in: Likewise.
* xlat/nbd_ioctl_flags.in: Likewise.
* tests/ioctl_nbd.c: Likewise.
* tests/.gitignore: Add ioctl_nbd.
* tests/pure_executables.list: Likewise.
* tests/gen_tests.in (ioctl_nbd): New entry.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Makefile.am
defs.h
ioctl.c
nbd_ioctl.c [new file with mode: 0644]
tests/.gitignore
tests/gen_tests.in
tests/ioctl_nbd.c [new file with mode: 0644]
tests/pure_executables.list
xlat/nbd_ioctl_cmds.in [new file with mode: 0644]
xlat/nbd_ioctl_flags.in [new file with mode: 0644]

index 9e5eef276c59d92b2bb9704e7e8c150ec7568049..913d26a9e9194854503d35e4d32721e39067a424 100644 (file)
@@ -204,6 +204,7 @@ strace_SOURCES =    \
        msghdr.h        \
        mtd.c           \
        native_defs.h   \
+       nbd_ioctl.c     \
        negated_errno.h \
        net.c           \
        netlink.c       \
diff --git a/defs.h b/defs.h
index 7f1e64dacdf23a7e53a535f7a1ffbe09d0781910..5ba95f53d788952a0060c3a0d32f13813b4da3c6 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -970,6 +970,7 @@ DECL_IOCTL(file);
 DECL_IOCTL(fs_x);
 DECL_IOCTL(inotify);
 DECL_IOCTL(kvm);
+DECL_IOCTL(nbd);
 DECL_IOCTL(nsfs);
 DECL_IOCTL(ptp);
 DECL_IOCTL(scsi);
diff --git a/ioctl.c b/ioctl.c
index 66b10ec4c7b11737ed0d6f0ca858994e588d7d88..4c9e7db313d1bb14fd082a8fee8d0a0b266dd439 100644 (file)
--- a/ioctl.c
+++ b/ioctl.c
@@ -327,6 +327,8 @@ ioctl_decode(struct tcb *tcp)
 #endif
        case 'I':
                return inotify_ioctl(tcp, code, arg);
+       case 0xab:
+               return nbd_ioctl(tcp, code, arg);
        default:
                break;
        }
diff --git a/nbd_ioctl.c b/nbd_ioctl.c
new file mode 100644 (file)
index 0000000..0ceec3e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2018 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include "print_fields.h"
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/nbd.h>
+
+#define XLAT_MACROS_ONLY
+# include "xlat/nbd_ioctl_cmds.h"
+#undef XLAT_MACROS_ONLY
+
+#include "xlat/nbd_ioctl_flags.h"
+
+int
+nbd_ioctl(struct tcb *const tcp, const unsigned int code,
+         const kernel_ulong_t arg)
+{
+       switch (code) {
+       case NBD_DISCONNECT:
+       case NBD_CLEAR_SOCK:
+       case NBD_DO_IT:
+       case NBD_CLEAR_QUE:
+       case NBD_PRINT_DEBUG:
+               return RVAL_IOCTL_DECODED;
+
+       case NBD_SET_SOCK:
+               tprints(", ");
+               printfd(tcp, arg);
+               return RVAL_IOCTL_DECODED;
+
+       case NBD_SET_BLKSIZE:
+       case NBD_SET_SIZE:
+       case NBD_SET_SIZE_BLOCKS:
+       case NBD_SET_TIMEOUT:
+               tprints(", ");
+               tprintf("%" PRI_klu, arg);
+               return RVAL_IOCTL_DECODED;
+
+       case NBD_SET_FLAGS:
+               tprints(", ");
+               printflags(nbd_ioctl_flags, arg, "NBD_IOC_FLAG_???");
+               return RVAL_IOCTL_DECODED;
+
+       default:
+               return RVAL_DECODED;
+       }
+}
index a7f201ee2bf1fb4f14a128e3b65f13d9bb248dfd..577a1316da0630bd90aa3421dca4d9ad4e387634 100644 (file)
@@ -153,6 +153,7 @@ ioctl_loop
 ioctl_loop-nv
 ioctl_loop-v
 ioctl_mtd
+ioctl_nbd
 ioctl_nsfs
 ioctl_perf
 ioctl_perf-success
index 16638970d5fb43e62864fbe254c828e4401cd0b0..cd63788d8893d0d7d31fcc62348444f844a25933 100644 (file)
@@ -146,6 +146,7 @@ ioctl_loop  +ioctl.test
 ioctl_loop-nv  +ioctl.test -a22 -e verbose=none
 ioctl_loop-v   +ioctl.test -v
 ioctl_mtd      +ioctl.test
+ioctl_nbd      +ioctl.test -y
 ioctl_nsfs     +ioctl.test -esignal=none
 ioctl_perf     +ioctl.test
 ioctl_ptp      +ioctl.test
diff --git a/tests/ioctl_nbd.c b/tests/ioctl_nbd.c
new file mode 100644 (file)
index 0000000..7daeec4
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2018 The strace developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/nbd.h>
+
+#define XLAT_MACROS_ONLY
+# include "xlat/nbd_ioctl_cmds.h"
+# include "xlat/nbd_ioctl_flags.h"
+#undef XLAT_MACROS_ONLY
+
+#define RVAL_EBADF " = -1 EBADF (%m)\n"
+
+int
+main(void)
+{
+       static const unsigned long ubeef = (unsigned long) 0xcafef00ddeadbeefULL;
+       static const char null_path[] = "/dev/null";
+
+       int fd = open(null_path, O_RDONLY);
+       if (fd < 0)
+               perror_msg_and_fail("open(\"%s\")", null_path);
+
+       skip_if_unavailable("/proc/self/fd/");
+
+       ioctl(-1, NBD_DISCONNECT, NULL);
+       printf("ioctl(-1, NBD_DISCONNECT)" RVAL_EBADF);
+       ioctl(-1, NBD_CLEAR_SOCK, NULL);
+       printf("ioctl(-1, NBD_CLEAR_SOCK)" RVAL_EBADF);
+       ioctl(-1, NBD_DO_IT, NULL);
+       printf("ioctl(-1, NBD_DO_IT)" RVAL_EBADF);
+       ioctl(-1, NBD_CLEAR_QUE, NULL);
+       printf("ioctl(-1, NBD_CLEAR_QUE)" RVAL_EBADF);
+       ioctl(-1, NBD_PRINT_DEBUG, NULL);
+       printf("ioctl(-1, NBD_PRINT_DEBUG)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_SOCK, fd);
+       printf("ioctl(-1, NBD_SET_SOCK, %d</dev/null>)" RVAL_EBADF, fd);
+
+       ioctl(-1, NBD_SET_BLKSIZE, ubeef);
+       printf("ioctl(-1, NBD_SET_BLKSIZE, %lu)" RVAL_EBADF, ubeef);
+       ioctl(-1, NBD_SET_SIZE, ubeef);
+       printf("ioctl(-1, NBD_SET_SIZE, %lu)" RVAL_EBADF, ubeef);
+       ioctl(-1, NBD_SET_SIZE_BLOCKS, ubeef);
+       printf("ioctl(-1, NBD_SET_SIZE_BLOCKS, %lu)" RVAL_EBADF, ubeef);
+
+       ioctl(-1, NBD_SET_TIMEOUT, ubeef);
+       printf("ioctl(-1, NBD_SET_TIMEOUT, %lu)" RVAL_EBADF, ubeef);
+
+       ioctl(-1, NBD_SET_FLAGS, 0);
+       printf("ioctl(-1, NBD_SET_FLAGS, 0)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_HAS_FLAGS);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_HAS_FLAGS)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_READ_ONLY);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_READ_ONLY)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_FLUSH);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_FLUSH)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_FUA);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_FUA)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_WRITE_ZEROES);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_WRITE_ZEROES)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_DF);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_DF)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_CAN_MULTI_CONN);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_CAN_MULTI_CONN)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_RESIZE);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_RESIZE)" RVAL_EBADF);
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_CACHE);
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_SEND_CACHE)" RVAL_EBADF);
+
+       ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_HAS_FLAGS|NBD_FLAG_READ_ONLY|
+                                NBD_FLAG_SEND_FUA|NBD_FLAG_SEND_CACHE|
+                                (1 << 15)|(1<<31));
+       printf("ioctl(-1, NBD_SET_FLAGS, NBD_FLAG_HAS_FLAGS|NBD_FLAG_READ_ONLY|"
+              "NBD_FLAG_SEND_FUA|NBD_FLAG_SEND_CACHE|0x80008000)" RVAL_EBADF);
+
+       ioctl(-1, _IOC(_IOC_NONE, 0xab, 0xb, 0), NULL);
+       printf("ioctl(-1, _IOC(_IOC_NONE, 0xab, 0xb, 0), 0)" RVAL_EBADF);
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
index 361984aa5de28a98bccd8644da8b6e16d5431179..69097bfb0955038ae24b7efdc2720fca0e2afa3a 100755 (executable)
@@ -118,6 +118,7 @@ ioctl_kvm_run-v
 ioctl_kvm_run_auxstr_vcpu
 ioctl_loop
 ioctl_mtd
+ioctl_nbd
 ioctl_perf
 ioctl_ptp
 ioctl_rtc
diff --git a/xlat/nbd_ioctl_cmds.in b/xlat/nbd_ioctl_cmds.in
new file mode 100644 (file)
index 0000000..34f891e
--- /dev/null
@@ -0,0 +1,11 @@
+NBD_SET_SOCK           _IO( 0xab, 0 )
+NBD_SET_BLKSIZE                _IO( 0xab, 1 )
+NBD_SET_SIZE           _IO( 0xab, 2 )
+NBD_DO_IT              _IO( 0xab, 3 )
+NBD_CLEAR_SOCK         _IO( 0xab, 4 )
+NBD_CLEAR_QUE          _IO( 0xab, 5 )
+NBD_PRINT_DEBUG                _IO( 0xab, 6 )
+NBD_SET_SIZE_BLOCKS    _IO( 0xab, 7 )
+NBD_DISCONNECT         _IO( 0xab, 8 )
+NBD_SET_TIMEOUT                _IO( 0xab, 9 )
+NBD_SET_FLAGS          _IO( 0xab, 10)
diff --git a/xlat/nbd_ioctl_flags.in b/xlat/nbd_ioctl_flags.in
new file mode 100644 (file)
index 0000000..60bb07f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Some flags are not defined in <linux/nbd.h>, but are passed anyway.
+ * These flags are sent from nbd-server to the client, and the client
+ * passes them to the kernel unmodified after parsing. Both the client
+ * and the kernel ignore flags unknown to them.
+ */
+
+/* The server supports flags */
+NBD_FLAG_HAS_FLAGS     (1 << 0)
+/* The export is read-only */
+NBD_FLAG_READ_ONLY     (1 << 1)
+/* The server supports NBD_CMD_FLUSH */
+NBD_FLAG_SEND_FLUSH    (1 << 2)
+/* The server supports NBD_CMD_FLAG_FUA (Force Unit Access) */
+NBD_FLAG_SEND_FUA      (1 << 3)
+/* The export is a rotational medium */
+NBD_FLAG_ROTATIONAL    (1 << 4)
+/* The server supports NBD_CMD_TRIM */
+NBD_FLAG_SEND_TRIM     (1 << 5)
+/* The server supports NBD_CMD_WRITE_ZEROES and NBD_CMD_FLAG_NO_HOLE */
+NBD_FLAG_SEND_WRITE_ZEROES     (1 << 6)
+/* The server supports NBD_CMD_FLAG_DF (don't fragment replies) */
+NBD_FLAG_SEND_DF       (1 << 7)
+/* The server supports multiple connections */
+NBD_FLAG_CAN_MULTI_CONN        (1 << 8)
+/* The server supports NBD_CMD_RESIZE (resizing the device) */
+NBD_FLAG_SEND_RESIZE   (1 << 9)
+/* The server supports NBD_CMD_CACHE */
+NBD_FLAG_SEND_CACHE    (1 << 10)