Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Apr 2017 16:53:34 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r316858 - in vendor/illumos/dist: cmd/zdb cmd/ztest lib/libzpool/common lib/libzpool/common/sys man/man1m
Message-ID:  <201704141653.v3EGrYEO030485@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Fri Apr 14 16:53:34 2017
New Revision: 316858
URL: https://svnweb.freebsd.org/changeset/base/316858

Log:
  7280 Allow changing global libzpool variables in zdb and ztest through command line
  
  illumos/illumos-gate@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@delphix.com>
  Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
  Approved by: Robert Mustacchi <rm@joyent.com>
  Author: Pavel Zakharov <pavel.zakharov@delphix.com>

Modified:
  vendor/illumos/dist/cmd/zdb/zdb.c
  vendor/illumos/dist/cmd/ztest/ztest.c
  vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h
  vendor/illumos/dist/lib/libzpool/common/util.c
  vendor/illumos/dist/man/man1m/zdb.1m

Modified: vendor/illumos/dist/cmd/zdb/zdb.c
==============================================================================
--- vendor/illumos/dist/cmd/zdb/zdb.c	Fri Apr 14 16:40:10 2017	(r316857)
+++ vendor/illumos/dist/cmd/zdb/zdb.c	Fri Apr 14 16:53:34 2017	(r316858)
@@ -118,7 +118,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] "
@@ -180,6 +181,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");
@@ -3575,7 +3578,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':
@@ -3644,6 +3647,11 @@ main(int argc, char **argv)
 		case 'x':
 			vn_dumpdir = optarg;
 			break;
+		case 'o':
+			error = set_global_var(optarg);
+			if (error != 0)
+				usage();
+			break;
 		default:
 			usage();
 			break;

Modified: vendor/illumos/dist/cmd/ztest/ztest.c
==============================================================================
--- vendor/illumos/dist/cmd/ztest/ztest.c	Fri Apr 14 16:40:10 2017	(r316857)
+++ vendor/illumos/dist/cmd/ztest/ztest.c	Fri Apr 14 16:53:34 2017	(r316858)
@@ -579,6 +579,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,
@@ -614,7 +616,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':
@@ -701,6 +703,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;

Modified: vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h
==============================================================================
--- vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h	Fri Apr 14 16:40:10 2017	(r316857)
+++ vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h	Fri Apr 14 16:53:34 2017	(r316858)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  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.
  */
 
@@ -541,6 +541,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: vendor/illumos/dist/lib/libzpool/common/util.c
==============================================================================
--- vendor/illumos/dist/lib/libzpool/common/util.c	Fri Apr 14 16:40:10 2017	(r316857)
+++ vendor/illumos/dist/lib/libzpool/common/util.c	Fri Apr 14 16:53:34 2017	(r316858)
@@ -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.
@@ -153,3 +155,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", 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);
+}

Modified: vendor/illumos/dist/man/man1m/zdb.1m
==============================================================================
--- vendor/illumos/dist/man/man1m/zdb.1m	Fri Apr 14 16:40:10 2017	(r316857)
+++ vendor/illumos/dist/man/man1m/zdb.1m	Fri Apr 14 16:53:34 2017	(r316858)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704141653.v3EGrYEO030485>