aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2013-03-01 09:42:58 +0000
committerMartin Matuska <mm@FreeBSD.org>2013-03-01 09:42:58 +0000
commitbb508e7732e285bcce70a43c900c58ee16e3c465 (patch)
tree6a0f6613d26f6954346147f7c33ceb0283ec85d9 /cddl/contrib/opensolaris
parent99c899985653fe4b9bef31d01c2b6bc4a0a5995f (diff)
downloadsrc-bb508e7732e285bcce70a43c900c58ee16e3c465.tar.gz
src-bb508e7732e285bcce70a43c900c58ee16e3c465.zip
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
Notes
Notes: svn path=/head/; revision=247540
Diffstat (limited to 'cddl/contrib/opensolaris')
-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 1c46d32f4bab..be07187f9d5e 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);