mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 02:49:32 +03:00
OpenZFS 7280 - Allow changing global libzpool variables in zdb and ztest through command line
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
This commit is contained in:
parent
41425f79da
commit
ed828c0c37
@ -127,7 +127,8 @@ usage(void)
|
|||||||
{
|
{
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
|
"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 "
|
" %s [-divPA] [-e -p path...] [-U config] dataset "
|
||||||
"[object...]\n"
|
"[object...]\n"
|
||||||
" %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
|
" %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
|
||||||
@ -189,6 +190,8 @@ usage(void)
|
|||||||
"checksumming I/Os [default is 200]\n");
|
"checksumming I/Os [default is 200]\n");
|
||||||
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
|
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
|
||||||
"exiting\n");
|
"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) "
|
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
||||||
"to make only that option verbose\n");
|
"to make only that option verbose\n");
|
||||||
(void) fprintf(stderr, "Default is to dump everything non-verbosely\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;
|
spa_config_path = spa_config_path_env;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv,
|
while ((c = getopt(argc, argv,
|
||||||
"bcdhilmMI:suCDRSAFLXx:evp:t:U:PVG")) != -1) {
|
"bcdhilmMI:suCDRSAFLXx:evp:t:U:PVGo")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -3762,9 +3765,6 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
searchdirs[nsearch++] = optarg;
|
searchdirs[nsearch++] = optarg;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
|
||||||
vn_dumpdir = optarg;
|
|
||||||
break;
|
|
||||||
case 't':
|
case 't':
|
||||||
max_txg = strtoull(optarg, NULL, 0);
|
max_txg = strtoull(optarg, NULL, 0);
|
||||||
if (max_txg < TXG_INITIAL) {
|
if (max_txg < TXG_INITIAL) {
|
||||||
@ -3779,6 +3779,14 @@ main(int argc, char **argv)
|
|||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
vn_dumpdir = optarg;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
error = set_global_var(optarg);
|
||||||
|
if (error != 0)
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
@ -629,6 +629,8 @@ usage(boolean_t requested)
|
|||||||
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
|
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
|
||||||
"\t[-P passtime (default: %llu sec)] time per pass\n"
|
"\t[-P passtime (default: %llu sec)] time per pass\n"
|
||||||
"\t[-B alt_ztest (default: <none>)] alternate ztest path\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"
|
"\t[-h] (print help)\n"
|
||||||
"",
|
"",
|
||||||
zo->zo_pool,
|
zo->zo_pool,
|
||||||
@ -664,7 +666,7 @@ process_options(int argc, char **argv)
|
|||||||
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
|
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
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;
|
value = 0;
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -752,6 +754,10 @@ process_options(int argc, char **argv)
|
|||||||
case 'B':
|
case 'B':
|
||||||
(void) strlcpy(altdir, optarg, sizeof (altdir));
|
(void) strlcpy(altdir, optarg, sizeof (altdir));
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (set_global_var(optarg) != 0)
|
||||||
|
usage(B_FALSE);
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(B_TRUE);
|
usage(B_TRUE);
|
||||||
break;
|
break;
|
||||||
|
@ -19,13 +19,10 @@
|
|||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Use is subject to license terms.
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
|
||||||
/*
|
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2012, Joyent, Inc. 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
|
#ifndef _SYS_ZFS_CONTEXT_H
|
||||||
@ -695,6 +692,7 @@ extern void random_fini(void);
|
|||||||
struct spa;
|
struct spa;
|
||||||
extern void nicenum(uint64_t num, char *buf);
|
extern void nicenum(uint64_t num, char *buf);
|
||||||
extern void show_pool_stats(struct spa *);
|
extern void show_pool_stats(struct spa *);
|
||||||
|
extern int set_global_var(char *arg);
|
||||||
|
|
||||||
typedef struct callb_cpr {
|
typedef struct callb_cpr {
|
||||||
kmutex_t *cc_lockp;
|
kmutex_t *cc_lockp;
|
||||||
|
@ -140,7 +140,7 @@ libzpool_la_LIBADD = \
|
|||||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||||
$(top_builddir)/lib/libicp/libicp.la
|
$(top_builddir)/lib/libicp/libicp.la
|
||||||
|
|
||||||
libzpool_la_LIBADD += $(ZLIB)
|
libzpool_la_LIBADD += $(ZLIB) -ldl
|
||||||
libzpool_la_LDFLAGS = -version-info 2:0:0
|
libzpool_la_LDFLAGS = -version-info 2:0:0
|
||||||
|
|
||||||
EXTRA_DIST = $(USER_C)
|
EXTRA_DIST = $(USER_C)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2016 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -31,6 +32,7 @@
|
|||||||
#include <sys/spa.h>
|
#include <sys/spa.h>
|
||||||
#include <sys/fs/zfs.h>
|
#include <sys/fs/zfs.h>
|
||||||
#include <sys/refcount.h>
|
#include <sys/refcount.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines needed by more than one client of libzpool.
|
* Routines needed by more than one client of libzpool.
|
||||||
@ -158,3 +160,58 @@ show_pool_stats(spa_t *spa)
|
|||||||
|
|
||||||
nvlist_free(config);
|
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);
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
\fBzdb\fR [-CumdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
|
\fBzdb\fR [-CumdibcsDvhLMXFPAG] [-e [-p \fIpath\fR...]] [-t \fItxg\fR]
|
||||||
[-U \fIcache\fR] [-I \fIinflight I/Os\fR] [-x \fIdumpdir\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
|
.P
|
||||||
\fBzdb\fR [-divPA] [-e [-p \fIpath\fR...]] [-U \fIcache\fR]
|
\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.
|
option.
|
||||||
.RE
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
|
Loading…
Reference in New Issue
Block a user