[PATCH v5] Handle OpenZFS ioctls

наб nabijaczleweli at gmail.com
Fri Feb 19 20:31:20 UTC 2021


Before/after of strace zfs list:
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x4, 0), 0x7ffe7f41e3b0) = 0
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x12, 0), 0x7ffe7f41e3c0) = 0
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x5, 0), 0x7ffe7f41ad30) = 0
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x27, 0), 0x7ffe7f41e320) = 0
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x14, 0), 0x7ffe7f41e370) = 0
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x14, 0), 0x7ffe7f41ad30) = -1 ESRCH (No such process)
+ioctl(3, ZFS_IOC_POOL_CONFIGS, 0x7ffffae160c0) = 0
+ioctl(3, ZFS_IOC_OBJSET_STATS, 0x7ffffae160d0) = 0
+ioctl(3, ZFS_IOC_POOL_STATS, 0x7ffffae12a40) = 0
+ioctl(3, ZFS_IOC_POOL_GET_PROPS, 0x7ffffae16030) = 0
+ioctl(3, ZFS_IOC_DATASET_LIST_NEXT, 0x7ffffae16080) = 0
+ioctl(3, ZFS_IOC_DATASET_LIST_NEXT, 0x7ffffae12a40) = -1 ESRCH (No such process)
-ioctl(3, _IOC(_IOC_NONE, 0x5a, 0x3f, 0), 0x7ffe7f41e5b0) = -1 EPERM (Operation not permitted)
+ioctl(3, ZFS_IOC_LOG_HISTORY, 0x7ffffae162c0) = -1 EPERM (Operation not permitted)

Before/after of strace zfs/cmd/zvol_id/zvol_id /dev/zd0:
-ioctl(3, _IOC(_IOC_READ, 0x12, 0x7d, 0x100), 0x7fffa7776e20) = 0
+ioctl(3, BLKZNAME, 0x7ffe02f435b0)      = 0

* maint/extract_zfs.sh: New file.
* src/ioctls_zfs.h: New file.
* ioctlsort.c: Always include ioctls_zfs.h,
as it's personality-independent
* tests/ioctl.c: Test a few ZFS ioctls.
---
For some reason I took your suggestion and samples very literally
and got very defensive about it, for which I can only apologise.

This gets rid of the AWK script and replaces it with two small sed ones,
which are, indeed, cleaner for this (and were a good way to get into
non-trivial sed scripts, so thanks for that as well).

 maint/extract_zfs.sh | 57 ++++++++++++++++++++++++++
 src/ioctls_zfs.h     | 98 ++++++++++++++++++++++++++++++++++++++++++++
 src/ioctlsort.c      |  2 +
 tests/ioctl.c        | 16 ++++++++
 4 files changed, 173 insertions(+)
 create mode 100755 maint/extract_zfs.sh
 create mode 100644 src/ioctls_zfs.h

