diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 6a36aa1ef94f..10bca4a91987 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -127,7 +127,8 @@ usage(void)
 {
 	(void) fprintf(stderr,
 	    "Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
-	    "[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n"
+	    "[-U config] [-I inflight I/Os] [-x dumpdir] [-o var=value] "
+	    "poolname [object...]\n"
 	    "       %s [-divPA] [-e -p path...] [-U config] dataset "
 	    "[object...]\n"
 	    "       %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
@@ -189,6 +190,8 @@ usage(void)
 	    "checksumming I/Os [default is 200]\n");
 	(void) fprintf(stderr, "        -G dump zfs_dbgmsg buffer before "
 	    "exiting\n");
+	(void) fprintf(stderr, "        -o <variable>=<value> set global "
+	    "variable to an unsigned 32-bit integer value\n");
 	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
 	    "to make only that option verbose\n");
 	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
@@ -3707,7 +3710,7 @@ main(int argc, char **argv)
 		spa_config_path = spa_config_path_env;
 
 	while ((c = getopt(argc, argv,
-	    "bcdhilmMI:suCDRSAFLXx:evp:t:U:PVG")) != -1) {
+	    "bcdhilmMI:suCDRSAFLXx:evp:t:U:PVGo")) != -1) {
 		switch (c) {
 		case 'b':
 		case 'c':
@@ -3762,9 +3765,6 @@ main(int argc, char **argv)
 			}
 			searchdirs[nsearch++] = optarg;
 			break;
-		case 'x':
-			vn_dumpdir = optarg;
-			break;
 		case 't':
 			max_txg = strtoull(optarg, NULL, 0);
 			if (max_txg < TXG_INITIAL) {
@@ -3779,6 +3779,14 @@ main(int argc, char **argv)
 		case 'v':
 			verbose++;
 			break;
+		case 'x':
+			vn_dumpdir = optarg;
+			break;
+		case 'o':
+			error = set_global_var(optarg);
+			if (error != 0)
+				usage();
+			break;
 		default:
 			usage();
 			break;
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index 70a3e206f6ea..d1c6a783aebd 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -629,6 +629,8 @@ usage(boolean_t requested)
 	    "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
 	    "\t[-P passtime (default: %llu sec)] time per pass\n"
 	    "\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
+	    "\t[-o variable=value] ... set global variable to an unsigned\n"
+	    "\t    32-bit integer value\n"
 	    "\t[-h] (print help)\n"
 	    "",
 	    zo->zo_pool,
@@ -664,7 +666,7 @@ process_options(int argc, char **argv)
 	bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
 
 	while ((opt = getopt(argc, argv,
-	    "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
+	    "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:o:")) != EOF) {
 		value = 0;
 		switch (opt) {
 		case 'v':
@@ -752,6 +754,10 @@ process_options(int argc, char **argv)
 		case 'B':
 			(void) strlcpy(altdir, optarg, sizeof (altdir));
 			break;
+		case 'o':
+			if (set_global_var(optarg) != 0)
+				usage(B_FALSE);
+			break;
 		case 'h':
 			usage(B_TRUE);
 			break;
diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h
index bca89e1c954f..b4f63e19c40f 100644
--- a/include/sys/zfs_context.h
+++ b/include/sys/zfs_context.h
@@ -19,13 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_ZFS_CONTEXT_H
@@ -695,6 +692,7 @@ extern void random_fini(void);
 struct spa;
 extern void nicenum(uint64_t num, char *buf);
 extern void show_pool_stats(struct spa *);
+extern int set_global_var(char *arg);
 
 typedef struct callb_cpr {
 	kmutex_t	*cc_lockp;
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am
index 40c460284329..1e95f8064c8f 100644
--- a/lib/libzpool/Makefile.am
+++ b/lib/libzpool/Makefile.am
@@ -140,7 +140,7 @@ libzpool_la_LIBADD = \
 	$(top_builddir)/lib/libnvpair/libnvpair.la \
 	$(top_builddir)/lib/libicp/libicp.la
 
-libzpool_la_LIBADD += $(ZLIB)
+libzpool_la_LIBADD += $(ZLIB) -ldl
 libzpool_la_LDFLAGS = -version-info 2:0:0
 
 EXTRA_DIST = $(USER_C)
diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c
index bc3bcbe78e51..3bdc31722981 100644
--- a/lib/libzpool/util.c
+++ b/lib/libzpool/util.c
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 by Delphix. All rights reserved.
  */
 
 #include <assert.h>
@@ -31,6 +32,7 @@
 #include <sys/spa.h>
 #include <sys/fs/zfs.h>
 #include <sys/refcount.h>
+#include <dlfcn.h>
 
 /*
  * Routines needed by more than one client of libzpool.
@@ -158,3 +160,58 @@ show_pool_stats(spa_t *spa)
 
 	nvlist_free(config);
 }
+
+/*
+ * Sets given global variable in libzpool to given unsigned 32-bit value.
+ * arg: "<variable>=<value>"
+ */
+int
+set_global_var(char *arg)
+{
+	void *zpoolhdl;
+	char *varname = arg, *varval;
+	u_longlong_t val;
+
+#ifndef _LITTLE_ENDIAN
+	/*
+	 * On big endian systems changing a 64-bit variable would set the high
+	 * 32 bits instead of the low 32 bits, which could cause unexpected
+	 * results.
+	 */
+	fprintf(stderr, "Setting global variables is only supported on "
+	    "little-endian systems\n");
+	return (ENOTSUP);
+#endif
+	if ((varval = strchr(arg, '=')) != NULL) {
+		*varval = '\0';
+		varval++;
+		val = strtoull(varval, NULL, 0);
+		if (val > UINT32_MAX) {
+			fprintf(stderr, "Value for global variable '%s' must "
+			    "be a 32-bit unsigned integer\n", varname);
+			return (EOVERFLOW);
+		}
+	} else {
+		return (EINVAL);
+	}
+
+	zpoolhdl = dlopen("libzpool.so", RTLD_LAZY);
+	if (zpoolhdl != NULL) {
+		uint32_t *var;
+		var = dlsym(zpoolhdl, varname);
+		if (var == NULL) {
+			fprintf(stderr, "Global variable '%s' does not exist "
+			    "in libzpool.so\n", varname);
+			return (EINVAL);
+		}
+		*var = (uint32_t)val;
+
+		dlclose(zpoolhdl);
+	} else {
+		fprintf(stderr, "Failed to open libzpool.so to set global "
+		    "variable\n");
+		return (EIO);
+	}
+
+	return (0);
+}
diff --git a/man/man8/zdb.8 b/man/man8/zdb.8
index 271e512d5eed..6696a2fe028b 100644
--- a/man/man8/zdb.8
+++ b/man/man8/zdb.8
@@ -21,7 +21,7 @@
 .SH "SYNOPSIS"
 \fBzdb\fR [-CumdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
     [-U \fIcache\fR] [-I \fIinflight I/Os\fR] [-x \fIdumpdir\fR]
-    [\fIpoolname\fR [\fIobject\fR ...]]
+    [-o \fIvar\fR=\fIvalue\fR] ... [\fIpoolname\fR [\fIobject\fR ...]]
 
 .P
 \fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] [-U \fIcache\fR]
@@ -420,6 +420,18 @@ default value is 200. This option affects the performance of the \fB-c\fR
 option.
 .RE
 
+.sp
+.ne 2
+.na
+\fB-o \fIvar\fR=\fIvalue\fR ... \fR
+.ad
+.sp .6
+.RS 4n
+Set the given global libzpool variable to the provided value. The value must
+be an unsigned 32-bit integer. Currently only little-endian systems are
+supported to avoid accidentally setting the high 32 bits of 64-bit variables.
+.RE
+
 .sp
 .ne 2
 .na