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

Alan Somers asomers at FreeBSD.org
Wed Oct 25 14:45:58 UTC 2017


Author: asomers
Date: Wed Oct 25 14:45:56 2017
New Revision: 324973
URL: https://svnweb.freebsd.org/changeset/base/324973

Log:
  MFC r324220:
  
  MFV 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/11/cddl/contrib/opensolaris/cmd/zdb/zdb.8
  stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.c
  stable/11/cddl/contrib/opensolaris/cmd/ztest/ztest.c
  stable/11/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
  stable/11/cddl/contrib/opensolaris/lib/libzpool/common/util.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.8
==============================================================================
--- stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.8	Wed Oct 25 11:44:46 2017	(r324972)
+++ stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.8	Wed Oct 25 14:45:56 2017	(r324973)
@@ -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/11/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Wed Oct 25 11:44:46 2017	(r324972)
+++ stable/11/cddl/contrib/opensolaris/cmd/zdb/zdb.c	Wed Oct 25 14:45:56 2017	(r324973)
@@ -121,7 +121,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] "
@@ -183,6 +184,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");
@@ -3614,7 +3617,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':
@@ -3682,6 +3685,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/11/cddl/contrib/opensolaris/cmd/ztest/ztest.c
==============================================================================
--- stable/11/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Wed Oct 25 11:44:46 2017	(r324972)
+++ stable/11/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Wed Oct 25 14:45:56 2017	(r324973)
@@ -583,6 +583,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,
@@ -618,7 +620,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':
@@ -704,6 +706,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/11/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h
==============================================================================
--- stable/11/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h	Wed Oct 25 11:44:46 2017	(r324972)
+++ stable/11/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h	Wed Oct 25 14:45:56 2017	(r324973)
@@ -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);
 extern void show_pool_stats(struct spa *);
+extern int set_global_var(char *arg);
 
 typedef struct callb_cpr {
 	kmutex_t	*cc_lockp;

Modified: stable/11/cddl/contrib/opensolaris/lib/libzpool/common/util.c
==============================================================================
--- stable/11/cddl/contrib/opensolaris/lib/libzpool/common/util.c	Wed Oct 25 11:44:46 2017	(r324972)
+++ stable/11/cddl/contrib/opensolaris/lib/libzpool/common/util.c	Wed Oct 25 14:45:56 2017	(r324973)
@@ -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.
@@ -152,4 +154,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 mailing list