summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2020-07-08 11:35:01 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2020-07-08 11:35:01 +0000
commitb97f5b09ef2e4af27e3cc4addd8abe5fc7c4d817 (patch)
tree26a516b2251314578cd471a7293f6d36cdd798a8 /usr/src/lib
parent500c01a56730addd2b2a8a00fef7ce205769f05a (diff)
parentf4f9009fc79529ef8f45e7a31acd2ce4ca86a276 (diff)
downloadillumos-joyent-b97f5b09ef2e4af27e3cc4addd8abe5fc7c4d817.tar.gz
[illumos-gate merge]
commit f4f9009fc79529ef8f45e7a31acd2ce4ca86a276 12912 epoll mishandles excessive timeout negativity commit be9c3adb90f4f745cf5c07f3c0dbdd6c9028cda0 12926 libstand: add missing iscntrl() isgraph() and ispunct() commit 7ac89354c798225fea6296348415955ccd95fb80 12877 Port OpenZFS #7780 - Add basic zfs ioc input nvpair validation 12895 zfs_onexit_fd_hold fails to release non-zfs fds commit 6f0673af8764c356a5bd511fc7ca8af579fe2000 12810 usr/src/tools/opensolaris contents are unused commit 086d96878f5f62a25a6d90e5b03a1ef9ba352231 12909 epoll should better detect fd reassignment Conflicts: usr/src/uts/common/sys/user.h
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libzfs/common/libzfs.h3
-rw-r--r--usr/src/lib/libzfs/common/libzfs_util.c37
-rw-r--r--usr/src/lib/libzfs_core/common/libzfs_core.c50
3 files changed, 87 insertions, 3 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h
index 8d14d37866..bdc24ac6ef 100644
--- a/usr/src/lib/libzfs/common/libzfs.h
+++ b/usr/src/lib/libzfs/common/libzfs.h
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 Pawel Jakub Dawidek. All rights reserved.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright 2020 Joyent, Inc.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
@@ -147,6 +147,7 @@ typedef enum zfs_error {
EZFS_NO_TRIM, /* no active trim */
EZFS_TRIM_NOTSUP, /* device does not support trim */
EZFS_NO_RESILVER_DEFER, /* pool doesn't support resilver_defer */
+ EZFS_IOC_NOTSUPPORTED, /* operation not supported by zfs module */
EZFS_UNKNOWN
} zfs_error_t;
diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c
index c3cf11a897..3ccefa5585 100644
--- a/usr/src/lib/libzfs/common/libzfs_util.c
+++ b/usr/src/lib/libzfs/common/libzfs_util.c
@@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2020 Joyent, Inc.
- * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2017 Datto Inc.
*/
@@ -205,6 +205,9 @@ libzfs_error_description(libzfs_handle_t *hdl)
case EZFS_NOTSUP:
return (dgettext(TEXT_DOMAIN, "operation not supported "
"on this dataset"));
+ case EZFS_IOC_NOTSUPPORTED:
+ return (dgettext(TEXT_DOMAIN, "operation not supported by "
+ "zfs kernel module"));
case EZFS_ACTIVE_SPARE:
return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
"device"));
@@ -442,6 +445,22 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
case EREMOTEIO:
zfs_verror(hdl, EZFS_ACTIVE_POOL, fmt, ap);
break;
+ case ZFS_ERR_IOC_CMD_UNAVAIL:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
+ "module does not support this operation. A reboot may "
+ "be required to enable this operation."));
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
+ case ZFS_ERR_IOC_ARG_UNAVAIL:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
+ "module does not support an option for this operation. "
+ "A reboot may be required to enable this option."));
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
+ case ZFS_ERR_IOC_ARG_REQUIRED:
+ case ZFS_ERR_IOC_ARG_BADTYPE:
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
default:
zfs_error_aux(hdl, strerror(error));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
@@ -547,6 +566,22 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
case ZFS_ERR_VDEV_TOO_BIG:
zfs_verror(hdl, EZFS_VDEV_TOO_BIG, fmt, ap);
break;
+ case ZFS_ERR_IOC_CMD_UNAVAIL:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
+ "module does not support this operation. A reboot may "
+ "be required to enable this operation."));
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
+ case ZFS_ERR_IOC_ARG_UNAVAIL:
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
+ "module does not support an option for this operation. "
+ "A reboot may be required to enable this option."));
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
+ case ZFS_ERR_IOC_ARG_REQUIRED:
+ case ZFS_ERR_IOC_ARG_BADTYPE:
+ zfs_verror(hdl, EZFS_IOC_NOTSUPPORTED, fmt, ap);
+ break;
default:
zfs_error_aux(hdl, strerror(error));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
diff --git a/usr/src/lib/libzfs_core/common/libzfs_core.c b/usr/src/lib/libzfs_core/common/libzfs_core.c
index 628b1cc8ff..31ffddd93f 100644
--- a/usr/src/lib/libzfs_core/common/libzfs_core.c
+++ b/usr/src/lib/libzfs_core/common/libzfs_core.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2018 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 RackTop Systems.
@@ -79,6 +79,9 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#ifdef ZFS_DEBUG
+#include <stdio.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
@@ -92,6 +95,42 @@ static int g_fd = -1;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
static int g_refcount;
+#ifdef ZFS_DEBUG
+static zfs_ioc_t fail_ioc_cmd;
+static zfs_errno_t fail_ioc_err;
+
+static void
+libzfs_core_debug_ioc(void)
+{
+ /*
+ * To test running newer user space binaries with kernel's
+ * that don't yet support an ioctl or a new ioctl arg we
+ * provide an override to intentionally fail an ioctl.
+ *
+ * USAGE:
+ * The override variable, ZFS_IOC_TEST, is of the form "cmd:err"
+ *
+ * For example, to fail a ZFS_IOC_POOL_CHECKPOINT with a
+ * ZFS_ERR_IOC_CMD_UNAVAIL, the string would be "0x5a4d:1029"
+ *
+ * $ sudo sh -c "ZFS_IOC_TEST=0x5a4d:1029 zpool checkpoint tank"
+ * cannot checkpoint 'tank': the loaded zfs module does not support
+ * this operation. A reboot may be required to enable this operation.
+ */
+ if (fail_ioc_cmd == 0) {
+ char *ioc_test = getenv("ZFS_IOC_TEST");
+ unsigned int ioc_num = 0, ioc_err = 0;
+
+ if (ioc_test != NULL &&
+ sscanf(ioc_test, "%i:%i", &ioc_num, &ioc_err) == 2 &&
+ ioc_num < ZFS_IOC_LAST) {
+ fail_ioc_cmd = ioc_num;
+ fail_ioc_err = ioc_err;
+ }
+ }
+}
+#endif
+
int
libzfs_core_init(void)
{
@@ -104,6 +143,10 @@ libzfs_core_init(void)
}
}
g_refcount++;
+
+#ifdef ZFS_DEBUG
+ libzfs_core_debug_ioc();
+#endif
(void) pthread_mutex_unlock(&g_lock);
return (0);
}
@@ -136,6 +179,11 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
ASSERT3S(g_refcount, >, 0);
VERIFY3S(g_fd, !=, -1);
+#ifdef ZFS_DEBUG
+ if (ioc == fail_ioc_cmd)
+ return (fail_ioc_err);
+#endif
+
if (name != NULL)
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));