summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-03-01 09:42:58 +0000
committermm <mm@FreeBSD.org>2013-03-01 09:42:58 +0000
commite653c470f763b4dff0b51050c92e379b1ff3f646 (patch)
tree6a0f6613d26f6954346147f7c33ceb0283ec85d9 /cddl
parent9ecef62d739ff26f081c6ce4d79c74c293ba9fee (diff)
downloadFreeBSD-src-e653c470f763b4dff0b51050c92e379b1ff3f646.zip
FreeBSD-src-e653c470f763b4dff0b51050c92e379b1ff3f646.tar.gz
Fix the zfs_ioctl compat layer to support zfs_cmd size change introduced
in r247265 (ZFS deadman thread). Both new utilities now support the old kernel and new kernel properly detects old utilities. For future backwards compatibility, the vfs.zfs.version.ioctl read-only sysctl has been introduced. With this sysctl zfs utilities will be able to detect the ioctl interface version of the currently loaded zfs module. As a side effect, the zfs utilities between r247265 and this revision don't support the old kernel module. If you are using HEAD newer or equal than r247265, install the new kernel module (or whole kernel) first. MFC after: 10 days
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h35
1 files changed, 26 insertions, 9 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
index 1c46d32..be07187 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h
@@ -24,6 +24,7 @@
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
#ifndef _LIBFS_IMPL_H
@@ -216,6 +217,7 @@ extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
#ifndef sun
static int zfs_kernel_version = 0;
+static int zfs_ioctl_version = 0;
/*
* This is FreeBSD version of ioctl, because Solaris' ioctl() updates
@@ -225,19 +227,34 @@ static int zfs_kernel_version = 0;
static __inline int
zcmd_ioctl(int fd, unsigned long cmd, zfs_cmd_t *zc)
{
- size_t oldsize, zfs_kernel_version_size;
+ size_t oldsize, zfs_kernel_version_size, zfs_ioctl_version_size;
int version, ret, cflag = ZFS_CMD_COMPAT_NONE;
- zfs_kernel_version_size = sizeof(zfs_kernel_version);
- if (zfs_kernel_version == 0) {
- sysctlbyname("vfs.zfs.version.spa", &zfs_kernel_version,
- &zfs_kernel_version_size, NULL, 0);
+ zfs_ioctl_version_size = sizeof(zfs_ioctl_version);
+ if (zfs_ioctl_version == 0) {
+ sysctlbyname("vfs.zfs.version.ioctl", &zfs_ioctl_version,
+ &zfs_ioctl_version_size, NULL, 0);
}
- if (zfs_kernel_version == SPA_VERSION_15 ||
- zfs_kernel_version == SPA_VERSION_14 ||
- zfs_kernel_version == SPA_VERSION_13)
- cflag = ZFS_CMD_COMPAT_V15;
+ /*
+ * If vfs.zfs.version.ioctl is not defined, assume we have v28
+ * compatible binaries and use vfs.zfs.version.spa to test for v15
+ */
+ if (zfs_ioctl_version < ZFS_IOCVER_DEADMAN) {
+ cflag = ZFS_CMD_COMPAT_V28;
+ zfs_kernel_version_size = sizeof(zfs_kernel_version);
+
+ if (zfs_kernel_version == 0) {
+ sysctlbyname("vfs.zfs.version.spa",
+ &zfs_kernel_version,
+ &zfs_kernel_version_size, NULL, 0);
+ }
+
+ if (zfs_kernel_version == SPA_VERSION_15 ||
+ zfs_kernel_version == SPA_VERSION_14 ||
+ zfs_kernel_version == SPA_VERSION_13)
+ cflag = ZFS_CMD_COMPAT_V15;
+ }
oldsize = zc->zc_nvlist_dst_size;
ret = zcmd_ioctl_compat(fd, cmd, zc, cflag);
OpenPOWER on IntegriCloud