diff --git a/maint/extract_zfs.sh b/maint/extract_zfs.sh
new file mode 100755
index 00000000..1d0960b1
--- /dev/null
+++ b/maint/extract_zfs.sh
@@ -0,0 +1,57 @@
+#!/bin/sh -e
+#
+# Scrape out ioctls from an OpenZFS tree.
+# This should only be needed for getting new definitions,
+# since OpenZFS is committed to this ABI.
+#
+# Copyright (c) 2021 The strace developers.
+# All rights reserved
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+[ -z "$1" ] && {
+	echo "Usage: $0 <path to OpenZFS clone>" >&2
+	exit 1
+}
+
+cleanup() {
+	trap - EXIT
+	rm -f "$source" "$executable"
+	exit "$@"
+}
+
+trap 'cleanup $?' EXIT
+trap 'cleanup 1' HUP PIPE INT QUIT TERM
+
+source="$(mktemp --suffix .c)"
+executable="$(mktemp)"
+ZVER="$(sed '/^Version:[[:space:]]*/!d;s///;q' "$1/META")"
+
+cd "$1"
+
+{
+	cat <<EOF
+#include <stdio.h>
+#include <include/sys/fs/zfs.h>
+#include <lib/libspl/include/sys/kstat.h>
+int main() {
+EOF
+	{
+		sed -Ene 's/^[[:space:]]*(ZFS_IOC_[^,[:space:]]+).*/\1/' \
+		      -e 'T;/(FIRST|LAST|PLATFORM)$/d;p;i include/sys/fs/zfs.h' \
+		         include/sys/fs/zfs.h
+		sed -Ene 's/^#define[[:space:]]+(KSTAT_IOC_[^[:space:]]+).*/\1/' \
+		      -e 'T;/BASE$/d;p;i lib/libspl/include/sys/kstat.h' \
+		         lib/libspl/include/sys/kstat.h
+	} | while read -r ioctl && read -r filename; do
+		echo '	printf("{ \"'"$filename"'\", \"'"$ioctl"'\", "'
+		echo '	       "0, 0x%04X, 0 },\\n", '"$ioctl"');'
+	done
+	echo '}'
+} > "$source"
+
+cc -I . -isystem include -isystem lib/libspl/include "$source" -o "$executable"
+
+echo "/* Generated by extract_zfs.sh from OpenZFS version $ZVER */"
+echo '{ "include/sys/fs/zfs.h", "BLKZNAME", _IOC_READ, (0x12 << 8) | 125, 256 },'
+"$executable"
diff --git a/src/ioctls_zfs.h b/src/ioctls_zfs.h
new file mode 100644
index 00000000..ec15390c
--- /dev/null
+++ b/src/ioctls_zfs.h
@@ -0,0 +1,98 @@
+/* Generated by extract_zfs.sh from OpenZFS version 2.0.3 */
+{ "include/sys/fs/zfs.h", "BLKZNAME", _IOC_READ, (0x12 << 8) | 125, 256 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_CREATE", 0, 0x5A00, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_DESTROY", 0, 0x5A01, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_IMPORT", 0, 0x5A02, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_EXPORT", 0, 0x5A03, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_CONFIGS", 0, 0x5A04, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_STATS", 0, 0x5A05, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_TRYIMPORT", 0, 0x5A06, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_SCAN", 0, 0x5A07, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_FREEZE", 0, 0x5A08, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_UPGRADE", 0, 0x5A09, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_GET_HISTORY", 0, 0x5A0A, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_ADD", 0, 0x5A0B, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_REMOVE", 0, 0x5A0C, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_SET_STATE", 0, 0x5A0D, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_ATTACH", 0, 0x5A0E, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_DETACH", 0, 0x5A0F, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_SETPATH", 0, 0x5A10, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_SETFRU", 0, 0x5A11, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_OBJSET_STATS", 0, 0x5A12, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_OBJSET_ZPLPROPS", 0, 0x5A13, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DATASET_LIST_NEXT", 0, 0x5A14, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SNAPSHOT_LIST_NEXT", 0, 0x5A15, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SET_PROP", 0, 0x5A16, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CREATE", 0, 0x5A17, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DESTROY", 0, 0x5A18, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_ROLLBACK", 0, 0x5A19, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_RENAME", 0, 0x5A1A, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_RECV", 0, 0x5A1B, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SEND", 0, 0x5A1C, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_INJECT_FAULT", 0, 0x5A1D, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CLEAR_FAULT", 0, 0x5A1E, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_INJECT_LIST_NEXT", 0, 0x5A1F, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_ERROR_LOG", 0, 0x5A20, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CLEAR", 0, 0x5A21, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_PROMOTE", 0, 0x5A22, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SNAPSHOT", 0, 0x5A23, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DSOBJ_TO_DSNAME", 0, 0x5A24, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_OBJ_TO_PATH", 0, 0x5A25, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_SET_PROPS", 0, 0x5A26, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_GET_PROPS", 0, 0x5A27, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SET_FSACL", 0, 0x5A28, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_GET_FSACL", 0, 0x5A29, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SHARE", 0, 0x5A2A, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_INHERIT_PROP", 0, 0x5A2B, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SMB_ACL", 0, 0x5A2C, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_USERSPACE_ONE", 0, 0x5A2D, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_USERSPACE_MANY", 0, 0x5A2E, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_USERSPACE_UPGRADE", 0, 0x5A2F, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_HOLD", 0, 0x5A30, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_RELEASE", 0, 0x5A31, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_GET_HOLDS", 0, 0x5A32, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_OBJSET_RECVD_PROPS", 0, 0x5A33, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_VDEV_SPLIT", 0, 0x5A34, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_NEXT_OBJ", 0, 0x5A35, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DIFF", 0, 0x5A36, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_TMP_SNAPSHOT", 0, 0x5A37, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_OBJ_TO_STATS", 0, 0x5A38, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SPACE_WRITTEN", 0, 0x5A39, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SPACE_SNAPS", 0, 0x5A3A, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DESTROY_SNAPS", 0, 0x5A3B, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_REGUID", 0, 0x5A3C, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_REOPEN", 0, 0x5A3D, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SEND_PROGRESS", 0, 0x5A3E, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_LOG_HISTORY", 0, 0x5A3F, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SEND_NEW", 0, 0x5A40, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SEND_SPACE", 0, 0x5A41, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CLONE", 0, 0x5A42, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_BOOKMARK", 0, 0x5A43, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_GET_BOOKMARKS", 0, 0x5A44, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_DESTROY_BOOKMARKS", 0, 0x5A45, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_RECV_NEW", 0, 0x5A46, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_SYNC", 0, 0x5A47, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CHANNEL_PROGRAM", 0, 0x5A48, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_LOAD_KEY", 0, 0x5A49, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_UNLOAD_KEY", 0, 0x5A4A, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_CHANGE_KEY", 0, 0x5A4B, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_REMAP", 0, 0x5A4C, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_CHECKPOINT", 0, 0x5A4D, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_DISCARD_CHECKPOINT", 0, 0x5A4E, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_INITIALIZE", 0, 0x5A4F, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_POOL_TRIM", 0, 0x5A50, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_REDACT", 0, 0x5A51, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_GET_BOOKMARK_PROPS", 0, 0x5A52, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_WAIT", 0, 0x5A53, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_WAIT_FS", 0, 0x5A54, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_EVENTS_NEXT", 0, 0x5A81, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_EVENTS_CLEAR", 0, 0x5A82, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_EVENTS_SEEK", 0, 0x5A83, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_NEXTBOOT", 0, 0x5A84, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_JAIL", 0, 0x5A85, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_UNJAIL", 0, 0x5A86, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_SET_BOOTENV", 0, 0x5A87, 0 },
+{ "include/sys/fs/zfs.h", "ZFS_IOC_GET_BOOTENV", 0, 0x5A88, 0 },
+{ "lib/libspl/include/sys/kstat.h", "KSTAT_IOC_CHAIN_ID", 0, 0x4B01, 0 },
+{ "lib/libspl/include/sys/kstat.h", "KSTAT_IOC_READ", 0, 0x4B02, 0 },
+{ "lib/libspl/include/sys/kstat.h", "KSTAT_IOC_WRITE", 0, 0x4B03, 0 },
diff --git a/src/ioctlsort.c b/src/ioctlsort.c
index 65166576..8095fbba 100644
--- a/src/ioctlsort.c
+++ b/src/ioctlsort.c
@@ -135,6 +135,8 @@ static struct ioctlent ioctls[] = {
 # include "ioctls_arch.h"
 # include "ioctls_inc.h"
 #endif
+
+#include "ioctls_zfs.h"
 };
 
 int
diff --git a/tests/ioctl.c b/tests/ioctl.c
index 0ce73f0c..1a85c394 100644
--- a/tests/ioctl.c
+++ b/tests/ioctl.c
@@ -80,6 +80,22 @@ main(void)
 	printf("ioctl(-1, _IOC(_IOC_READ, 0xde, 0xad, 0x8), %p)"
 	       " = -1 EBADF (%m)\n", &data);
 
+	(void) ioctl(-1, 'Z' << 8, &data);
+	printf("ioctl(-1, ZFS_IOC_POOL_CREATE, %p)"
+	       " = -1 EBADF (%m)\n", &data);
+
+	(void) ioctl(-1, 'Z' << 8 | 'A', &data);
+	printf("ioctl(-1, ZFS_IOC_SEND_SPACE, %p)"
+	       " = -1 EBADF (%m)\n", &data);
+
+	(void) ioctl(-1, _IOR(0x12, 125, char[256]), &data);
+	printf("ioctl(-1, BLKZNAME, %p)"
+	       " = -1 EBADF (%m)\n", &data);
+
+	(void) ioctl(-1, ('K' << 8) + 1, &data);
+	printf("ioctl(-1, KSTAT_IOC_CHAIN_ID, %p)"
+	       " = -1 EBADF (%m)\n", &data);
+
 	puts("+++ exited with 0 +++");
 	return 0;
 }
-- 
2.20.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20210219/af76008d/attachment.bin>


More information about the Strace-devel mailing list