svn commit: r326335 - in stable/10/cddl/contrib/opensolaris: cmd/zdb cmd/ztest lib/libzpool/common lib/libzpool/common/sys

Alan Somers asomers at FreeBSD.org
Tue Nov 28 18:36:00 UTC 2017


Author: asomers
Date: Tue Nov 28 18:35:58 2017
New Revision: 326335
URL: https://svnweb.freebsd.org/changeset/base/326335

Log:
  MFC r324220:
  
  MFC r316858 7280 Allow changing global libzpool variables in zdb
  
  7280 Allow changing global libzpool variables in zdb and ztest through command line
  
  illumos/illumos-gate at 0e60744c982adecd0a1f146f5637475d07ab1069
  https://github.com/illumos/illumos-gate/commit/0e60744c982adecd0a1f146f5637475d07ab1069
  
  https://www.illumos.org/issues/7280
    zdb is very handy for diagnosing problems with a pool in a safe and
    quick way. When a pool is in a bad shape, we often want to disable some
    fail-safes, or adjust some tunables in order to open them. In the
    kernel, this is done by changing public variables in mdb. The goal of
    this feature is to add the same capability to zdb and ztest, so that
    they can change libzpool tuneables from the command line.
  
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Reviewed by: Dan Kimmel <dan.kimmel at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author: Pavel Zakharov <pavel.zakharov at delphix.com>

Modified:
  stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.8
  stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c
  stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c
  stable/10/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
  stable/10/cddl/contrib/opensolaris/lib/libzpool/common/util.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.8
==============================================================================
--- stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.8	Tue Nov 28 18:27:25 2017	(r326334)
+++ stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.8	Tue Nov 28 18:35:58 2017	(r326335)
@@ -33,6 +33,7 @@
 .Op Fl U Ar cache
 .Op Fl I Ar inflight I/Os
 .Op Fl x Ar dumpdir
+.Op Fl o Ar var=value
 .Ar poolname
 .Op Ar object ...
 .Nm
@@ -252,6 +253,10 @@ Limit the number of outstanding checksum I/Os to the s
 The default value is 200. This option affects the performance of the
 .Fl c
 option.
+.It Fl o Ar var=value
+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.
 .It Fl P
 Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
 than 1M.

Modified: stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Tue Nov 28 18:27:25 2017	(r326334)
+++ stable/10/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Tue Nov 28 18:35:58 2017	(r326335)
@@ -119,7 +119,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] "
@@ -181,6 +182,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");
@@ -3649,7 +3652,7 @@ main(int argc, char **argv)
 		spa_config_path = spa_config_path_env;
 
 	while ((c = getopt(argc, argv,
-	    "bcdhilmMI:suCDRSAFLXx:evp:t:U:PG")) != -1) {
+	    "bcdhilmMI:suCDRSAFLXx:evp:t:U:PGo:")) != -1) {
 		switch (c) {
 		case 'b':
 		case 'c':
@@ -3717,6 +3720,11 @@ main(int argc, char **argv)
 			break;
 		case 'x':
 			vn_dumpdir = optarg;
+			break;
+		case 'o':
+			error = set_global_var(optarg);
+			if (error != 0)
+				usage();
 			break;
 		default:
 			usage();

Modified: stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Tue Nov 28 18:27:25 2017	(r326334)
+++ stable/10/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Tue Nov 28 18:35:58 2017	(r326335)
@@ -584,6 +584,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,
@@ -619,7 +621,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':
@@ -705,6 +707,10 @@ process_options(int argc, char **argv)
 			break;
 		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);

Modified: stable/10/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
==============================================================================
--- stable/10/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h	Tue Nov 28 18:27:25 2017	(r326334)
+++ stable/10/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h	Tue Nov 28 18:35:58 2017	(r326335)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  */
 /*
@@ -581,6 +581,7 @@ extern void kernel_fini(void);
 struct spa;
 extern void nicenum(uint64_t num, char *buf, size_t);
 extern void show_pool_stats(struct spa *);
+extern int set_global_var(char *arg);
 
 typedef struct callb_cpr {
 	kmutex_t	*cc_lockp;

Modified: stable/10/cddl/contrib/opensolaris/lib/libzpool/common/util.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/lib/libzpool/common/util.c	Tue Nov 28 18:27:25 2017	(r326334)
+++ stable/10/cddl/contrib/opensolaris/lib/libzpool/common/util.c	Tue Nov 28 18:35:58 2017	(r326335)
@@ -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.
@@ -127,4 +129,59 @@ show_pool_stats(spa_t *spa)
 	show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
 
 	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", varname);
+	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);
 }


More information about the svn-src-stable-10 mailing list