diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libzpool/Makefile.am | 2 | ||||
-rw-r--r-- | lib/libzpool/util.c | 57 |
2 files changed, 58 insertions, 1 deletions
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 40c460284..1e95f8064 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -140,7 +140,7 @@ libzpool_la_LIBADD = \ $(top_builddir)/lib/libnvpair/libnvpair.la \ $(top_builddir)/lib/libicp/libicp.la -libzpool_la_LIBADD += $(ZLIB) +libzpool_la_LIBADD += $(ZLIB) -ldl libzpool_la_LDFLAGS = -version-info 2:0:0 EXTRA_DIST = $(USER_C) 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); +} |