mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-23 02:44:41 +03:00
Add libzutil for libzfs or libzpool consumers
Adds a libzutil for utility functions that are common to libzfs and libzpool consumers (most of what was in libzfs_import.c). This removes the need for utilities to link against both libzpool and libzfs. Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Don Brady <don.brady@delphix.com> Closes #8050
This commit is contained in:
committed by
Brian Behlendorf
parent
6644e5bb6e
commit
e89f1295d4
@@ -31,6 +31,7 @@
|
||||
#include <sys/mntent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
#include <locale.h>
|
||||
#include <getopt.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@@ -16,5 +16,4 @@ zdb_SOURCES = \
|
||||
|
||||
zdb_LDADD = \
|
||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(top_builddir)/lib/libzpool/libzpool.la
|
||||
|
||||
+5
-8
@@ -67,7 +67,9 @@
|
||||
#include <sys/dsl_crypt.h>
|
||||
#include <sys/dsl_scan.h>
|
||||
#include <zfs_comutil.h>
|
||||
#include <libzfs.h>
|
||||
|
||||
#include <libnvpair.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
#include "zdb.h"
|
||||
|
||||
@@ -106,7 +108,6 @@ typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
|
||||
|
||||
uint64_t *zopt_object = NULL;
|
||||
static unsigned zopt_objects = 0;
|
||||
libzfs_handle_t *g_zfs;
|
||||
uint64_t max_inflight = 1000;
|
||||
static int leaked_objects = 0;
|
||||
static range_tree_t *mos_refd_objs;
|
||||
@@ -5996,10 +5997,6 @@ main(int argc, char **argv)
|
||||
spa_load_verify_dryrun = B_TRUE;
|
||||
|
||||
kernel_init(FREAD);
|
||||
if ((g_zfs = libzfs_init()) == NULL) {
|
||||
(void) fprintf(stderr, "%s", libzfs_error_init(errno));
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (dump_all)
|
||||
verbose = MAX(verbose, 1);
|
||||
@@ -6078,7 +6075,8 @@ main(int argc, char **argv)
|
||||
args.path = searchdirs;
|
||||
args.can_be_active = B_TRUE;
|
||||
|
||||
error = zpool_tryimport(g_zfs, target_pool, &cfg, &args);
|
||||
error = zpool_find_config(NULL, target_pool, &cfg, &args,
|
||||
&libzpool_config_ops);
|
||||
|
||||
if (error == 0) {
|
||||
|
||||
@@ -6228,7 +6226,6 @@ main(int argc, char **argv)
|
||||
|
||||
dump_debug_buffer();
|
||||
|
||||
libzfs_fini(g_zfs);
|
||||
kernel_fini();
|
||||
|
||||
return (error);
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <libnvpair.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <libnvpair.h>
|
||||
#include <libudev.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include <libzfs_core.h>
|
||||
#include <zfs_prop.h>
|
||||
#include <zfs_deleg.h>
|
||||
#include <libzutil.h>
|
||||
#include <libuutil.h>
|
||||
#ifdef HAVE_IDMAP
|
||||
#include <aclutils.h>
|
||||
|
||||
@@ -11,5 +11,4 @@ zhack_SOURCES = \
|
||||
|
||||
zhack_LDADD = \
|
||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(top_builddir)/lib/libzpool/libzpool.la
|
||||
|
||||
+4
-9
@@ -48,12 +48,11 @@
|
||||
#include <sys/zio_compress.h>
|
||||
#include <sys/zfeature.h>
|
||||
#include <sys/dmu_tx.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
extern boolean_t zfeature_checks_disable;
|
||||
|
||||
const char cmdname[] = "zhack";
|
||||
libzfs_handle_t *g_zfs;
|
||||
static importargs_t g_importargs;
|
||||
static char *g_pool;
|
||||
static boolean_t g_readonly;
|
||||
@@ -128,20 +127,17 @@ zhack_import(char *target, boolean_t readonly)
|
||||
int error;
|
||||
|
||||
kernel_init(readonly ? FREAD : (FREAD | FWRITE));
|
||||
g_zfs = libzfs_init();
|
||||
ASSERT(g_zfs != NULL);
|
||||
|
||||
dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb);
|
||||
|
||||
g_readonly = readonly;
|
||||
g_importargs.unique = B_TRUE;
|
||||
g_importargs.can_be_active = readonly;
|
||||
g_pool = strdup(target);
|
||||
|
||||
error = zpool_tryimport(g_zfs, target, &config, &g_importargs);
|
||||
error = zpool_find_config(NULL, target, &config, &g_importargs,
|
||||
&libzpool_config_ops);
|
||||
if (error)
|
||||
fatal(NULL, FTAG, "cannot import '%s': %s", target,
|
||||
libzfs_error_description(g_zfs));
|
||||
fatal(NULL, FTAG, "cannot import '%s'", target);
|
||||
|
||||
props = NULL;
|
||||
if (readonly) {
|
||||
@@ -529,7 +525,6 @@ main(int argc, char **argv)
|
||||
"changes may not be committed to disk\n");
|
||||
}
|
||||
|
||||
libzfs_fini(g_zfs);
|
||||
kernel_fini();
|
||||
|
||||
return (rv);
|
||||
|
||||
@@ -13,5 +13,4 @@ zinject_SOURCES = \
|
||||
|
||||
zinject_LDADD = \
|
||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(top_builddir)/lib/libzpool/libzpool.la
|
||||
$(top_builddir)/lib/libzfs/libzfs.la
|
||||
|
||||
+16
-110
@@ -25,8 +25,6 @@
|
||||
|
||||
#include <libzfs.h>
|
||||
|
||||
#include <sys/zfs_context.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
@@ -49,9 +47,6 @@
|
||||
|
||||
#include "zinject.h"
|
||||
|
||||
extern void kernel_init(int);
|
||||
extern void kernel_fini(void);
|
||||
|
||||
static int debug;
|
||||
|
||||
static void
|
||||
@@ -161,51 +156,32 @@ parse_pathname(const char *inpath, char *dataset, char *relpath,
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from a (dataset, path) pair into a (objset, object) pair. Note that
|
||||
* we grab the object number from the inode number, since looking this up via
|
||||
* libzpool is a real pain.
|
||||
* Convert from a dataset to a objset id. Note that
|
||||
* we grab the object number from the inode number.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
|
||||
zinject_record_t *record)
|
||||
object_from_path(const char *dataset, uint64_t object, zinject_record_t *record)
|
||||
{
|
||||
objset_t *os;
|
||||
int err;
|
||||
zfs_handle_t *zhp;
|
||||
|
||||
/*
|
||||
* Before doing any libzpool operations, call sync() to ensure that the
|
||||
* on-disk state is consistent with the in-core state.
|
||||
*/
|
||||
sync();
|
||||
|
||||
err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, B_FALSE, FTAG, &os);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||
dataset, strerror(err));
|
||||
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
record->zi_objset = dmu_objset_id(os);
|
||||
record->zi_object = statbuf->st_ino;
|
||||
record->zi_objset = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
|
||||
record->zi_object = object;
|
||||
|
||||
dmu_objset_disown(os, B_FALSE, FTAG);
|
||||
zfs_close(zhp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the real range based on the type, level, and range given.
|
||||
* Intialize the range based on the type, level, and range given.
|
||||
*/
|
||||
static int
|
||||
calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
initialize_range(err_type_t type, int level, char *range,
|
||||
zinject_record_t *record)
|
||||
{
|
||||
objset_t *os = NULL;
|
||||
dnode_t *dn = NULL;
|
||||
int err;
|
||||
int ret = -1;
|
||||
|
||||
/*
|
||||
* Determine the numeric range from the string.
|
||||
*/
|
||||
@@ -233,7 +209,7 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
(void) fprintf(stderr, "invalid range '%s': must be "
|
||||
"a numeric range of the form 'start[,end]'\n",
|
||||
range);
|
||||
goto out;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +229,7 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
if (range != NULL) {
|
||||
(void) fprintf(stderr, "range cannot be specified when "
|
||||
"type is 'dnode'\n");
|
||||
goto out;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
|
||||
@@ -262,76 +238,9 @@ calculate_range(const char *dataset, err_type_t type, int level, char *range,
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the dnode associated with object, so we can calculate the block
|
||||
* size.
|
||||
*/
|
||||
if ((err = dmu_objset_own(dataset, DMU_OST_ANY,
|
||||
B_TRUE, B_FALSE, FTAG, &os)) != 0) {
|
||||
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
|
||||
dataset, strerror(err));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (record->zi_object == 0) {
|
||||
dn = DMU_META_DNODE(os);
|
||||
} else {
|
||||
err = dnode_hold(os, record->zi_object, FTAG, &dn);
|
||||
if (err != 0) {
|
||||
(void) fprintf(stderr, "failed to hold dnode "
|
||||
"for object %llu\n",
|
||||
(u_longlong_t)record->zi_object);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
|
||||
ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
|
||||
|
||||
/*
|
||||
* Translate range into block IDs.
|
||||
*/
|
||||
if (record->zi_start != 0 || record->zi_end != -1ULL) {
|
||||
record->zi_start >>= dn->dn_datablkshift;
|
||||
record->zi_end >>= dn->dn_datablkshift;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check level, and then translate level 0 blkids into ranges
|
||||
* appropriate for level of indirection.
|
||||
*/
|
||||
record->zi_level = level;
|
||||
if (level > 0) {
|
||||
ziprintf("level 0 blkid range: [%llu, %llu]\n",
|
||||
record->zi_start, record->zi_end);
|
||||
|
||||
if (level >= dn->dn_nlevels) {
|
||||
(void) fprintf(stderr, "level %d exceeds max level "
|
||||
"of object (%d)\n", level, dn->dn_nlevels - 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (record->zi_start != 0 || record->zi_end != 0) {
|
||||
int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
|
||||
|
||||
for (; level > 0; level--) {
|
||||
record->zi_start >>= shift;
|
||||
record->zi_end >>= shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (dn) {
|
||||
if (dn != DMU_META_DNODE(os))
|
||||
dnode_rele(dn, FTAG);
|
||||
}
|
||||
if (os)
|
||||
dmu_objset_disown(os, B_FALSE, FTAG);
|
||||
|
||||
return (ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -343,8 +252,6 @@ translate_record(err_type_t type, const char *object, const char *range,
|
||||
struct stat64 statbuf;
|
||||
int ret = -1;
|
||||
|
||||
kernel_init(FREAD);
|
||||
|
||||
debug = (getenv("ZINJECT_DEBUG") != NULL);
|
||||
|
||||
ziprintf("translating: %s\n", object);
|
||||
@@ -396,16 +303,16 @@ translate_record(err_type_t type, const char *object, const char *range,
|
||||
/*
|
||||
* Convert (dataset, file) into (objset, object)
|
||||
*/
|
||||
if (object_from_path(dataset, path, &statbuf, record) != 0)
|
||||
if (object_from_path(dataset, statbuf.st_ino, record) != 0)
|
||||
goto err;
|
||||
|
||||
ziprintf("raw objset: %llu\n", record->zi_objset);
|
||||
ziprintf("raw object: %llu\n", record->zi_object);
|
||||
|
||||
/*
|
||||
* For the given object, calculate the real (type, level, range)
|
||||
* For the given object, intialize the range in bytes
|
||||
*/
|
||||
if (calculate_range(dataset, type, level, (char *)range, record) != 0)
|
||||
if (initialize_range(type, level, (char *)range, record) != 0)
|
||||
goto err;
|
||||
|
||||
ziprintf(" objset: %llu\n", record->zi_objset);
|
||||
@@ -427,7 +334,6 @@ translate_record(err_type_t type, const char *object, const char *range,
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
kernel_fini();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -561,6 +561,7 @@ register_handler(const char *pool, int flags, zinject_record_t *record,
|
||||
|
||||
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
|
||||
(void) fprintf(stderr, "failed to add handler: %s\n",
|
||||
errno == EDOM ? "block level exceeds max level of object" :
|
||||
strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
@@ -853,6 +854,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 'r':
|
||||
range = optarg;
|
||||
flags |= ZINJECT_CALC_RANGE;
|
||||
break;
|
||||
case 's':
|
||||
dur_secs = 1;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <thread_pool.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
#include <sys/zfs_context.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
+41
-4
@@ -64,6 +64,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
|
||||
#include "zpool_util.h"
|
||||
#include "zfs_comutil.h"
|
||||
@@ -2533,6 +2534,40 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
|
||||
return (ret);
|
||||
}
|
||||
|
||||
typedef struct target_exists_args {
|
||||
const char *poolname;
|
||||
uint64_t poolguid;
|
||||
} target_exists_args_t;
|
||||
|
||||
static int
|
||||
name_or_guid_exists(zpool_handle_t *zhp, void *data)
|
||||
{
|
||||
target_exists_args_t *args = data;
|
||||
nvlist_t *config = zpool_get_config(zhp, NULL);
|
||||
int found = 0;
|
||||
|
||||
if (config == NULL)
|
||||
return (0);
|
||||
|
||||
if (args->poolname != NULL) {
|
||||
char *pool_name;
|
||||
|
||||
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
|
||||
&pool_name) == 0);
|
||||
if (strcmp(pool_name, args->poolname) == 0)
|
||||
found = 1;
|
||||
} else {
|
||||
uint64_t pool_guid;
|
||||
|
||||
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
|
||||
&pool_guid) == 0);
|
||||
if (pool_guid == args->poolguid)
|
||||
found = 1;
|
||||
}
|
||||
zpool_close(zhp);
|
||||
|
||||
return (found);
|
||||
}
|
||||
/*
|
||||
* zpool checkpoint <pool>
|
||||
* checkpoint --discard <pool>
|
||||
@@ -2685,6 +2720,7 @@ zpool_do_import(int argc, char **argv)
|
||||
boolean_t do_rewind = B_FALSE;
|
||||
boolean_t xtreme_rewind = B_FALSE;
|
||||
boolean_t do_scan = B_FALSE;
|
||||
boolean_t pool_exists = B_FALSE;
|
||||
uint64_t pool_state, txg = -1ULL;
|
||||
char *cachefile = NULL;
|
||||
importargs_t idata = { 0 };
|
||||
@@ -2892,7 +2928,8 @@ zpool_do_import(int argc, char **argv)
|
||||
/*
|
||||
* User specified a name or guid. Ensure it's unique.
|
||||
*/
|
||||
idata.unique = B_TRUE;
|
||||
target_exists_args_t search = {searchname, searchguid};
|
||||
pool_exists = zpool_iter(g_zfs, name_or_guid_exists, &search);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2928,9 +2965,9 @@ zpool_do_import(int argc, char **argv)
|
||||
idata.scan = do_scan;
|
||||
idata.policy = policy;
|
||||
|
||||
pools = zpool_search_import(g_zfs, &idata);
|
||||
pools = zpool_search_import(g_zfs, &idata, &libzfs_config_ops);
|
||||
|
||||
if (pools != NULL && idata.exists &&
|
||||
if (pools != NULL && pool_exists &&
|
||||
(argc == 1 || strcmp(argv[0], argv[1]) == 0)) {
|
||||
(void) fprintf(stderr, gettext("cannot import '%s': "
|
||||
"a pool with that name already exists\n"),
|
||||
@@ -2939,7 +2976,7 @@ zpool_do_import(int argc, char **argv)
|
||||
"<pool | id> <newpool>' to give it a new name\n"),
|
||||
"zpool import");
|
||||
err = 1;
|
||||
} else if (pools == NULL && idata.exists) {
|
||||
} else if (pools == NULL && pool_exists) {
|
||||
(void) fprintf(stderr, gettext("cannot import '%s': "
|
||||
"a pool with that name is already created/imported,\n"),
|
||||
argv[0]);
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <libintl.h>
|
||||
#include <libnvpair.h>
|
||||
#include <libzutil.h>
|
||||
#include <limits.h>
|
||||
#include <sys/spa.h>
|
||||
#include <scsi/scsi.h>
|
||||
|
||||
@@ -20,7 +20,6 @@ ztest_SOURCES = \
|
||||
|
||||
ztest_LDADD = \
|
||||
$(top_builddir)/lib/libnvpair/libnvpair.la \
|
||||
$(top_builddir)/lib/libzfs/libzfs.la \
|
||||
$(top_builddir)/lib/libzpool/libzpool.la
|
||||
|
||||
ztest_LDADD += -lm
|
||||
|
||||
+3
-5
@@ -128,7 +128,7 @@
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <zfs_fletcher.h>
|
||||
#include <libnvpair.h>
|
||||
#include <libzfs.h>
|
||||
#include <libzutil.h>
|
||||
#include <sys/crypto/icp.h>
|
||||
#ifdef __GLIBC__
|
||||
#include <execinfo.h> /* for backtrace() */
|
||||
@@ -7065,7 +7065,6 @@ make_random_props(void)
|
||||
static void
|
||||
ztest_import(ztest_shared_t *zs)
|
||||
{
|
||||
libzfs_handle_t *hdl;
|
||||
importargs_t args = { 0 };
|
||||
spa_t *spa;
|
||||
nvlist_t *cfg = NULL;
|
||||
@@ -7080,14 +7079,14 @@ ztest_import(ztest_shared_t *zs)
|
||||
VERIFY0(pthread_rwlock_init(&ztest_name_lock, NULL));
|
||||
|
||||
kernel_init(FREAD | FWRITE);
|
||||
hdl = libzfs_init();
|
||||
|
||||
searchdirs[0] = ztest_opts.zo_dir;
|
||||
args.paths = nsearch;
|
||||
args.path = searchdirs;
|
||||
args.can_be_active = B_FALSE;
|
||||
|
||||
error = zpool_tryimport(hdl, name, &cfg, &args);
|
||||
error = zpool_find_config(NULL, name, &cfg, &args,
|
||||
&libzpool_config_ops);
|
||||
if (error)
|
||||
(void) fatal(0, "No pools found\n");
|
||||
|
||||
@@ -7097,7 +7096,6 @@ ztest_import(ztest_shared_t *zs)
|
||||
1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift;
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
libzfs_fini(hdl);
|
||||
kernel_fini();
|
||||
|
||||
if (!ztest_opts.zo_mmp_test) {
|
||||
|
||||
Reference in New Issue
Block a user