diff options
author | George Melikov <[email protected]> | 2017-01-31 21:13:10 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-31 10:13:10 -0800 |
commit | ed828c0c375477ff27d5fa9a7bf46ae6b6f2e57a (patch) | |
tree | 09347b9e65fb56cd28afbe2ac3b1e29f0d175bc0 /lib/libzpool/util.c | |
parent | 41425f79dabc58e5ddb16cc701cc435a5480e56a (diff) |
OpenZFS 7280 - Allow changing global libzpool variables in zdb and ztest through command line
Authored by: Pavel Zakharov <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Dan Kimmel <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Ported-by: George Melikov <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/7280
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/0e60744
Closes #5676
Diffstat (limited to 'lib/libzpool/util.c')
-rw-r--r-- | lib/libzpool/util.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/libzpool/util.c b/lib/libzpool/util.c index bc3bcbe78..3bdc31722 100644 --- a/lib/libzpool/util.c +++ b/lib/libzpool/util.c @@ -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); +} |