summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Melikov <[email protected]>2017-01-31 21:13:10 +0300
committerBrian Behlendorf <[email protected]>2017-01-31 10:13:10 -0800
commited828c0c375477ff27d5fa9a7bf46ae6b6f2e57a (patch)
tree09347b9e65fb56cd28afbe2ac3b1e29f0d175bc0
parent41425f79dabc58e5ddb16cc701cc435a5480e56a (diff)
OpenZFS 7280 - Allow changing global libzpool variables in zdb and ztest through command line
Authored by: Pavel Zakharov <[email protected]> Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Dan Kimmel <[email protected]> Approved by: Robert Mustacchi <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Ported-by: George Melikov <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/7280 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/0e60744 Closes #5676
-rw-r--r--cmd/zdb/zdb.c18
-rw-r--r--cmd/ztest/ztest.c8
-rw-r--r--include/sys/zfs_context.h10
-rw-r--r--lib/libzpool/Makefile.am2
-rw-r--r--lib/libzpool/util.c57
-rw-r--r--man/man8/zdb.814
6 files changed, 95 insertions, 14 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 6a36aa1ef..10bca4a91 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 70a3e206f..d1c6a783a 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 bca89e1c9..b4f63e19c 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 40c460284..1e95f8064 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 bc3bcbe78..3bdc31722 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 271e512d5..6696a2fe0 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]
@@ -423,6 +423,18 @@ option.
.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
\fB-P\fR
.ad
.sp .6