]> granicus.if.org Git - zfs/commitdiff
OpenZFS 7280 - Allow changing global libzpool variables in zdb and ztest through...
authorGeorge Melikov <mail@gmelikov.ru>
Tue, 31 Jan 2017 18:13:10 +0000 (21:13 +0300)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 Jan 2017 18:13:10 +0000 (10:13 -0800)
Authored by: Pavel Zakharov <pavel.zakharov@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Ported-by: George Melikov <mail@gmelikov.ru>
OpenZFS-issue: https://www.illumos.org/issues/7280
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/0e60744
Closes #5676

cmd/zdb/zdb.c
cmd/ztest/ztest.c
include/sys/zfs_context.h
lib/libzpool/Makefile.am
lib/libzpool/util.c
man/man8/zdb.8

index 6a36aa1ef94f55e89b983fe865618f546b4ee92f..10bca4a91987a9ff98708a556588e167d7bc35a0 100644 (file)
@@ -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;
index 70a3e206f6ea916ee0fd09517b2a0f6d09d5ef84..d1c6a783aebde05e7a86a72bc67725a868fcb00b 100644 (file)
@@ -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;
index bca89e1c954f538920ae1190fa9421c8476f03a8..b4f63e19c40f676eee98c57090e74052f23eccfd 100644 (file)
  * 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;
index 40c46028432986cf829be0ab57f3d746e6c0d6d6..1e95f8064c8f08d71b5d18c1da4bda6fd2ccb540 100644 (file)
@@ -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)
index bc3bcbe78e510fad07a0db8d6b7a302b59c5bbaf..3bdc3172298117ba835d3adc82252d9845313ef2 100644 (file)
@@ -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);
+}
index 271e512d5eed9b47f2445d41b59fd8214ad6bb77..6696a2fe028ba38c1fab9b6fa017509d8b7a676d 100644 (file)
@@ -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