parent
f00af48295
commit
7f85a9adfc
|
@ -5811,7 +5811,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
|
||||||
/*
|
/*
|
||||||
* Theoretically, we could try to track leaks here, but it would
|
* Theoretically, we could try to track leaks here, but it would
|
||||||
* require also importing the shared log pool and processing the
|
* require also importing the shared log pool and processing the
|
||||||
* chain map and space maps for it. The ZIL currently doesn't have
|
* chain map and space maps for it. ZDB currently doesn't have
|
||||||
* much facility to support multiple pools at once, so we leave this
|
* much facility to support multiple pools at once, so we leave this
|
||||||
* for future work.
|
* for future work.
|
||||||
*/
|
*/
|
||||||
|
@ -6849,7 +6849,8 @@ chain_map_count_blocks(spa_t *spa, zdb_cb_t *zbc)
|
||||||
for (spa_chain_map_os_t *os_node = avl_first(os_t);
|
for (spa_chain_map_os_t *os_node = avl_first(os_t);
|
||||||
os_node != NULL; os_node = AVL_NEXT(os_t, os_node)) {
|
os_node != NULL; os_node = AVL_NEXT(os_t, os_node)) {
|
||||||
(void) zil_parse_raw(spa, &os_node->scmo_chain_head,
|
(void) zil_parse_raw(spa, &os_node->scmo_chain_head,
|
||||||
chain_map_count_blk_cb, chain_map_count_lr_cb, zbc);
|
chain_map_count_blk_cb, chain_map_count_lr_cb,
|
||||||
|
zbc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8210,6 +8211,57 @@ dump_log_spacemap_obsolete_stats(spa_t *spa)
|
||||||
(u_longlong_t)lsos.lsos_total_entries);
|
(u_longlong_t)lsos.lsos_total_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_blkptr(const blkptr_t *bp)
|
||||||
|
{
|
||||||
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
|
if (dump_opt['Z'] && BP_GET_COMPRESS(bp) == ZIO_COMPRESS_ZSTD)
|
||||||
|
snprintf_zstd_header(spa, blkbuf, sizeof (blkbuf), bp);
|
||||||
|
(void) printf("%s\n", blkbuf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chain_map_dump_blk_cb(spa_t *spa, const blkptr_t *bp, void *arg)
|
||||||
|
{
|
||||||
|
(void) spa, (void) arg;
|
||||||
|
printf("\t\t\tBP: ");
|
||||||
|
print_blkptr(bp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
chain_map_dump_lr_cb(spa_t *spa, const lr_t *lrc, void *arg)
|
||||||
|
{
|
||||||
|
(void) spa, (void) arg;
|
||||||
|
lr_write_t *lr = (lr_write_t *)lrc;
|
||||||
|
blkptr_t *bp = &lr->lr_blkptr;
|
||||||
|
printf("\t\t\tLR BP: ");
|
||||||
|
print_blkptr(bp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_chain_map(spa_t *spa)
|
||||||
|
{
|
||||||
|
(void) printf("Chain map contents:\n");
|
||||||
|
avl_tree_t *pool_t = &spa->spa_chain_map;
|
||||||
|
|
||||||
|
for (spa_chain_map_pool_t *pool_node = avl_first(pool_t);
|
||||||
|
pool_node != NULL; pool_node = AVL_NEXT(pool_t, pool_node)) {
|
||||||
|
avl_tree_t *os_t = &pool_node->scmp_os_tree;
|
||||||
|
(void) printf("\tPool entry: %s\n", pool_node->scmp_name);
|
||||||
|
for (spa_chain_map_os_t *os_node = avl_first(os_t);
|
||||||
|
os_node != NULL; os_node = AVL_NEXT(os_t, os_node)) {
|
||||||
|
(void) printf("\t\tObjset entry: %"PRIu64"\n\t\t\t",
|
||||||
|
os_node->scmo_id);
|
||||||
|
print_blkptr(&os_node->scmo_chain_head);
|
||||||
|
(void) zil_parse_raw(spa, &os_node->scmo_chain_head,
|
||||||
|
chain_map_dump_blk_cb, chain_map_dump_lr_cb, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_zpool(spa_t *spa)
|
dump_zpool(spa_t *spa)
|
||||||
{
|
{
|
||||||
|
@ -8291,6 +8343,9 @@ dump_zpool(spa_t *spa)
|
||||||
(void) dmu_objset_find(spa_name(spa), dump_one_objset,
|
(void) dmu_objset_find(spa_name(spa), dump_one_objset,
|
||||||
NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
|
NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
|
||||||
|
|
||||||
|
if (spa_is_shared_log(spa))
|
||||||
|
dump_chain_map(spa);
|
||||||
|
|
||||||
if (rc == 0 && !dump_opt['L'])
|
if (rc == 0 && !dump_opt['L'])
|
||||||
rc = dump_mos_leaks(spa);
|
rc = dump_mos_leaks(spa);
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ fatal(spa_t *spa, const void *tag, const char *fmt, ...)
|
||||||
|
|
||||||
if (spa != NULL) {
|
if (spa != NULL) {
|
||||||
spa_close(spa, tag);
|
spa_close(spa, tag);
|
||||||
(void) spa_export(g_pool, NULL, B_TRUE, B_FALSE);
|
(void) spa_export(g_pool, NULL, B_TRUE, B_FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
@ -1015,7 +1015,8 @@ main(int argc, char **argv)
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_FALSE) != 0) {
|
if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_FALSE,
|
||||||
|
NULL) != 0) {
|
||||||
fatal(NULL, FTAG, "pool export failed; "
|
fatal(NULL, FTAG, "pool export failed; "
|
||||||
"changes may not be committed to disk\n");
|
"changes may not be committed to disk\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,9 +391,10 @@ get_usage(zpool_help_t idx)
|
||||||
"\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
|
"\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m] [-N] "
|
||||||
"[-R root] [-F [-n]] -a\n"
|
"[-R root] [-F [-n]] -a\n"
|
||||||
"\timport [-o mntopts] [-o property=value] ... \n"
|
"\timport [-o mntopts] [-o property=value] ... \n"
|
||||||
"\t [-d dir | -c cachefile] [-D] [-l] [-f] [-m -L pool] "
|
"\t [-d dir | -c cachefile] [-D] [-l] [-f] "
|
||||||
"[-N] [-R root] [-F [-n]]\n"
|
"[-m [-L pool]] [-N] [-R root]\n"
|
||||||
"\t [--rewind-to-checkpoint] <pool | id> [newpool]\n"));
|
"\t [-F [-n]] [--rewind-to-checkpoint] <pool | id> "
|
||||||
|
"[newpool]\n"));
|
||||||
case HELP_IOSTAT:
|
case HELP_IOSTAT:
|
||||||
return (gettext("\tiostat [[[-c [script1,script2,...]"
|
return (gettext("\tiostat [[[-c [script1,script2,...]"
|
||||||
"[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
|
"[-lq]]|[-rw]] [-T d | u] [-ghHLpPvy]\n"
|
||||||
|
@ -1181,8 +1182,7 @@ zpool_do_add(int argc, char **argv)
|
||||||
|
|
||||||
/* pass off to make_root_vdev for processing */
|
/* pass off to make_root_vdev for processing */
|
||||||
nvroot = make_root_vdev(zhp, props, !check_inuse,
|
nvroot = make_root_vdev(zhp, props, !check_inuse,
|
||||||
check_replication, B_FALSE, dryrun, has_shared_log, argc,
|
check_replication, B_FALSE, dryrun, has_shared_log, argc, argv);
|
||||||
argv);
|
|
||||||
if (nvroot == NULL) {
|
if (nvroot == NULL) {
|
||||||
zpool_close(zhp);
|
zpool_close(zhp);
|
||||||
return (1);
|
return (1);
|
||||||
|
@ -3667,10 +3667,31 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
||||||
uint_t npools = 0;
|
uint_t npools = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int err = 0;
|
||||||
|
nvpair_t *elem = NULL, *next = NULL;
|
||||||
|
boolean_t first = B_TRUE;
|
||||||
tpool_t *tp = NULL;
|
tpool_t *tp = NULL;
|
||||||
if (import->do_all) {
|
if (import->do_all) {
|
||||||
tp = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
|
tp = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
|
||||||
|
elem = nvlist_next_nvpair(pools, NULL);
|
||||||
|
next = nvlist_next_nvpair(pools, elem);
|
||||||
|
|
||||||
|
while (elem != NULL) {
|
||||||
|
verify(nvpair_value_nvlist(elem, &config) == 0);
|
||||||
|
if (fnvlist_lookup_boolean(config,
|
||||||
|
ZPOOL_CONFIG_IS_SHARED_LOG)) {
|
||||||
|
err = do_import(config, NULL, mntopts, props,
|
||||||
|
flags, mount_tp_nthr);
|
||||||
|
first = B_FALSE;
|
||||||
|
fnvlist_remove_nvpair(pools, elem);
|
||||||
|
}
|
||||||
|
elem = next;
|
||||||
|
next = nvlist_next_nvpair(pools, elem);
|
||||||
|
}
|
||||||
|
if (err != 0)
|
||||||
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3679,9 +3700,6 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
|
||||||
* post-process the list to deal with pool state and possible
|
* post-process the list to deal with pool state and possible
|
||||||
* duplicate names.
|
* duplicate names.
|
||||||
*/
|
*/
|
||||||
int err = 0;
|
|
||||||
nvpair_t *elem = NULL;
|
|
||||||
boolean_t first = B_TRUE;
|
|
||||||
if (!pool_specified && import->do_all) {
|
if (!pool_specified && import->do_all) {
|
||||||
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL)
|
while ((elem = nvlist_next_nvpair(pools, elem)) != NULL)
|
||||||
npools++;
|
npools++;
|
||||||
|
@ -6814,8 +6832,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
|
|
||||||
if (!printed) {
|
if (!printed) {
|
||||||
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||||
(void) printf(dashes, depth + 2, "", cb->cb_namewidth,
|
(void) printf(dashes, depth + 2, "",
|
||||||
class_name[n]);
|
cb->cb_namewidth, class_name[n]);
|
||||||
printed = B_TRUE;
|
printed = B_TRUE;
|
||||||
}
|
}
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||||
|
@ -6829,7 +6847,8 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
uint64_t shared_log_guid;
|
uint64_t shared_log_guid;
|
||||||
if (name == NULL && nvlist_lookup_uint64(zpool_get_config(zhp, NULL),
|
if (name == NULL && nvlist_lookup_uint64(zpool_get_config(zhp, NULL),
|
||||||
ZPOOL_CONFIG_SHARED_LOG_POOL, &shared_log_guid) == 0) {
|
ZPOOL_CONFIG_SHARED_LOG_POOL, &shared_log_guid) == 0) {
|
||||||
(void) printf(dashes, depth + 2, "", cb->cb_namewidth, "shared log");
|
(void) printf(dashes, depth + 2, "", cb->cb_namewidth,
|
||||||
|
"shared log");
|
||||||
zpool_handle_t *shared_log = find_by_guid(g_zfs,
|
zpool_handle_t *shared_log = find_by_guid(g_zfs,
|
||||||
shared_log_guid);
|
shared_log_guid);
|
||||||
VERIFY(shared_log);
|
VERIFY(shared_log);
|
||||||
|
@ -8082,17 +8101,10 @@ struct recycle_data {
|
||||||
boolean_t verbose;
|
boolean_t verbose;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static void
|
||||||
recycle_callback(zpool_handle_t *zhp, void *data)
|
print_recycle_info(nvlist_t *nvl, boolean_t dryrun)
|
||||||
{
|
{
|
||||||
struct recycle_data *rd = data;
|
printf("Cleaned up%s: [", dryrun ? " (dry run)" : "");
|
||||||
nvlist_t *nvl;
|
|
||||||
|
|
||||||
int err = lzc_recycle(zpool_get_name(zhp), rd->dryrun, &nvl);
|
|
||||||
if (err)
|
|
||||||
return (err);
|
|
||||||
if (rd->verbose) {
|
|
||||||
printf("Cleaned up%s: [", rd->dryrun ? " (dry run)" : "");
|
|
||||||
nvpair_t *elem = NULL;
|
nvpair_t *elem = NULL;
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
while ((elem = nvlist_next_nvpair(nvl, elem))) {
|
while ((elem = nvlist_next_nvpair(nvl, elem))) {
|
||||||
|
@ -8100,13 +8112,25 @@ recycle_callback(zpool_handle_t *zhp, void *data)
|
||||||
first = B_FALSE;
|
first = B_FALSE;
|
||||||
}
|
}
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
recycle_callback(zpool_handle_t *zhp, void *data)
|
||||||
|
{
|
||||||
|
struct recycle_data *rd = data;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
|
||||||
|
int err = lzc_recycle(zpool_get_name(zhp), NULL, rd->dryrun, &nvl);
|
||||||
|
if (err)
|
||||||
|
return (err);
|
||||||
|
if (rd->verbose)
|
||||||
|
print_recycle_info(nvl, rd->dryrun);
|
||||||
nvlist_free(nvl);
|
nvlist_free(nvl);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool recycle <pool> ...
|
* zpool recycle [-a] [-n] [-v] <pool> [pool]...
|
||||||
*
|
*
|
||||||
* Cleans up chain maps for non-attached client pools
|
* Cleans up chain maps for non-attached client pools
|
||||||
*/
|
*/
|
||||||
|
@ -8115,9 +8139,10 @@ zpool_do_recycle(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
struct recycle_data rd = {0};
|
struct recycle_data rd = {0};
|
||||||
|
boolean_t doall = B_FALSE;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "nv")) != -1) {
|
while ((c = getopt(argc, argv, "nva")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'n':
|
case 'n':
|
||||||
rd.dryrun = B_TRUE;
|
rd.dryrun = B_TRUE;
|
||||||
|
@ -8125,6 +8150,9 @@ zpool_do_recycle(int argc, char **argv)
|
||||||
case 'v':
|
case 'v':
|
||||||
rd.verbose = B_TRUE;
|
rd.verbose = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
doall = B_TRUE;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
@ -8138,10 +8166,44 @@ zpool_do_recycle(int argc, char **argv)
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
(void) fprintf(stderr, gettext("missing pool name argument\n"));
|
(void) fprintf(stderr, gettext("missing pool name argument\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
|
} else if (argc == 1 && !doall) {
|
||||||
|
(void) fprintf(stderr, gettext("missing client pools\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
} else if (argc > 1 && doall) {
|
||||||
|
(void) fprintf(stderr, gettext("specific client pools and "
|
||||||
|
"do_all\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doall) {
|
||||||
return (for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
return (for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
|
||||||
B_FALSE, recycle_callback, &rd));
|
B_FALSE, recycle_callback, &rd));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pool = argv[0];
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
nvlist_t *clients = NULL;
|
||||||
|
if (argc > 0)
|
||||||
|
clients = fnvlist_alloc();
|
||||||
|
while (argc > 0) {
|
||||||
|
fnvlist_add_boolean(clients, argv[0]);
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvlist_t *nvl;
|
||||||
|
int err = lzc_recycle(pool, clients, rd.dryrun, &nvl);
|
||||||
|
if (clients)
|
||||||
|
nvlist_free(clients);
|
||||||
|
if (err)
|
||||||
|
return (err);
|
||||||
|
if (rd.verbose)
|
||||||
|
print_recycle_info(nvl, rd.dryrun);
|
||||||
|
nvlist_free(nvl);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
12
cmd/ztest.c
12
cmd/ztest.c
|
@ -3048,7 +3048,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
|
||||||
* an export concurrently.
|
* an export concurrently.
|
||||||
*/
|
*/
|
||||||
VERIFY0(spa_open(zo->zo_pool, &spa, FTAG));
|
VERIFY0(spa_open(zo->zo_pool, &spa, FTAG));
|
||||||
int error = spa_destroy(zo->zo_pool);
|
int error = spa_destroy(zo->zo_pool, NULL);
|
||||||
if (error != EBUSY && error != ZFS_ERR_EXPORT_IN_PROGRESS) {
|
if (error != EBUSY && error != ZFS_ERR_EXPORT_IN_PROGRESS) {
|
||||||
fatal(B_FALSE, "spa_destroy(%s) returned unexpected value %d",
|
fatal(B_FALSE, "spa_destroy(%s) returned unexpected value %d",
|
||||||
spa->spa_name, error);
|
spa->spa_name, error);
|
||||||
|
@ -3150,7 +3150,7 @@ ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
|
||||||
/*
|
/*
|
||||||
* Clean up from previous runs.
|
* Clean up from previous runs.
|
||||||
*/
|
*/
|
||||||
(void) spa_destroy(name);
|
(void) spa_destroy(name, NULL);
|
||||||
|
|
||||||
raidz_children = ztest_get_raidz_children(ztest_spa);
|
raidz_children = ztest_get_raidz_children(ztest_spa);
|
||||||
|
|
||||||
|
@ -3604,7 +3604,7 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up the old pool, if any */
|
/* clean up the old pool, if any */
|
||||||
(void) spa_destroy("splitp");
|
(void) spa_destroy("splitp", NULL);
|
||||||
|
|
||||||
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
|
||||||
|
|
||||||
|
@ -7384,7 +7384,7 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||||
/*
|
/*
|
||||||
* Clean up from previous runs.
|
* Clean up from previous runs.
|
||||||
*/
|
*/
|
||||||
(void) spa_destroy(newname);
|
(void) spa_destroy(newname, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the pool's configuration and guid.
|
* Get the pool's configuration and guid.
|
||||||
|
@ -7405,7 +7405,7 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||||
/*
|
/*
|
||||||
* Export it.
|
* Export it.
|
||||||
*/
|
*/
|
||||||
VERIFY0(spa_export(oldname, &config, B_FALSE, B_FALSE));
|
VERIFY0(spa_export(oldname, &config, B_FALSE, B_FALSE, NULL));
|
||||||
|
|
||||||
ztest_walk_pool_directory("pools after export");
|
ztest_walk_pool_directory("pools after export");
|
||||||
|
|
||||||
|
@ -8556,7 +8556,7 @@ ztest_init(ztest_shared_t *zs)
|
||||||
/*
|
/*
|
||||||
* Create the storage pool.
|
* Create the storage pool.
|
||||||
*/
|
*/
|
||||||
(void) spa_destroy(ztest_opts.zo_pool);
|
(void) spa_destroy(ztest_opts.zo_pool, NULL);
|
||||||
ztest_shared->zs_vdev_next_leaf = 0;
|
ztest_shared->zs_vdev_next_leaf = 0;
|
||||||
zs->zs_splits = 0;
|
zs->zs_splits = 0;
|
||||||
zs->zs_mirrors = ztest_opts.zo_mirrors;
|
zs->zs_mirrors = ztest_opts.zo_mirrors;
|
||||||
|
|
|
@ -346,6 +346,7 @@ _LIBZFS_H uint64_t zpool_vdev_path_to_guid(zpool_handle_t *zhp,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
_LIBZFS_H const char *zpool_get_state_str(zpool_handle_t *);
|
_LIBZFS_H const char *zpool_get_state_str(zpool_handle_t *);
|
||||||
|
_LIBZFS_H zpool_handle_t *zpool_get_shared_log(zpool_handle_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to manage pool properties
|
* Functions to manage pool properties
|
||||||
|
|
|
@ -156,13 +156,18 @@ _LIBZFS_CORE_H int lzc_wait_fs(const char *, zfs_wait_activity_t, boolean_t *);
|
||||||
_LIBZFS_CORE_H int lzc_set_bootenv(const char *, const nvlist_t *);
|
_LIBZFS_CORE_H int lzc_set_bootenv(const char *, const nvlist_t *);
|
||||||
_LIBZFS_CORE_H int lzc_get_bootenv(const char *, nvlist_t **);
|
_LIBZFS_CORE_H int lzc_get_bootenv(const char *, nvlist_t **);
|
||||||
|
|
||||||
_LIBZFS_CORE_H int lzc_recycle(const char *, boolean_t, nvlist_t **);
|
_LIBZFS_CORE_H int lzc_recycle(const char *, nvlist_t *, boolean_t,
|
||||||
|
nvlist_t **);
|
||||||
|
|
||||||
_LIBZFS_CORE_H int lzc_get_vdev_prop(const char *, nvlist_t *, nvlist_t **);
|
_LIBZFS_CORE_H int lzc_get_vdev_prop(const char *, nvlist_t *, nvlist_t **);
|
||||||
_LIBZFS_CORE_H int lzc_set_vdev_prop(const char *, nvlist_t *, nvlist_t **);
|
_LIBZFS_CORE_H int lzc_set_vdev_prop(const char *, nvlist_t *, nvlist_t **);
|
||||||
|
|
||||||
_LIBZFS_CORE_H int lzc_scrub(zfs_ioc_t, const char *, nvlist_t *, nvlist_t **);
|
_LIBZFS_CORE_H int lzc_scrub(zfs_ioc_t, const char *, nvlist_t *, nvlist_t **);
|
||||||
|
|
||||||
|
_LIBZFS_CORE_H int lzc_pool_destroy(const char *, const char *, nvlist_t **);
|
||||||
|
_LIBZFS_CORE_H int lzc_pool_export(const char *, const char *, boolean_t,
|
||||||
|
boolean_t, nvlist_t **);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1522,6 +1522,8 @@ typedef enum zfs_ioc {
|
||||||
ZFS_IOC_POOL_SCRUB, /* 0x5a57 */
|
ZFS_IOC_POOL_SCRUB, /* 0x5a57 */
|
||||||
ZFS_IOC_POOL_PREFETCH, /* 0x5158 */
|
ZFS_IOC_POOL_PREFETCH, /* 0x5158 */
|
||||||
ZFS_IOC_POOL_RECYCLE, /* 0x5a59 */
|
ZFS_IOC_POOL_RECYCLE, /* 0x5a59 */
|
||||||
|
ZFS_IOC_POOL_DESTROY_NEW, /* 0x5a59 */
|
||||||
|
ZFS_IOC_POOL_EXPORT_NEW, /* 0x5a5a */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-platform (Optional) - 8/128 numbers reserved.
|
* Per-platform (Optional) - 8/128 numbers reserved.
|
||||||
|
@ -1752,9 +1754,21 @@ typedef enum {
|
||||||
#define ZPOOL_PREFETCH_TYPE "prefetch_type"
|
#define ZPOOL_PREFETCH_TYPE "prefetch_type"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following name is used when invoking ZFS_IOC_POOL_RECYCLE.
|
* The following names are used when invoking ZFS_IOC_POOL_RECYCLE.
|
||||||
*/
|
*/
|
||||||
#define ZPOOL_RECYCLE_DRYRUN "dryrun"
|
#define ZPOOL_RECYCLE_DRYRUN "dryrun"
|
||||||
|
#define ZPOOL_RECYCLE_CLIENTS "clients"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are names used when invoking ZFS_IOC_POOL_EXPORT_NEW.
|
||||||
|
*/
|
||||||
|
#define ZPOOL_EXPORT_FORCE "force"
|
||||||
|
#define ZPOOL_EXPORT_HARDFORCE "hardforce"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Name that is used to convey client information for shared log pools.
|
||||||
|
*/
|
||||||
|
#define ZPOOL_SHARED_LOG_CLIENTS "clients"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for ZFS_IOC_VDEV_SET_STATE
|
* Flags for ZFS_IOC_VDEV_SET_STATE
|
||||||
|
|
|
@ -749,11 +749,11 @@ extern int spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props,
|
extern int spa_import(char *pool, nvlist_t *config, nvlist_t *props,
|
||||||
uint64_t flags);
|
uint64_t flags);
|
||||||
extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
|
extern nvlist_t *spa_tryimport(nvlist_t *tryconfig);
|
||||||
extern int spa_destroy(const char *pool);
|
extern int spa_destroy(const char *pool, nvlist_t *ounvl);
|
||||||
extern int spa_checkpoint(const char *pool);
|
extern int spa_checkpoint(const char *pool);
|
||||||
extern int spa_checkpoint_discard(const char *pool);
|
extern int spa_checkpoint_discard(const char *pool);
|
||||||
extern int spa_export(const char *pool, nvlist_t **oldconfig, boolean_t force,
|
extern int spa_export(const char *pool, nvlist_t **oldconfig, boolean_t force,
|
||||||
boolean_t hardforce);
|
boolean_t hardforce, nvlist_t *outnvl);
|
||||||
extern int spa_reset(const char *pool);
|
extern int spa_reset(const char *pool);
|
||||||
extern void spa_async_request(spa_t *spa, int flag);
|
extern void spa_async_request(spa_t *spa, int flag);
|
||||||
extern void spa_async_unrequest(spa_t *spa, int flag);
|
extern void spa_async_unrequest(spa_t *spa, int flag);
|
||||||
|
@ -1233,7 +1233,9 @@ extern void spa_zil_delete(spa_t *spa, objset_t *os);
|
||||||
extern void spa_zil_header_convert(spa_t *spa, objset_t *os, blkptr_t *bp);
|
extern void spa_zil_header_convert(spa_t *spa, objset_t *os, blkptr_t *bp);
|
||||||
extern void spa_zil_header_mask(spa_t *spa, blkptr_t *bp);
|
extern void spa_zil_header_mask(spa_t *spa, blkptr_t *bp);
|
||||||
extern spa_t *spa_get_shared_log_pool(spa_t *spa);
|
extern spa_t *spa_get_shared_log_pool(spa_t *spa);
|
||||||
extern int spa_recycle(spa_t *spa, boolean_t dryrun, nvlist_t *outnvl);
|
extern int spa_recycle_all(spa_t *spa, boolean_t dryrun, nvlist_t *outnvl);
|
||||||
|
extern int spa_recycle_clients(spa_t *spa, nvlist_t *clients,
|
||||||
|
boolean_t dryrun, nvlist_t *outnvl);
|
||||||
|
|
||||||
/* module param call functions */
|
/* module param call functions */
|
||||||
int param_set_deadman_ziotime(ZFS_MODULE_PARAM_ARGS);
|
int param_set_deadman_ziotime(ZFS_MODULE_PARAM_ARGS);
|
||||||
|
|
|
@ -228,6 +228,8 @@ typedef struct spa_zil_update_head {
|
||||||
uint64_t szuh_id;
|
uint64_t szuh_id;
|
||||||
blkptr_t szuh_chain_head;
|
blkptr_t szuh_chain_head;
|
||||||
boolean_t szuh_set;
|
boolean_t szuh_set;
|
||||||
|
// Only used for the special once-per-pool entry
|
||||||
|
boolean_t szuh_force;
|
||||||
} spa_zil_update_head_t;
|
} spa_zil_update_head_t;
|
||||||
|
|
||||||
typedef struct spa_zil_update {
|
typedef struct spa_zil_update {
|
||||||
|
@ -235,6 +237,11 @@ typedef struct spa_zil_update {
|
||||||
blkptr_t szu_chain_head;
|
blkptr_t szu_chain_head;
|
||||||
} spa_zil_update_t;
|
} spa_zil_update_t;
|
||||||
|
|
||||||
|
typedef struct spa_zil_chain_map_value {
|
||||||
|
char szcmv_pool_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
|
blkptr_t szcmv_bp;
|
||||||
|
} spa_zil_chain_map_value_t;
|
||||||
|
|
||||||
typedef struct spa_chain_map_os {
|
typedef struct spa_chain_map_os {
|
||||||
avl_node_t scmo_avl;
|
avl_node_t scmo_avl;
|
||||||
uint64_t scmo_id;
|
uint64_t scmo_id;
|
||||||
|
@ -244,6 +251,7 @@ typedef struct spa_chain_map_os {
|
||||||
typedef struct spa_chain_map_pool {
|
typedef struct spa_chain_map_pool {
|
||||||
avl_node_t scmp_avl;
|
avl_node_t scmp_avl;
|
||||||
uint64_t scmp_guid;
|
uint64_t scmp_guid;
|
||||||
|
char scmp_name[ZFS_MAX_DATASET_NAME_LEN];
|
||||||
avl_tree_t scmp_os_tree;
|
avl_tree_t scmp_os_tree;
|
||||||
} spa_chain_map_pool_t;
|
} spa_chain_map_pool_t;
|
||||||
|
|
||||||
|
@ -256,7 +264,7 @@ struct spa {
|
||||||
avl_node_t spa_avl; /* node in spa_namespace_avl */
|
avl_node_t spa_avl; /* node in spa_namespace_avl */
|
||||||
avl_node_t spa_log_avl; /* node in spa_shared_log_avl */
|
avl_node_t spa_log_avl; /* node in spa_shared_log_avl */
|
||||||
/* node in spa_registered_clients */
|
/* node in spa_registered_clients */
|
||||||
avl_node_t spa_client_avl;
|
list_node_t spa_client_node;
|
||||||
nvlist_t *spa_config; /* last synced config */
|
nvlist_t *spa_config; /* last synced config */
|
||||||
nvlist_t *spa_config_syncing; /* currently syncing config */
|
nvlist_t *spa_config_syncing; /* currently syncing config */
|
||||||
nvlist_t *spa_config_splitting; /* config for splitting */
|
nvlist_t *spa_config_splitting; /* config for splitting */
|
||||||
|
@ -279,6 +287,11 @@ struct spa {
|
||||||
kthread_t *spa_export_thread; /* valid during pool export */
|
kthread_t *spa_export_thread; /* valid during pool export */
|
||||||
/* true if pool's log device is shared log */
|
/* true if pool's log device is shared log */
|
||||||
boolean_t spa_uses_shared_log;
|
boolean_t spa_uses_shared_log;
|
||||||
|
/*
|
||||||
|
* true if pool was imported with MISSING_LOGS and couldn't find
|
||||||
|
* its shared log pool
|
||||||
|
*/
|
||||||
|
boolean_t spa_discarding_shared_log;
|
||||||
kthread_t *spa_load_thread; /* loading, no namespace lock */
|
kthread_t *spa_load_thread; /* loading, no namespace lock */
|
||||||
metaslab_class_t *spa_normal_class; /* normal data class */
|
metaslab_class_t *spa_normal_class; /* normal data class */
|
||||||
metaslab_class_t *spa_log_class; /* intent log data class */
|
metaslab_class_t *spa_log_class; /* intent log data class */
|
||||||
|
@ -338,7 +351,7 @@ struct spa {
|
||||||
boolean_t spa_extreme_rewind; /* rewind past deferred frees */
|
boolean_t spa_extreme_rewind; /* rewind past deferred frees */
|
||||||
kmutex_t spa_scrub_lock; /* resilver/scrub lock */
|
kmutex_t spa_scrub_lock; /* resilver/scrub lock */
|
||||||
uint64_t spa_scrub_inflight; /* in-flight scrub bytes */
|
uint64_t spa_scrub_inflight; /* in-flight scrub bytes */
|
||||||
boolean_t spa_pool_type; /* normal or object-based */
|
spa_pool_type_t spa_pool_type;
|
||||||
|
|
||||||
/* in-flight verification bytes */
|
/* in-flight verification bytes */
|
||||||
uint64_t spa_load_verify_bytes;
|
uint64_t spa_load_verify_bytes;
|
||||||
|
@ -517,7 +530,7 @@ struct spa {
|
||||||
/* Only used if type is shared log */
|
/* Only used if type is shared log */
|
||||||
kmutex_t spa_chain_map_lock;
|
kmutex_t spa_chain_map_lock;
|
||||||
avl_tree_t spa_chain_map;
|
avl_tree_t spa_chain_map;
|
||||||
avl_tree_t spa_registered_clients;
|
list_t spa_registered_clients;
|
||||||
|
|
||||||
/* Only used during syncing context if using shared log */
|
/* Only used during syncing context if using shared log */
|
||||||
kmutex_t spa_zil_map_lock;
|
kmutex_t spa_zil_map_lock;
|
||||||
|
|
|
@ -599,6 +599,8 @@ extern void zil_commit_impl(zilog_t *zilog, uint64_t oid);
|
||||||
extern void zil_remove_async(zilog_t *zilog, uint64_t oid);
|
extern void zil_remove_async(zilog_t *zilog, uint64_t oid);
|
||||||
|
|
||||||
extern int zil_reset(const char *osname, void *txarg);
|
extern int zil_reset(const char *osname, void *txarg);
|
||||||
|
extern int zil_clear(struct dsl_pool *dp,
|
||||||
|
struct dsl_dataset *ds, void *txarg);
|
||||||
extern int zil_claim(struct dsl_pool *dp,
|
extern int zil_claim(struct dsl_pool *dp,
|
||||||
struct dsl_dataset *ds, void *txarg);
|
struct dsl_dataset *ds, void *txarg);
|
||||||
extern int zil_check_log_chain(struct dsl_pool *dp,
|
extern int zil_check_log_chain(struct dsl_pool *dp,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -246,6 +246,39 @@ zpool_pool_state_to_name(pool_state_t state)
|
||||||
return (gettext("UNKNOWN"));
|
return (gettext("UNKNOWN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct shared_log_cbdata {
|
||||||
|
uint64_t guid;
|
||||||
|
zpool_handle_t *shared_log_pool;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
shared_log_cb(zpool_handle_t *hdl, void *arg)
|
||||||
|
{
|
||||||
|
struct shared_log_cbdata *data = arg;
|
||||||
|
if (fnvlist_lookup_uint64(hdl->zpool_config, ZPOOL_CONFIG_POOL_GUID) ==
|
||||||
|
data->guid) {
|
||||||
|
data->shared_log_pool = hdl;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
zpool_handle_t *
|
||||||
|
zpool_get_shared_log(zpool_handle_t *zhp)
|
||||||
|
{
|
||||||
|
uint64_t guid;
|
||||||
|
if (nvlist_lookup_uint64(zhp->zpool_config,
|
||||||
|
ZPOOL_CONFIG_SHARED_LOG_POOL, &guid) != 0) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
struct shared_log_cbdata data;
|
||||||
|
data.guid = guid;
|
||||||
|
int err = zpool_iter(zhp->zpool_hdl, shared_log_cb, &data);
|
||||||
|
if (err != 0) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (data.shared_log_pool);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a pool handle, return the pool health string ("ONLINE", "DEGRADED",
|
* Given a pool handle, return the pool health string ("ONLINE", "DEGRADED",
|
||||||
* "SUSPENDED", etc).
|
* "SUSPENDED", etc).
|
||||||
|
@ -272,6 +305,10 @@ zpool_get_state_str(zpool_handle_t *zhp)
|
||||||
vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
|
vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
|
||||||
nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc);
|
nvroot, ZPOOL_CONFIG_VDEV_STATS, &vsc);
|
||||||
str = zpool_state_to_name(vs->vs_state, vs->vs_aux);
|
str = zpool_state_to_name(vs->vs_state, vs->vs_aux);
|
||||||
|
zpool_handle_t *shared_log = zpool_get_shared_log(zhp);
|
||||||
|
if (vs->vs_state == VDEV_STATE_HEALTHY && shared_log != NULL) {
|
||||||
|
str = zpool_get_state_str(shared_log);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (str);
|
return (str);
|
||||||
}
|
}
|
||||||
|
@ -1681,23 +1718,48 @@ zpool_destroy(zpool_handle_t *zhp, const char *log_str)
|
||||||
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
char errbuf[ERRBUFLEN];
|
char errbuf[ERRBUFLEN];
|
||||||
|
|
||||||
|
nvlist_t *outnvl;
|
||||||
|
int err = lzc_pool_destroy(zhp->zpool_name, log_str, &outnvl);
|
||||||
|
if (err == ZFS_ERR_IOC_CMD_UNAVAIL) {
|
||||||
if (zhp->zpool_state == POOL_STATE_ACTIVE &&
|
if (zhp->zpool_state == POOL_STATE_ACTIVE &&
|
||||||
(zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM)) == NULL)
|
(zfp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_FILESYSTEM))
|
||||||
|
== NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
(void) strlcpy(zc.zc_name, zhp->zpool_name,
|
||||||
|
sizeof (zc.zc_name));
|
||||||
zc.zc_history = (uint64_t)(uintptr_t)log_str;
|
zc.zc_history = (uint64_t)(uintptr_t)log_str;
|
||||||
|
if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0)
|
||||||
|
err = errno;
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (zfs_ioctl(hdl, ZFS_IOC_POOL_DESTROY, &zc) != 0) {
|
if (err != 0) {
|
||||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||||
"cannot destroy '%s'"), zhp->zpool_name);
|
"cannot destroy '%s'"), zhp->zpool_name);
|
||||||
|
|
||||||
if (errno == EROFS) {
|
if (err == EROFS) {
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"one or more devices is read only"));
|
"one or more devices is read only"));
|
||||||
(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
|
(void) zfs_error(hdl, EZFS_BADDEV, errbuf);
|
||||||
|
} else if (err == EBUSY && outnvl != NULL) {
|
||||||
|
nvlist_t *clients = fnvlist_lookup_nvlist(outnvl,
|
||||||
|
ZPOOL_SHARED_LOG_CLIENTS);
|
||||||
|
nvpair_t *elem = nvlist_next_nvpair(clients, NULL);
|
||||||
|
char buf[ERRBUFLEN];
|
||||||
|
int idx = snprintf(buf, ERRBUFLEN, "%s",
|
||||||
|
nvpair_name(elem));
|
||||||
|
while ((elem = nvlist_next_nvpair(clients, elem))
|
||||||
|
!= NULL && idx < ERRBUFLEN) {
|
||||||
|
idx += snprintf(buf + idx, ERRBUFLEN - idx,
|
||||||
|
", %s", nvpair_name(elem));
|
||||||
|
}
|
||||||
|
zfs_error_aux(hdl, "pool has active clients: %s", buf);
|
||||||
|
(void) zfs_error(hdl, EZFS_BUSY, errbuf);
|
||||||
|
fnvlist_free(outnvl);
|
||||||
} else {
|
} else {
|
||||||
(void) zpool_standard_error(hdl, errno, errbuf);
|
(void) zpool_standard_error(hdl, err, errbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zfp)
|
if (zfp)
|
||||||
|
@ -1897,14 +1959,24 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
|
||||||
{
|
{
|
||||||
zfs_cmd_t zc = {"\0"};
|
zfs_cmd_t zc = {"\0"};
|
||||||
|
|
||||||
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
|
nvlist_t *outnvl;
|
||||||
|
int err = lzc_pool_export(zhp->zpool_name, log_str, force, hardforce,
|
||||||
|
&outnvl);
|
||||||
|
if (err == ZFS_ERR_IOC_CMD_UNAVAIL) {
|
||||||
|
|
||||||
|
(void) strlcpy(zc.zc_name, zhp->zpool_name,
|
||||||
|
sizeof (zc.zc_name));
|
||||||
zc.zc_cookie = force;
|
zc.zc_cookie = force;
|
||||||
zc.zc_guid = hardforce;
|
zc.zc_guid = hardforce;
|
||||||
zc.zc_history = (uint64_t)(uintptr_t)log_str;
|
zc.zc_history = (uint64_t)(uintptr_t)log_str;
|
||||||
|
|
||||||
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0) {
|
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_EXPORT, &zc) != 0)
|
||||||
switch (errno) {
|
err = errno;
|
||||||
case EXDEV:
|
else
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == EXDEV) {
|
||||||
zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(zhp->zpool_hdl, dgettext(TEXT_DOMAIN,
|
||||||
"use '-f' to override the following errors:\n"
|
"use '-f' to override the following errors:\n"
|
||||||
"'%s' has an active shared spare which could be"
|
"'%s' has an active shared spare which could be"
|
||||||
|
@ -1913,12 +1985,27 @@ zpool_export_common(zpool_handle_t *zhp, boolean_t force, boolean_t hardforce,
|
||||||
return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
|
return (zfs_error_fmt(zhp->zpool_hdl, EZFS_ACTIVE_SPARE,
|
||||||
dgettext(TEXT_DOMAIN, "cannot export '%s'"),
|
dgettext(TEXT_DOMAIN, "cannot export '%s'"),
|
||||||
zhp->zpool_name));
|
zhp->zpool_name));
|
||||||
default:
|
} else if (err == EBUSY && outnvl != NULL) {
|
||||||
|
libzfs_handle_t *hdl = zhp->zpool_hdl;
|
||||||
|
nvlist_t *clients = fnvlist_lookup_nvlist(outnvl,
|
||||||
|
ZPOOL_SHARED_LOG_CLIENTS);
|
||||||
|
nvpair_t *elem = nvlist_next_nvpair(clients, NULL);
|
||||||
|
char buf[ERRBUFLEN];
|
||||||
|
int idx = snprintf(buf, ERRBUFLEN, "%s", nvpair_name(elem));
|
||||||
|
while ((elem = nvlist_next_nvpair(clients, elem)) != NULL &&
|
||||||
|
idx < ERRBUFLEN) {
|
||||||
|
idx += snprintf(buf + idx, ERRBUFLEN - idx, ", %s",
|
||||||
|
nvpair_name(elem));
|
||||||
|
}
|
||||||
|
fnvlist_free(outnvl);
|
||||||
|
zfs_error_aux(hdl, "pool has active clients: %s", buf);
|
||||||
|
return (zfs_error_fmt(hdl, EZFS_BUSY, dgettext(TEXT_DOMAIN,
|
||||||
|
"cannot export '%s'"), zhp->zpool_name));
|
||||||
|
} else if (err != 0) {
|
||||||
return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
|
return (zpool_standard_error_fmt(zhp->zpool_hdl, errno,
|
||||||
dgettext(TEXT_DOMAIN, "cannot export '%s'"),
|
dgettext(TEXT_DOMAIN, "cannot export '%s'"),
|
||||||
zhp->zpool_name));
|
zhp->zpool_name));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -2350,6 +2437,11 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
|
||||||
"the maximum allowable length"));
|
"the maximum allowable length"));
|
||||||
(void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
|
(void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
|
||||||
break;
|
break;
|
||||||
|
case ESRCH:
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"shared log pool no longer contains this client"));
|
||||||
|
(void) zfs_error(hdl, EZFS_NOENT, desc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
(void) zpool_standard_error(hdl, error, desc);
|
(void) zpool_standard_error(hdl, error, desc);
|
||||||
zpool_explain_recover(hdl,
|
zpool_explain_recover(hdl,
|
||||||
|
|
|
@ -510,6 +510,10 @@ zpool_get_status(zpool_handle_t *zhp, const char **msgid,
|
||||||
|
|
||||||
zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata,
|
zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata,
|
||||||
compatibility);
|
compatibility);
|
||||||
|
if (ret == ZPOOL_STATUS_OK && zpool_get_shared_log(zhp)) {
|
||||||
|
ret = check_status(zpool_get_shared_log(zhp)->zpool_config,
|
||||||
|
B_FALSE, errata, compatibility);
|
||||||
|
}
|
||||||
|
|
||||||
if (msgid != NULL) {
|
if (msgid != NULL) {
|
||||||
if (ret >= NMSGID)
|
if (ret >= NMSGID)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1929,11 +1929,37 @@ lzc_get_bootenv(const char *pool, nvlist_t **outnvl)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lzc_recycle(const char *pool, boolean_t dryrun, nvlist_t **outnvl)
|
lzc_recycle(const char *pool, nvlist_t *clients, boolean_t dryrun,
|
||||||
|
nvlist_t **outnvl)
|
||||||
{
|
{
|
||||||
nvlist_t *args = fnvlist_alloc();
|
nvlist_t *args = fnvlist_alloc();
|
||||||
fnvlist_add_boolean_value(args, ZPOOL_RECYCLE_DRYRUN, dryrun);
|
fnvlist_add_boolean_value(args, ZPOOL_RECYCLE_DRYRUN, dryrun);
|
||||||
|
if (clients != NULL)
|
||||||
|
fnvlist_add_nvlist(args, ZPOOL_RECYCLE_CLIENTS, clients);
|
||||||
int err = lzc_ioctl(ZFS_IOC_POOL_RECYCLE, pool, args, outnvl);
|
int err = lzc_ioctl(ZFS_IOC_POOL_RECYCLE, pool, args, outnvl);
|
||||||
fnvlist_free(args);
|
fnvlist_free(args);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lzc_pool_destroy(const char *pool, const char *log_str, nvlist_t **outnvl)
|
||||||
|
{
|
||||||
|
nvlist_t *args = fnvlist_alloc();
|
||||||
|
fnvlist_add_string(args, ZPOOL_HIST_CMD, log_str);
|
||||||
|
int err = lzc_ioctl(ZFS_IOC_POOL_DESTROY_NEW, pool, args, outnvl);
|
||||||
|
fnvlist_free(args);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lzc_pool_export(const char *pool, const char *log_str, boolean_t force,
|
||||||
|
boolean_t hardforce, nvlist_t **outnvl)
|
||||||
|
{
|
||||||
|
nvlist_t *args = fnvlist_alloc();
|
||||||
|
fnvlist_add_string(args, ZPOOL_HIST_CMD, log_str);
|
||||||
|
fnvlist_add_boolean_value(args, ZPOOL_EXPORT_FORCE, force);
|
||||||
|
fnvlist_add_boolean_value(args, ZPOOL_EXPORT_HARDFORCE, hardforce);
|
||||||
|
int err = lzc_ioctl(ZFS_IOC_POOL_EXPORT_NEW, pool, args, outnvl);
|
||||||
|
fnvlist_free(args);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,67 @@
|
||||||
</elf-function-symbols>
|
</elf-function-symbols>
|
||||||
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_device.c' language='LANG_C99'>
|
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_device.c' language='LANG_C99'>
|
||||||
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
|
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
|
||||||
|
<type-decl name='int' size-in-bits='32' id='95e97e5e'/>
|
||||||
|
<type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
|
||||||
|
<type-decl name='void' id='48b5725f'/>
|
||||||
|
<enum-decl name='lzbe_flags' id='2b77720b'>
|
||||||
|
<underlying-type type-id='9cac1fee'/>
|
||||||
|
<enumerator name='lzbe_add' value='0'/>
|
||||||
|
<enumerator name='lzbe_replace' value='1'/>
|
||||||
|
</enum-decl>
|
||||||
|
<typedef-decl name='lzbe_flags_t' type-id='2b77720b' id='a1936f04'/>
|
||||||
|
<pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
|
||||||
|
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
||||||
|
<qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
|
||||||
|
<pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
|
||||||
|
<function-decl name='lzbe_set_boot_device' mangled-name='lzbe_set_boot_device' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_set_boot_device'>
|
||||||
|
<parameter type-id='80f4b756' name='pool'/>
|
||||||
|
<parameter type-id='a1936f04' name='flag'/>
|
||||||
|
<parameter type-id='80f4b756' name='device'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='lzbe_get_boot_device' mangled-name='lzbe_get_boot_device' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_get_boot_device'>
|
||||||
|
<parameter type-id='80f4b756' name='pool'/>
|
||||||
|
<parameter type-id='9b23c9ad' name='device'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
</abi-instr>
|
||||||
|
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_pair.c' language='LANG_C99'>
|
||||||
|
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
||||||
|
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
||||||
|
<pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
|
||||||
|
<pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
|
||||||
|
<function-decl name='lzbe_nvlist_get' mangled-name='lzbe_nvlist_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_get'>
|
||||||
|
<parameter type-id='80f4b756' name='pool'/>
|
||||||
|
<parameter type-id='80f4b756' name='key'/>
|
||||||
|
<parameter type-id='63e171df' name='ptr'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='lzbe_nvlist_set' mangled-name='lzbe_nvlist_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_set'>
|
||||||
|
<parameter type-id='80f4b756' name='pool'/>
|
||||||
|
<parameter type-id='80f4b756' name='key'/>
|
||||||
|
<parameter type-id='eaa32e2f' name='ptr'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='lzbe_nvlist_free' mangled-name='lzbe_nvlist_free' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_free'>
|
||||||
|
<parameter type-id='eaa32e2f' name='ptr'/>
|
||||||
|
<return type-id='48b5725f'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='lzbe_add_pair' mangled-name='lzbe_add_pair' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_add_pair'>
|
||||||
|
<parameter type-id='eaa32e2f' name='ptr'/>
|
||||||
|
<parameter type-id='80f4b756' name='key'/>
|
||||||
|
<parameter type-id='80f4b756' name='type'/>
|
||||||
|
<parameter type-id='eaa32e2f' name='value'/>
|
||||||
|
<parameter type-id='b59d7dce' name='size'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
<function-decl name='lzbe_remove_pair' mangled-name='lzbe_remove_pair' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_remove_pair'>
|
||||||
|
<parameter type-id='eaa32e2f' name='ptr'/>
|
||||||
|
<parameter type-id='80f4b756' name='key'/>
|
||||||
|
<return type-id='95e97e5e'/>
|
||||||
|
</function-decl>
|
||||||
|
</abi-instr>
|
||||||
|
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_util.c' language='LANG_C99'>
|
||||||
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8' id='89feb1ec'>
|
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='8' id='89feb1ec'>
|
||||||
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
<subrange length='1' type-id='7359adad' id='52f813b4'/>
|
||||||
</array-type-def>
|
</array-type-def>
|
||||||
|
@ -25,55 +86,9 @@
|
||||||
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
||||||
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
||||||
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
||||||
<class-decl name='libzfs_handle' is-struct='yes' visibility='default' is-declaration-only='yes' id='c8a9d9d8'/>
|
|
||||||
<class-decl name='zpool_handle' is-struct='yes' visibility='default' is-declaration-only='yes' id='67002a8a'/>
|
|
||||||
<type-decl name='int' size-in-bits='32' id='95e97e5e'/>
|
|
||||||
<type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
|
<type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
|
||||||
<type-decl name='signed char' size-in-bits='8' id='28577a57'/>
|
<type-decl name='signed char' size-in-bits='8' id='28577a57'/>
|
||||||
<type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
|
|
||||||
<type-decl name='unsigned int' size-in-bits='32' id='f0981eeb'/>
|
|
||||||
<type-decl name='unsigned long int' size-in-bits='64' id='7359adad'/>
|
|
||||||
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
|
||||||
<type-decl name='variadic parameter type' id='2c1145c5'/>
|
|
||||||
<type-decl name='void' id='48b5725f'/>
|
|
||||||
<typedef-decl name='zpool_handle_t' type-id='67002a8a' id='b1efc708'/>
|
|
||||||
<typedef-decl name='libzfs_handle_t' type-id='c8a9d9d8' id='95942d0c'/>
|
|
||||||
<enum-decl name='lzbe_flags' id='2b77720b'>
|
|
||||||
<underlying-type type-id='9cac1fee'/>
|
|
||||||
<enumerator name='lzbe_add' value='0'/>
|
|
||||||
<enumerator name='lzbe_replace' value='1'/>
|
|
||||||
</enum-decl>
|
|
||||||
<typedef-decl name='lzbe_flags_t' type-id='2b77720b' id='a1936f04'/>
|
|
||||||
<class-decl name='nvlist' size-in-bits='192' is-struct='yes' visibility='default' id='ac266fd9'>
|
|
||||||
<data-member access='public' layout-offset-in-bits='0'>
|
|
||||||
<var-decl name='nvl_version' type-id='3ff5601b' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='32'>
|
|
||||||
<var-decl name='nvl_nvflag' type-id='8f92235e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='64'>
|
|
||||||
<var-decl name='nvl_priv' type-id='9c313c2d' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='128'>
|
|
||||||
<var-decl name='nvl_flag' type-id='8f92235e' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
<data-member access='public' layout-offset-in-bits='160'>
|
|
||||||
<var-decl name='nvl_pad' type-id='3ff5601b' visibility='default'/>
|
|
||||||
</data-member>
|
|
||||||
</class-decl>
|
|
||||||
<typedef-decl name='nvlist_t' type-id='ac266fd9' id='8e8d4be3'/>
|
|
||||||
<enum-decl name='boolean_t' naming-typedef-id='c19b74c3' id='f58c8277'>
|
|
||||||
<underlying-type type-id='9cac1fee'/>
|
|
||||||
<enumerator name='B_FALSE' value='0'/>
|
|
||||||
<enumerator name='B_TRUE' value='1'/>
|
|
||||||
</enum-decl>
|
|
||||||
<typedef-decl name='boolean_t' type-id='f58c8277' id='c19b74c3'/>
|
|
||||||
<typedef-decl name='int32_t' type-id='33f57a65' id='3ff5601b'/>
|
|
||||||
<typedef-decl name='uint32_t' type-id='62f1140c' id='8f92235e'/>
|
|
||||||
<typedef-decl name='uint64_t' type-id='8910171f' id='9c313c2d'/>
|
|
||||||
<typedef-decl name='__int32_t' type-id='95e97e5e' id='33f57a65'/>
|
|
||||||
<typedef-decl name='__uint32_t' type-id='f0981eeb' id='62f1140c'/>
|
|
||||||
<typedef-decl name='__uint64_t' type-id='7359adad' id='8910171f'/>
|
|
||||||
<typedef-decl name='__off_t' type-id='bd54fe1a' id='79989e9c'/>
|
<typedef-decl name='__off_t' type-id='bd54fe1a' id='79989e9c'/>
|
||||||
<typedef-decl name='__off64_t' type-id='bd54fe1a' id='724e4de6'/>
|
<typedef-decl name='__off64_t' type-id='bd54fe1a' id='724e4de6'/>
|
||||||
<typedef-decl name='FILE' type-id='ec1ed955' id='aa12d1ba'/>
|
<typedef-decl name='FILE' type-id='ec1ed955' id='aa12d1ba'/>
|
||||||
|
@ -167,413 +182,15 @@
|
||||||
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
|
||||||
</data-member>
|
</data-member>
|
||||||
</class-decl>
|
</class-decl>
|
||||||
<typedef-decl name='size_t' type-id='7359adad' id='b59d7dce'/>
|
|
||||||
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
|
||||||
<qualified-type-def type-id='822cd80b' restrict='yes' id='e75a27e9'/>
|
|
||||||
<pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
|
<pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
|
||||||
<pointer-type-def type-id='a4036571' size-in-bits='64' id='570f8c59'/>
|
<pointer-type-def type-id='a4036571' size-in-bits='64' id='570f8c59'/>
|
||||||
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
|
||||||
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
|
||||||
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
|
||||||
<pointer-type-def type-id='a84c031d' size-in-bits='64' id='26a90f95'/>
|
|
||||||
<pointer-type-def type-id='26a90f95' size-in-bits='64' id='9b23c9ad'/>
|
|
||||||
<qualified-type-def type-id='9b23c9ad' restrict='yes' id='8c85230f'/>
|
|
||||||
<qualified-type-def type-id='a84c031d' const='yes' id='9b45d938'/>
|
|
||||||
<pointer-type-def type-id='9b45d938' size-in-bits='64' id='80f4b756'/>
|
|
||||||
<qualified-type-def type-id='80f4b756' restrict='yes' id='9d26089a'/>
|
|
||||||
<pointer-type-def type-id='80f4b756' size-in-bits='64' id='7d3cd834'/>
|
|
||||||
<qualified-type-def type-id='8e8d4be3' const='yes' id='693c3853'/>
|
|
||||||
<pointer-type-def type-id='693c3853' size-in-bits='64' id='22cce67b'/>
|
|
||||||
<pointer-type-def type-id='95942d0c' size-in-bits='64' id='b0382bb3'/>
|
|
||||||
<pointer-type-def type-id='8e8d4be3' size-in-bits='64' id='5ce45b60'/>
|
|
||||||
<pointer-type-def type-id='5ce45b60' size-in-bits='64' id='857bb57e'/>
|
|
||||||
<pointer-type-def type-id='9c313c2d' size-in-bits='64' id='5d6479ae'/>
|
|
||||||
<pointer-type-def type-id='48b5725f' size-in-bits='64' id='eaa32e2f'/>
|
|
||||||
<pointer-type-def type-id='b1efc708' size-in-bits='64' id='4c81de99'/>
|
|
||||||
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
|
||||||
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
|
||||||
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
|
||||||
<class-decl name='libzfs_handle' is-struct='yes' visibility='default' is-declaration-only='yes' id='c8a9d9d8'/>
|
|
||||||
<class-decl name='zpool_handle' is-struct='yes' visibility='default' is-declaration-only='yes' id='67002a8a'/>
|
|
||||||
<function-decl name='libzfs_init' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='b0382bb3'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='libzfs_fini' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='b0382bb3'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='libzfs_error_description' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='b0382bb3'/>
|
|
||||||
<return type-id='80f4b756'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='zpool_open' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='b0382bb3'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='4c81de99'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='zpool_close' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='4c81de99'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='zpool_set_bootenv' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='4c81de99'/>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='zpool_get_bootenv' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='4c81de99'/>
|
|
||||||
<parameter type-id='857bb57e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_free' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_lookup_uint64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='5d6479ae'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_lookup_string' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='7d3cd834'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_exists' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='c19b74c3'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fnvlist_alloc' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<return type-id='5ce45b60'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fnvlist_free' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fnvlist_add_uint64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='9c313c2d'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fnvlist_add_string' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='fnvlist_remove' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='free' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='eaa32e2f'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strncmp' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b59d7dce'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strdup' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='26a90f95'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strlen' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='b59d7dce'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='__fprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='e75a27e9'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='__asprintf_chk' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='8c85230f'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<parameter type-id='9d26089a'/>
|
|
||||||
<parameter is-variadic='yes'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_set_boot_device' mangled-name='lzbe_set_boot_device' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_set_boot_device'>
|
|
||||||
<parameter type-id='80f4b756' name='pool'/>
|
|
||||||
<parameter type-id='a1936f04' name='flag'/>
|
|
||||||
<parameter type-id='80f4b756' name='device'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_get_boot_device' mangled-name='lzbe_get_boot_device' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_get_boot_device'>
|
|
||||||
<parameter type-id='80f4b756' name='pool'/>
|
|
||||||
<parameter type-id='9b23c9ad' name='device'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
|
||||||
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_pair.c' language='LANG_C99'>
|
|
||||||
<type-decl name='short int' size-in-bits='16' id='a2185560'/>
|
|
||||||
<type-decl name='unsigned char' size-in-bits='8' id='002ac4a6'/>
|
|
||||||
<typedef-decl name='uchar_t' type-id='002ac4a6' id='d8bf0010'/>
|
|
||||||
<typedef-decl name='uint_t' type-id='f0981eeb' id='3502e3ff'/>
|
|
||||||
<typedef-decl name='int8_t' type-id='2171a512' id='ee31ee44'/>
|
|
||||||
<typedef-decl name='int16_t' type-id='03896e23' id='23bd8cb5'/>
|
|
||||||
<typedef-decl name='int64_t' type-id='0c9942d2' id='9da381c4'/>
|
|
||||||
<typedef-decl name='uint8_t' type-id='c51d6389' id='b96825af'/>
|
|
||||||
<typedef-decl name='uint16_t' type-id='253c2d2a' id='149c6638'/>
|
|
||||||
<typedef-decl name='__int8_t' type-id='28577a57' id='2171a512'/>
|
|
||||||
<typedef-decl name='__uint8_t' type-id='002ac4a6' id='c51d6389'/>
|
|
||||||
<typedef-decl name='__int16_t' type-id='a2185560' id='03896e23'/>
|
|
||||||
<typedef-decl name='__uint16_t' type-id='8efea9e5' id='253c2d2a'/>
|
|
||||||
<typedef-decl name='__int64_t' type-id='bd54fe1a' id='0c9942d2'/>
|
|
||||||
<qualified-type-def type-id='c19b74c3' const='yes' id='12373e33'/>
|
|
||||||
<pointer-type-def type-id='12373e33' size-in-bits='64' id='c5f6c15b'/>
|
|
||||||
<qualified-type-def type-id='80f4b756' const='yes' id='b99c00c9'/>
|
|
||||||
<pointer-type-def type-id='b99c00c9' size-in-bits='64' id='13956559'/>
|
|
||||||
<qualified-type-def type-id='23bd8cb5' const='yes' id='75f7b0c5'/>
|
|
||||||
<pointer-type-def type-id='75f7b0c5' size-in-bits='64' id='a3eb883d'/>
|
|
||||||
<qualified-type-def type-id='3ff5601b' const='yes' id='922df12b'/>
|
|
||||||
<pointer-type-def type-id='922df12b' size-in-bits='64' id='1f526493'/>
|
|
||||||
<qualified-type-def type-id='9da381c4' const='yes' id='f07b7694'/>
|
|
||||||
<pointer-type-def type-id='f07b7694' size-in-bits='64' id='505bed1a'/>
|
|
||||||
<qualified-type-def type-id='ee31ee44' const='yes' id='721c32d4'/>
|
|
||||||
<pointer-type-def type-id='721c32d4' size-in-bits='64' id='a06445da'/>
|
|
||||||
<qualified-type-def type-id='22cce67b' const='yes' id='d2816df0'/>
|
|
||||||
<pointer-type-def type-id='d2816df0' size-in-bits='64' id='3bbfee2e'/>
|
|
||||||
<qualified-type-def type-id='d8bf0010' const='yes' id='a9125480'/>
|
|
||||||
<pointer-type-def type-id='a9125480' size-in-bits='64' id='d1db479e'/>
|
|
||||||
<qualified-type-def type-id='149c6638' const='yes' id='b01a5ac8'/>
|
|
||||||
<pointer-type-def type-id='b01a5ac8' size-in-bits='64' id='1b7d11c6'/>
|
|
||||||
<qualified-type-def type-id='8f92235e' const='yes' id='b9930aae'/>
|
|
||||||
<pointer-type-def type-id='b9930aae' size-in-bits='64' id='a6798dcc'/>
|
|
||||||
<qualified-type-def type-id='9c313c2d' const='yes' id='c3b7ba7d'/>
|
|
||||||
<pointer-type-def type-id='c3b7ba7d' size-in-bits='64' id='713a56f5'/>
|
|
||||||
<qualified-type-def type-id='b96825af' const='yes' id='2b61797f'/>
|
|
||||||
<pointer-type-def type-id='2b61797f' size-in-bits='64' id='9f7200cf'/>
|
|
||||||
<pointer-type-def type-id='eaa32e2f' size-in-bits='64' id='63e171df'/>
|
|
||||||
<function-decl name='nvlist_alloc' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='857bb57e'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_dup' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<parameter type-id='857bb57e'/>
|
|
||||||
<parameter type-id='95e97e5e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_boolean_value' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='c19b74c3'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_byte' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='d8bf0010'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int8' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='ee31ee44'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint8' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='b96825af'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int16' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='23bd8cb5'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint16' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='149c6638'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int32' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='3ff5601b'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint32' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='8f92235e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='9da381c4'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint64' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='9c313c2d'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_string' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_nvlist' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='22cce67b'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_boolean_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='c5f6c15b'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_byte_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='d1db479e'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int8_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='a06445da'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint8_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='9f7200cf'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int16_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='a3eb883d'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint16_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='1b7d11c6'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int32_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='1f526493'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint32_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='a6798dcc'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_int64_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='505bed1a'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_uint64_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='713a56f5'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_string_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='13956559'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_add_nvlist_array' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='3bbfee2e'/>
|
|
||||||
<parameter type-id='3502e3ff'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_remove_all' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='nvlist_lookup_nvlist' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='857bb57e'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='strcmp' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<parameter type-id='80f4b756'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_nvlist_get' mangled-name='lzbe_nvlist_get' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_get'>
|
|
||||||
<parameter type-id='80f4b756' name='pool'/>
|
|
||||||
<parameter type-id='80f4b756' name='key'/>
|
|
||||||
<parameter type-id='63e171df' name='ptr'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_nvlist_set' mangled-name='lzbe_nvlist_set' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_set'>
|
|
||||||
<parameter type-id='80f4b756' name='pool'/>
|
|
||||||
<parameter type-id='80f4b756' name='key'/>
|
|
||||||
<parameter type-id='eaa32e2f' name='ptr'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_nvlist_free' mangled-name='lzbe_nvlist_free' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_nvlist_free'>
|
|
||||||
<parameter type-id='eaa32e2f' name='ptr'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_add_pair' mangled-name='lzbe_add_pair' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_add_pair'>
|
|
||||||
<parameter type-id='eaa32e2f' name='ptr'/>
|
|
||||||
<parameter type-id='80f4b756' name='key'/>
|
|
||||||
<parameter type-id='80f4b756' name='type'/>
|
|
||||||
<parameter type-id='eaa32e2f' name='value'/>
|
|
||||||
<parameter type-id='b59d7dce' name='size'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_remove_pair' mangled-name='lzbe_remove_pair' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_remove_pair'>
|
|
||||||
<parameter type-id='eaa32e2f' name='ptr'/>
|
|
||||||
<parameter type-id='80f4b756' name='key'/>
|
|
||||||
<return type-id='95e97e5e'/>
|
|
||||||
</function-decl>
|
|
||||||
</abi-instr>
|
|
||||||
<abi-instr address-size='64' path='lib/libzfsbootenv/lzbe_util.c' language='LANG_C99'>
|
|
||||||
<function-decl name='nvlist_print' visibility='default' binding='global' size-in-bits='64'>
|
|
||||||
<parameter type-id='822cd80b'/>
|
|
||||||
<parameter type-id='5ce45b60'/>
|
|
||||||
<return type-id='48b5725f'/>
|
|
||||||
</function-decl>
|
|
||||||
<function-decl name='lzbe_bootenv_print' mangled-name='lzbe_bootenv_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_bootenv_print'>
|
<function-decl name='lzbe_bootenv_print' mangled-name='lzbe_bootenv_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_bootenv_print'>
|
||||||
<parameter type-id='80f4b756' name='pool'/>
|
<parameter type-id='80f4b756' name='pool'/>
|
||||||
<parameter type-id='80f4b756' name='nvlist'/>
|
<parameter type-id='80f4b756' name='nvlist'/>
|
||||||
|
|
|
@ -180,8 +180,8 @@ For more information, see the
|
||||||
section.
|
section.
|
||||||
.It Sy shared log
|
.It Sy shared log
|
||||||
A separate ZFS storage pool used as a shared intent log device.
|
A separate ZFS storage pool used as a shared intent log device.
|
||||||
Only one shared log can specified at pool creation or import, and a normal log
|
Only one shared log can be specified at pool creation or import, and a normal
|
||||||
device cannot also be specified.
|
log device cannot also be specified.
|
||||||
For more information, see the
|
For more information, see the
|
||||||
.Sx Intent Log
|
.Sx Intent Log
|
||||||
section.
|
section.
|
||||||
|
|
|
@ -170,6 +170,9 @@ static int zfs_zil_clean_taskq_nthr_pct = 100;
|
||||||
static int zfs_zil_clean_taskq_minalloc = 1024;
|
static int zfs_zil_clean_taskq_minalloc = 1024;
|
||||||
static int zfs_zil_clean_taskq_maxalloc = 1024 * 1024;
|
static int zfs_zil_clean_taskq_maxalloc = 1024 * 1024;
|
||||||
|
|
||||||
|
static unsigned int chain_map_zap_default_bs = 17;
|
||||||
|
static unsigned int chain_map_zap_default_ibs = 15;
|
||||||
|
|
||||||
int
|
int
|
||||||
dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **ddp)
|
dsl_pool_open_special_dir(dsl_pool_t *dp, const char *name, dsl_dir_t **ddp)
|
||||||
{
|
{
|
||||||
|
@ -559,7 +562,8 @@ dsl_pool_create(spa_t *spa, nvlist_t *zplprops __attribute__((unused)),
|
||||||
if (spa_is_shared_log(spa)) {
|
if (spa_is_shared_log(spa)) {
|
||||||
dp->dp_chain_map_obj = zap_create_flags(dp->dp_meta_objset, 0,
|
dp->dp_chain_map_obj = zap_create_flags(dp->dp_meta_objset, 0,
|
||||||
ZAP_FLAG_HASH64 | ZAP_FLAG_UINT64_KEY |
|
ZAP_FLAG_HASH64 | ZAP_FLAG_UINT64_KEY |
|
||||||
ZAP_FLAG_PRE_HASHED_KEY, DMU_OTN_ZAP_METADATA, 0, 0,
|
ZAP_FLAG_PRE_HASHED_KEY, DMU_OTN_ZAP_METADATA,
|
||||||
|
chain_map_zap_default_bs, chain_map_zap_default_ibs,
|
||||||
DMU_OT_NONE, 0, tx);
|
DMU_OT_NONE, 0, tx);
|
||||||
VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
|
VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
|
||||||
DMU_POOL_CHAIN_MAP_OBJ, sizeof (uint64_t), 1,
|
DMU_POOL_CHAIN_MAP_OBJ, sizeof (uint64_t), 1,
|
||||||
|
|
337
module/zfs/spa.c
337
module/zfs/spa.c
|
@ -1725,6 +1725,19 @@ get_shared_log_pool(nvlist_t *config, spa_t **out)
|
||||||
mutex_enter(&result->spa_chain_map_lock);
|
mutex_enter(&result->spa_chain_map_lock);
|
||||||
mutex_exit(&spa_shared_log_lock);
|
mutex_exit(&spa_shared_log_lock);
|
||||||
*out = result;
|
*out = result;
|
||||||
|
|
||||||
|
avl_tree_t *t = &result->spa_chain_map;
|
||||||
|
spa_chain_map_pool_t *search_scmp = kmem_zalloc(sizeof (*search_scmp),
|
||||||
|
KM_SLEEP);
|
||||||
|
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
search_scmp->scmp_guid = guid;
|
||||||
|
spa_chain_map_pool_t *result_scmp = avl_find(t, search_scmp, NULL);
|
||||||
|
kmem_free(search_scmp, sizeof (*search_scmp));
|
||||||
|
if (!result_scmp) {
|
||||||
|
return (ESRCH);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1734,22 +1747,29 @@ extern metaslab_ops_t *metaslab_allocator(spa_t *shared_log);
|
||||||
* Activate an uninitialized pool.
|
* Activate an uninitialized pool.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
spa_activate(spa_t *spa, nvlist_t *config, spa_mode_t mode)
|
spa_activate(spa_t *spa, nvlist_t *config, spa_mode_t mode, boolean_t creating)
|
||||||
{
|
{
|
||||||
metaslab_ops_t *msp = metaslab_allocator(spa);
|
metaslab_ops_t *msp = metaslab_allocator(spa);
|
||||||
ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
|
ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
|
||||||
|
boolean_t missing_logs = spa->spa_import_flags & ZFS_IMPORT_MISSING_LOG;
|
||||||
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
spa_t *shared_log = NULL;
|
spa_t *shared_log = NULL;
|
||||||
if (strcmp(spa->spa_name, TRYIMPORT_NAME) != 0 &&
|
if (strcmp(spa->spa_name, TRYIMPORT_NAME) != 0 &&
|
||||||
(error = get_shared_log_pool(config, &shared_log)) != 0) {
|
(error = get_shared_log_pool(config, &shared_log)) != 0) {
|
||||||
// We handle this case in spa_check_for_missing_logs
|
// We handle the ENOENT case in spa_check_for_missing_logs
|
||||||
if (error == ENOENT &&
|
if (missing_logs && (error == ENOENT || error == ESRCH)) {
|
||||||
(spa->spa_import_flags & ZFS_IMPORT_MISSING_LOG)) {
|
spa->spa_discarding_shared_log = B_TRUE;
|
||||||
error = 0;
|
error = 0;
|
||||||
} else {
|
|
||||||
return (error);
|
|
||||||
}
|
}
|
||||||
|
if (error == ESRCH) {
|
||||||
|
if (creating)
|
||||||
|
error = 0;
|
||||||
|
else
|
||||||
|
mutex_exit(&shared_log->spa_chain_map_lock);
|
||||||
|
}
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
spa->spa_state = POOL_STATE_ACTIVE;
|
spa->spa_state = POOL_STATE_ACTIVE;
|
||||||
|
@ -1758,7 +1778,7 @@ spa_activate(spa_t *spa, nvlist_t *config, spa_mode_t mode)
|
||||||
|
|
||||||
spa->spa_normal_class = metaslab_class_create(spa, msp);
|
spa->spa_normal_class = metaslab_class_create(spa, msp);
|
||||||
if (shared_log != NULL) {
|
if (shared_log != NULL) {
|
||||||
avl_add(&shared_log->spa_registered_clients, spa);
|
list_insert_tail(&shared_log->spa_registered_clients, spa);
|
||||||
mutex_exit(&shared_log->spa_chain_map_lock);
|
mutex_exit(&shared_log->spa_chain_map_lock);
|
||||||
|
|
||||||
spa->spa_log_class = metaslab_class_create(spa,
|
spa->spa_log_class = metaslab_class_create(spa,
|
||||||
|
@ -1840,6 +1860,12 @@ spa_activate(spa_t *spa, nvlist_t *config, spa_mode_t mode)
|
||||||
avl_create(&spa->spa_zil_map,
|
avl_create(&spa->spa_zil_map,
|
||||||
spa_zil_update_head_compare, sizeof (spa_zil_update_head_t),
|
spa_zil_update_head_compare, sizeof (spa_zil_update_head_t),
|
||||||
offsetof(spa_zil_update_head_t, szuh_avl));
|
offsetof(spa_zil_update_head_t, szuh_avl));
|
||||||
|
if (spa->spa_uses_shared_log) {
|
||||||
|
spa_zil_update_head_t *entry = kmem_zalloc(sizeof (*entry),
|
||||||
|
KM_SLEEP);
|
||||||
|
entry->szuh_force = B_TRUE;
|
||||||
|
avl_add(&spa->spa_zil_map, entry);
|
||||||
|
}
|
||||||
|
|
||||||
spa_activate_os(spa);
|
spa_activate_os(spa);
|
||||||
|
|
||||||
|
@ -1960,7 +1986,7 @@ spa_deactivate(spa_t *spa)
|
||||||
spa_t *shared_log;
|
spa_t *shared_log;
|
||||||
if ((shared_log = spa_get_shared_log_pool(spa)) != NULL) {
|
if ((shared_log = spa_get_shared_log_pool(spa)) != NULL) {
|
||||||
mutex_enter(&shared_log->spa_chain_map_lock);
|
mutex_enter(&shared_log->spa_chain_map_lock);
|
||||||
avl_remove(&shared_log->spa_registered_clients, spa);
|
list_remove(&shared_log->spa_registered_clients, spa);
|
||||||
mutex_exit(&shared_log->spa_chain_map_lock);
|
mutex_exit(&shared_log->spa_chain_map_lock);
|
||||||
}
|
}
|
||||||
metaslab_class_destroy(spa->spa_log_class);
|
metaslab_class_destroy(spa->spa_log_class);
|
||||||
|
@ -2655,7 +2681,6 @@ static int
|
||||||
spa_check_for_missing_logs(spa_t *spa)
|
spa_check_for_missing_logs(spa_t *spa)
|
||||||
{
|
{
|
||||||
vdev_t *rvd = spa->spa_root_vdev;
|
vdev_t *rvd = spa->spa_root_vdev;
|
||||||
uint64_t guid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're doing a normal import, then build up any additional
|
* If we're doing a normal import, then build up any additional
|
||||||
|
@ -2702,10 +2727,7 @@ spa_check_for_missing_logs(spa_t *spa)
|
||||||
vdev_dbgmsg_print_tree(rvd, 2);
|
vdev_dbgmsg_print_tree(rvd, 2);
|
||||||
return (SET_ERROR(ENXIO));
|
return (SET_ERROR(ENXIO));
|
||||||
}
|
}
|
||||||
} else if (nvlist_lookup_uint64(spa->spa_config,
|
} else if (spa->spa_discarding_shared_log) {
|
||||||
ZPOOL_CONFIG_SHARED_LOG_POOL, &guid)) {
|
|
||||||
if (spa_uses_shared_log(spa))
|
|
||||||
return (0);
|
|
||||||
spa_set_log_state(spa, SPA_LOG_CLEAR);
|
spa_set_log_state(spa, SPA_LOG_CLEAR);
|
||||||
spa_load_note(spa, "shared log pool is "
|
spa_load_note(spa, "shared log pool is "
|
||||||
"missing, ZIL is dropped.");
|
"missing, ZIL is dropped.");
|
||||||
|
@ -4106,6 +4128,7 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type)
|
||||||
parse = (type == SPA_IMPORT_EXISTING ?
|
parse = (type == SPA_IMPORT_EXISTING ?
|
||||||
VDEV_ALLOC_LOAD : VDEV_ALLOC_SPLIT);
|
VDEV_ALLOC_LOAD : VDEV_ALLOC_SPLIT);
|
||||||
error = spa_config_parse(spa, &rvd, nvtree, NULL, 0, parse);
|
error = spa_config_parse(spa, &rvd, nvtree, NULL, 0, parse);
|
||||||
|
spa_set_pool_type(spa);
|
||||||
spa_config_exit(spa, SCL_ALL, FTAG);
|
spa_config_exit(spa, SCL_ALL, FTAG);
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
|
@ -4484,6 +4507,7 @@ spa_ld_trusted_config(spa_t *spa, spa_import_type_t type,
|
||||||
error);
|
error);
|
||||||
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, error));
|
return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, error));
|
||||||
}
|
}
|
||||||
|
spa_set_pool_type(spa);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Vdev paths in the MOS may be obsolete. If the untrusted config was
|
* Vdev paths in the MOS may be obsolete. If the untrusted config was
|
||||||
|
@ -4776,7 +4800,7 @@ spa_ld_check_features(spa_t *spa, boolean_t *missing_feat_writep)
|
||||||
struct load_chain_map_arg {
|
struct load_chain_map_arg {
|
||||||
blkptr_t *bp;
|
blkptr_t *bp;
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
int *error;
|
uint64_t *error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -4818,11 +4842,11 @@ load_chain_map_cb(void *arg)
|
||||||
kmem_free(lcmca, sizeof (*lcmca));
|
kmem_free(lcmca, sizeof (*lcmca));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
noinline static int
|
||||||
spa_load_chain_map(spa_t *spa)
|
spa_load_chain_map(spa_t *spa)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int dispatch_error = 0;
|
uint64_t dispatch_error = 0;
|
||||||
uint64_t chain_map_zap = spa->spa_dsl_pool->dp_chain_map_obj;
|
uint64_t chain_map_zap = spa->spa_dsl_pool->dp_chain_map_obj;
|
||||||
if (!spa_is_shared_log(spa))
|
if (!spa_is_shared_log(spa))
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -4831,34 +4855,49 @@ spa_load_chain_map(spa_t *spa)
|
||||||
zap_cursor_t zc;
|
zap_cursor_t zc;
|
||||||
zap_attribute_t attr;
|
zap_attribute_t attr;
|
||||||
objset_t *os = spa->spa_dsl_pool->dp_meta_objset;
|
objset_t *os = spa->spa_dsl_pool->dp_meta_objset;
|
||||||
|
spa_zil_chain_map_value_t *szcmv = kmem_alloc(sizeof (*szcmv),
|
||||||
|
KM_SLEEP);
|
||||||
for (zap_cursor_init(&zc, os, chain_map_zap);
|
for (zap_cursor_init(&zc, os, chain_map_zap);
|
||||||
zap_cursor_retrieve(&zc, &attr) == 0; zap_cursor_advance(&zc)) {
|
zap_cursor_retrieve(&zc, &attr) == 0; zap_cursor_advance(&zc)) {
|
||||||
uint64_t pool_guid = ((uint64_t *)attr.za_name)[0];
|
uint64_t pool_guid = ((uint64_t *)attr.za_name)[0];
|
||||||
uint64_t os_guid = ((uint64_t *)attr.za_name)[1];
|
uint64_t os_guid = ((uint64_t *)attr.za_name)[1];
|
||||||
|
error = zap_lookup_uint64(os, chain_map_zap,
|
||||||
|
(uint64_t *)attr.za_name, 2, sizeof (uint64_t),
|
||||||
|
sizeof (*szcmv) / sizeof (uint64_t),
|
||||||
|
szcmv);
|
||||||
|
if (error != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
avl_index_t where;
|
avl_index_t where;
|
||||||
spa_chain_map_pool_t search;
|
spa_chain_map_pool_t search;
|
||||||
search.scmp_guid = pool_guid;
|
search.scmp_guid = pool_guid;
|
||||||
spa_chain_map_pool_t *pool_entry = avl_find(&spa->spa_chain_map,
|
spa_chain_map_pool_t *pool_entry =
|
||||||
&search, &where);
|
avl_find(&spa->spa_chain_map, &search, &where);
|
||||||
if (pool_entry == NULL) {
|
if (pool_entry == NULL) {
|
||||||
pool_entry = kmem_alloc(sizeof (*pool_entry), KM_SLEEP);
|
pool_entry = kmem_alloc(sizeof (*pool_entry),
|
||||||
|
KM_SLEEP);
|
||||||
pool_entry->scmp_guid = pool_guid;
|
pool_entry->scmp_guid = pool_guid;
|
||||||
avl_create(&pool_entry->scmp_os_tree,
|
avl_create(&pool_entry->scmp_os_tree,
|
||||||
spa_chain_map_os_compare,
|
spa_chain_map_os_compare,
|
||||||
sizeof (spa_chain_map_os_t),
|
sizeof (spa_chain_map_os_t),
|
||||||
offsetof(spa_chain_map_os_t, scmo_avl));
|
offsetof(spa_chain_map_os_t, scmo_avl));
|
||||||
|
strlcpy(pool_entry->scmp_name,
|
||||||
|
szcmv->szcmv_pool_name, ZFS_MAX_DATASET_NAME_LEN);
|
||||||
avl_insert(&spa->spa_chain_map, pool_entry, where);
|
avl_insert(&spa->spa_chain_map, pool_entry, where);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (os_guid == 0) {
|
||||||
|
/*
|
||||||
|
* This is the dummy marker to make sure we know about
|
||||||
|
* the pool; no need to add an os-specific entry
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
spa_chain_map_os_t *os_entry = kmem_alloc(sizeof (*os_entry),
|
spa_chain_map_os_t *os_entry = kmem_alloc(sizeof (*os_entry),
|
||||||
KM_SLEEP);
|
KM_SLEEP);
|
||||||
os_entry->scmo_id = os_guid;
|
os_entry->scmo_id = os_guid;
|
||||||
error = zap_lookup_uint64(os, chain_map_zap,
|
os_entry->scmo_chain_head = szcmv->szcmv_bp;
|
||||||
(uint64_t *)attr.za_name, 2, sizeof (uint64_t),
|
|
||||||
sizeof (blkptr_t) / sizeof (uint64_t),
|
|
||||||
&os_entry->scmo_chain_head);
|
|
||||||
if (error != 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
avl_add(&pool_entry->scmp_os_tree, os_entry);
|
avl_add(&pool_entry->scmp_os_tree, os_entry);
|
||||||
struct load_chain_map_arg *arg = kmem_alloc(sizeof (*arg),
|
struct load_chain_map_arg *arg = kmem_alloc(sizeof (*arg),
|
||||||
KM_SLEEP);
|
KM_SLEEP);
|
||||||
|
@ -4868,6 +4907,7 @@ spa_load_chain_map(spa_t *spa)
|
||||||
(void) taskq_dispatch(spa->spa_chain_map_taskq,
|
(void) taskq_dispatch(spa->spa_chain_map_taskq,
|
||||||
load_chain_map_cb, arg, TQ_SLEEP);
|
load_chain_map_cb, arg, TQ_SLEEP);
|
||||||
}
|
}
|
||||||
|
kmem_free(szcmv, sizeof (*szcmv));
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
void *cookie = NULL;
|
void *cookie = NULL;
|
||||||
|
@ -5299,6 +5339,13 @@ spa_ld_claim_log_blocks(spa_t *spa)
|
||||||
(void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
|
(void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
|
||||||
zil_claim, tx, DS_FIND_CHILDREN);
|
zil_claim, tx, DS_FIND_CHILDREN);
|
||||||
dmu_tx_commit(tx);
|
dmu_tx_commit(tx);
|
||||||
|
} else if (spa_get_log_state(spa) == SPA_LOG_CLEAR) {
|
||||||
|
ASSERT(spa->spa_discarding_shared_log);
|
||||||
|
tx = dmu_tx_create_assigned(dp, spa_first_txg(spa));
|
||||||
|
(void) dmu_objset_find_dp(dp, dp->dp_root_dir_obj,
|
||||||
|
zil_clear, tx, DS_FIND_CHILDREN);
|
||||||
|
dmu_tx_commit(tx);
|
||||||
|
spa->spa_discarding_shared_log = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spa->spa_claiming = B_FALSE;
|
spa->spa_claiming = B_FALSE;
|
||||||
|
@ -5346,7 +5393,7 @@ spa_ld_prepare_for_reload(spa_t *spa)
|
||||||
|
|
||||||
spa_unload(spa);
|
spa_unload(spa);
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
VERIFY0(spa_activate(spa, spa->spa_config, mode));
|
VERIFY0(spa_activate(spa, spa->spa_config, mode, B_FALSE));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We save the value of spa_async_suspended as it gets reset to 0 by
|
* We save the value of spa_async_suspended as it gets reset to 0 by
|
||||||
|
@ -5924,7 +5971,7 @@ spa_load_retry(spa_t *spa, spa_load_state_t state)
|
||||||
|
|
||||||
spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
|
spa->spa_load_max_txg = spa->spa_uberblock.ub_txg - 1;
|
||||||
|
|
||||||
VERIFY0(spa_activate(spa, spa->spa_config, mode));
|
VERIFY0(spa_activate(spa, spa->spa_config, mode, B_FALSE));
|
||||||
spa_async_suspend(spa);
|
spa_async_suspend(spa);
|
||||||
|
|
||||||
spa_load_note(spa, "spa_load_retry: rewind, max txg: %llu",
|
spa_load_note(spa, "spa_load_retry: rewind, max txg: %llu",
|
||||||
|
@ -6091,7 +6138,8 @@ spa_open_common(const char *pool, spa_t **spapp, const void *tag,
|
||||||
if (policy.zlp_rewind & ZPOOL_DO_REWIND)
|
if (policy.zlp_rewind & ZPOOL_DO_REWIND)
|
||||||
state = SPA_LOAD_RECOVER;
|
state = SPA_LOAD_RECOVER;
|
||||||
|
|
||||||
error = spa_activate(spa, spa->spa_config, spa_mode_global);
|
error = spa_activate(spa, spa->spa_config, spa_mode_global,
|
||||||
|
B_FALSE);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
if (locked)
|
if (locked)
|
||||||
|
@ -6701,7 +6749,7 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
|
zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot);
|
||||||
spa = spa_add(poolname, nvl, altroot);
|
spa = spa_add(poolname, nvl, altroot);
|
||||||
fnvlist_free(nvl);
|
fnvlist_free(nvl);
|
||||||
error = spa_activate(spa, nvroot, spa_mode_global);
|
error = spa_activate(spa, nvroot, spa_mode_global, B_TRUE);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -6743,15 +6791,8 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_shared_log && spa_uses_shared_log(spa)) {
|
if (!has_shared_log && (spa_uses_shared_log(spa) ||
|
||||||
spa_deactivate(spa);
|
fnvlist_lookup_boolean(nvroot, ZPOOL_CONFIG_IS_SHARED_LOG))) {
|
||||||
spa_remove(spa);
|
|
||||||
mutex_exit(&spa_namespace_lock);
|
|
||||||
return (SET_ERROR(ENOTSUP));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_shared_log && fnvlist_lookup_boolean(nvroot,
|
|
||||||
ZPOOL_CONFIG_IS_SHARED_LOG)) {
|
|
||||||
spa_deactivate(spa);
|
spa_deactivate(spa);
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -6808,6 +6849,8 @@ spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props,
|
||||||
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
|
||||||
|
|
||||||
error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD);
|
error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD);
|
||||||
|
if (error == 0)
|
||||||
|
spa_set_pool_type(spa);
|
||||||
|
|
||||||
ASSERT(error != 0 || rvd != NULL);
|
ASSERT(error != 0 || rvd != NULL);
|
||||||
ASSERT(error != 0 || spa->spa_root_vdev == rvd);
|
ASSERT(error != 0 || spa->spa_root_vdev == rvd);
|
||||||
|
@ -7050,7 +7093,7 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = spa_activate(spa, config, mode);
|
error = spa_activate(spa, config, mode, B_FALSE);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -7211,7 +7254,17 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
mutex_enter(&spa_namespace_lock);
|
mutex_enter(&spa_namespace_lock);
|
||||||
spa = spa_add(name, tryconfig, NULL);
|
spa = spa_add(name, tryconfig, NULL);
|
||||||
kmem_free(name, MAXPATHLEN);
|
kmem_free(name, MAXPATHLEN);
|
||||||
error = spa_activate(spa, tryconfig, SPA_MODE_READ);
|
|
||||||
|
/*
|
||||||
|
* spa_import() relies on a pool config fetched by spa_try_import()
|
||||||
|
* for spare/cache devices. Import flags are not passed to
|
||||||
|
* spa_tryimport(), which makes it return early due to a missing log
|
||||||
|
* device and missing retrieving the cache device and spare eventually.
|
||||||
|
* Passing ZFS_IMPORT_MISSING_LOG to spa_tryimport() makes it fetch
|
||||||
|
* the correct configuration regardless of the missing log device.
|
||||||
|
*/
|
||||||
|
spa->spa_import_flags |= ZFS_IMPORT_MISSING_LOG;
|
||||||
|
error = spa_activate(spa, tryconfig, SPA_MODE_READ, B_FALSE);
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
spa_remove(spa);
|
spa_remove(spa);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
|
@ -7239,16 +7292,6 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
spa->spa_config_source = SPA_CONFIG_SRC_SCAN;
|
spa->spa_config_source = SPA_CONFIG_SRC_SCAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* spa_import() relies on a pool config fetched by spa_try_import()
|
|
||||||
* for spare/cache devices. Import flags are not passed to
|
|
||||||
* spa_tryimport(), which makes it return early due to a missing log
|
|
||||||
* device and missing retrieving the cache device and spare eventually.
|
|
||||||
* Passing ZFS_IMPORT_MISSING_LOG to spa_tryimport() makes it fetch
|
|
||||||
* the correct configuration regardless of the missing log device.
|
|
||||||
*/
|
|
||||||
spa->spa_import_flags |= ZFS_IMPORT_MISSING_LOG;
|
|
||||||
|
|
||||||
error = spa_load(spa, SPA_LOAD_TRYIMPORT, SPA_IMPORT_EXISTING);
|
error = spa_load(spa, SPA_LOAD_TRYIMPORT, SPA_IMPORT_EXISTING);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7269,7 +7312,6 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
uint64_t shared_log_guid;
|
uint64_t shared_log_guid;
|
||||||
if (nvlist_lookup_uint64(tryconfig,
|
if (nvlist_lookup_uint64(tryconfig,
|
||||||
ZPOOL_CONFIG_SHARED_LOG_POOL, &shared_log_guid) == 0) {
|
ZPOOL_CONFIG_SHARED_LOG_POOL, &shared_log_guid) == 0) {
|
||||||
zfs_dbgmsg("in tryimport: got %llu", (unsigned long long) shared_log_guid);
|
|
||||||
fnvlist_add_uint64(config, ZPOOL_CONFIG_SHARED_LOG_POOL,
|
fnvlist_add_uint64(config, ZPOOL_CONFIG_SHARED_LOG_POOL,
|
||||||
shared_log_guid);
|
shared_log_guid);
|
||||||
}
|
}
|
||||||
|
@ -7335,7 +7377,7 @@ spa_tryimport(nvlist_t *tryconfig)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
boolean_t force, boolean_t hardforce)
|
boolean_t force, boolean_t hardforce, nvlist_t *outnvl)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
|
@ -7355,7 +7397,19 @@ spa_export_common(const char *pool, int new_state, nvlist_t **oldconfig,
|
||||||
|
|
||||||
if (spa_is_shared_log(spa)) {
|
if (spa_is_shared_log(spa)) {
|
||||||
mutex_enter(&spa->spa_chain_map_lock);
|
mutex_enter(&spa->spa_chain_map_lock);
|
||||||
if (avl_numnodes(&spa->spa_registered_clients) != 0) {
|
if (!list_is_empty(&spa->spa_registered_clients)) {
|
||||||
|
if (outnvl != NULL) {
|
||||||
|
spa_t *client;
|
||||||
|
list_t *l = &spa->spa_registered_clients;
|
||||||
|
nvlist_t *clients = fnvlist_alloc();
|
||||||
|
for (client = list_head(l); client != NULL;
|
||||||
|
client = list_next(l, client)) {
|
||||||
|
fnvlist_add_boolean(clients,
|
||||||
|
spa_name(client));
|
||||||
|
}
|
||||||
|
fnvlist_add_nvlist(outnvl,
|
||||||
|
ZPOOL_SHARED_LOG_CLIENTS, clients);
|
||||||
|
}
|
||||||
mutex_exit(&spa->spa_chain_map_lock);
|
mutex_exit(&spa->spa_chain_map_lock);
|
||||||
mutex_exit(&spa_namespace_lock);
|
mutex_exit(&spa_namespace_lock);
|
||||||
return (SET_ERROR(EBUSY));
|
return (SET_ERROR(EBUSY));
|
||||||
|
@ -7539,10 +7593,10 @@ fail:
|
||||||
* Destroy a storage pool.
|
* Destroy a storage pool.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
spa_destroy(const char *pool)
|
spa_destroy(const char *pool, nvlist_t *outnvl)
|
||||||
{
|
{
|
||||||
return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL,
|
return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL,
|
||||||
B_FALSE, B_FALSE));
|
B_FALSE, B_FALSE, outnvl));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7550,10 +7604,10 @@ spa_destroy(const char *pool)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
spa_export(const char *pool, nvlist_t **oldconfig, boolean_t force,
|
spa_export(const char *pool, nvlist_t **oldconfig, boolean_t force,
|
||||||
boolean_t hardforce)
|
boolean_t hardforce, nvlist_t *outnvl)
|
||||||
{
|
{
|
||||||
return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig,
|
return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig,
|
||||||
force, hardforce));
|
force, hardforce, outnvl));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7564,7 +7618,7 @@ int
|
||||||
spa_reset(const char *pool)
|
spa_reset(const char *pool)
|
||||||
{
|
{
|
||||||
return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL,
|
return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL,
|
||||||
B_FALSE, B_FALSE));
|
B_FALSE, B_FALSE, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8840,7 +8894,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config,
|
||||||
if (zio_injection_enabled)
|
if (zio_injection_enabled)
|
||||||
zio_handle_panic_injection(spa, FTAG, 1);
|
zio_handle_panic_injection(spa, FTAG, 1);
|
||||||
|
|
||||||
VERIFY0(spa_activate(newspa, config, spa_mode_global));
|
VERIFY0(spa_activate(newspa, config, spa_mode_global, B_TRUE));
|
||||||
spa_async_suspend(newspa);
|
spa_async_suspend(newspa);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8959,7 +9013,7 @@ spa_vdev_split_mirror(spa_t *spa, const char *newname, nvlist_t *config,
|
||||||
/* if we're not going to mount the filesystems in userland, export */
|
/* if we're not going to mount the filesystems in userland, export */
|
||||||
if (exp)
|
if (exp)
|
||||||
error = spa_export_common(newname, POOL_STATE_EXPORTED, NULL,
|
error = spa_export_common(newname, POOL_STATE_EXPORTED, NULL,
|
||||||
B_FALSE, B_FALSE);
|
B_FALSE, B_FALSE, NULL);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
@ -11464,6 +11518,7 @@ spa_chain_map_update(spa_t *spa)
|
||||||
spa_chain_map_os_compare,
|
spa_chain_map_os_compare,
|
||||||
sizeof (spa_chain_map_os_t),
|
sizeof (spa_chain_map_os_t),
|
||||||
offsetof(spa_chain_map_os_t, scmo_avl));
|
offsetof(spa_chain_map_os_t, scmo_avl));
|
||||||
|
strcpy(pool_entry->scmp_name, spa_name(spa));
|
||||||
avl_insert(&target->spa_chain_map, pool_entry, where);
|
avl_insert(&target->spa_chain_map, pool_entry, where);
|
||||||
}
|
}
|
||||||
avl_tree_t *target_tree = &pool_entry->scmp_os_tree;
|
avl_tree_t *target_tree = &pool_entry->scmp_os_tree;
|
||||||
|
@ -11484,17 +11539,37 @@ spa_chain_map_update(spa_t *spa)
|
||||||
list_create(&local_frees, sizeof (spa_zil_update_t),
|
list_create(&local_frees, sizeof (spa_zil_update_t),
|
||||||
offsetof(spa_zil_update_t, szu_list));
|
offsetof(spa_zil_update_t, szu_list));
|
||||||
spa_zil_update_head_t *node;
|
spa_zil_update_head_t *node;
|
||||||
uint64_t buf[2];
|
uint64_t keybuf[2];
|
||||||
buf[0] = spa_guid(spa);
|
keybuf[0] = spa_guid(spa);
|
||||||
for (node = avl_first(t); node; node = AVL_NEXT(t, node)) {
|
spa_zil_chain_map_value_t szcmv = {0};
|
||||||
|
strcpy(szcmv.szcmv_pool_name, spa_name(spa));
|
||||||
|
for (node = avl_first(t); node; ) {
|
||||||
uint64_t guid = node->szuh_id;
|
uint64_t guid = node->szuh_id;
|
||||||
|
|
||||||
|
if (node->szuh_force) {
|
||||||
|
ASSERT0(node->szuh_id);
|
||||||
|
ASSERT(BP_IS_HOLE(&node->szuh_chain_head));
|
||||||
|
keybuf[1] = 0;
|
||||||
|
int res = zap_add_uint64(target_mos, chain_map_zap,
|
||||||
|
keybuf, sizeof (keybuf) / sizeof (uint64_t),
|
||||||
|
sizeof (uint64_t), sizeof (szcmv) /
|
||||||
|
sizeof (uint64_t), (uint64_t *)&szcmv, tx);
|
||||||
|
IMPLY(res != 0, res == EEXIST);
|
||||||
|
spa_zil_update_head_t *next = AVL_NEXT(t, node);
|
||||||
|
avl_remove(t, node);
|
||||||
|
kmem_free(node, sizeof (*node));
|
||||||
|
node = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
list_t *l = &node->szuh_list;
|
list_t *l = &node->szuh_list;
|
||||||
spa_zil_update_t *szu = list_head(l);
|
spa_zil_update_t *szu = list_head(l);
|
||||||
if (!node->szuh_set || szu == NULL ||
|
if (!node->szuh_set || szu == NULL ||
|
||||||
BP_IS_HOLE(&node->szuh_chain_head)) {
|
BP_IS_HOLE(&node->szuh_chain_head)) {
|
||||||
|
node = AVL_NEXT(t, node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
buf[1] = guid;
|
keybuf[1] = guid;
|
||||||
spa_chain_map_os_t osearch;
|
spa_chain_map_os_t osearch;
|
||||||
osearch.scmo_id = guid;
|
osearch.scmo_id = guid;
|
||||||
spa_chain_map_os_t *os_entry = avl_find(target_tree,
|
spa_chain_map_os_t *os_entry = avl_find(target_tree,
|
||||||
|
@ -11524,18 +11599,21 @@ spa_chain_map_update(spa_t *spa)
|
||||||
os_entry->scmo_id = guid;
|
os_entry->scmo_id = guid;
|
||||||
os_entry->scmo_chain_head = node->szuh_chain_head;
|
os_entry->scmo_chain_head = node->szuh_chain_head;
|
||||||
avl_insert(&pool_entry->scmp_os_tree, os_entry, where);
|
avl_insert(&pool_entry->scmp_os_tree, os_entry, where);
|
||||||
blkptr_t *bp = &os_entry->scmo_chain_head;
|
szcmv.szcmv_bp = os_entry->scmo_chain_head;
|
||||||
|
|
||||||
zap_add_uint64(target_mos, chain_map_zap, buf, 2,
|
VERIFY0(zap_add_uint64(target_mos, chain_map_zap,
|
||||||
sizeof (uint64_t), sizeof (*bp) / sizeof (uint64_t),
|
keybuf, sizeof (keybuf) / sizeof (uint64_t),
|
||||||
bp, tx);
|
sizeof (uint64_t), sizeof (szcmv) /
|
||||||
|
sizeof (uint64_t), (uint64_t *)&szcmv, tx));
|
||||||
} else {
|
} else {
|
||||||
os_entry->scmo_chain_head = node->szuh_chain_head;
|
os_entry->scmo_chain_head = node->szuh_chain_head;
|
||||||
blkptr_t *bp = &os_entry->scmo_chain_head;
|
szcmv.szcmv_bp = os_entry->scmo_chain_head;
|
||||||
zap_update_uint64(target_mos, chain_map_zap, buf, 2,
|
VERIFY0(zap_update_uint64(target_mos, chain_map_zap,
|
||||||
sizeof (uint64_t), sizeof (*bp) / sizeof (uint64_t),
|
keybuf, sizeof (keybuf) / sizeof (uint64_t),
|
||||||
bp, tx);
|
sizeof (uint64_t), sizeof (szcmv) /
|
||||||
|
sizeof (uint64_t), (uint64_t *)&szcmv, tx));
|
||||||
}
|
}
|
||||||
|
node = AVL_NEXT(t, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -11561,9 +11639,10 @@ spa_chain_map_update(spa_t *spa)
|
||||||
avl_remove(target_tree, tree_entry);
|
avl_remove(target_tree, tree_entry);
|
||||||
kmem_free(tree_entry, sizeof (*tree_entry));
|
kmem_free(tree_entry, sizeof (*tree_entry));
|
||||||
|
|
||||||
buf[1] = entry->zde_guid;
|
keybuf[1] = entry->zde_guid;
|
||||||
kmem_free(entry, sizeof (*entry));
|
kmem_free(entry, sizeof (*entry));
|
||||||
zap_remove_uint64(target_mos, chain_map_zap, buf, 2, tx);
|
VERIFY0(zap_remove_uint64(target_mos, chain_map_zap, keybuf, 2,
|
||||||
|
tx));
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&target->spa_chain_map_lock);
|
mutex_exit(&target->spa_chain_map_lock);
|
||||||
|
@ -11653,33 +11732,36 @@ spa_zil_header_mask(spa_t *spa, blkptr_t *bp)
|
||||||
*bp = masked;
|
*bp = masked;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
spa_recycle(spa_t *spa, boolean_t dryrun, nvlist_t *outnvl)
|
spa_recycle_one(spa_t *spa, spa_chain_map_pool_t *entry, boolean_t dryrun,
|
||||||
|
nvlist_t *outnvl)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (!spa_is_shared_log(spa)) {
|
|
||||||
return (SET_ERROR(ENOTSUP));
|
|
||||||
}
|
|
||||||
|
|
||||||
spa_t *search = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
|
|
||||||
mutex_enter(&spa->spa_chain_map_lock);
|
|
||||||
avl_tree_t *t = &spa->spa_chain_map;
|
|
||||||
spa_chain_map_pool_t *entry = avl_first(t);
|
|
||||||
while (entry != NULL) {
|
|
||||||
uint64_t guid = entry->scmp_guid;
|
uint64_t guid = entry->scmp_guid;
|
||||||
|
spa_t *search = kmem_zalloc(sizeof (spa_t), KM_SLEEP);
|
||||||
search->spa_config_guid = guid;
|
search->spa_config_guid = guid;
|
||||||
spa_t *client = avl_find(&spa->spa_registered_clients, search,
|
|
||||||
NULL);
|
spa_t *client;
|
||||||
spa_chain_map_pool_t *next = AVL_NEXT(t, entry);
|
list_t *l = &spa->spa_registered_clients;
|
||||||
|
for (client = list_head(l); client != NULL;
|
||||||
|
client = list_next(l, client)) {
|
||||||
|
if (spa_const_guid(client) == entry->scmp_guid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!client) {
|
if (!client) {
|
||||||
char buf[64];
|
fnvlist_add_uint64(outnvl, entry->scmp_name, guid);
|
||||||
snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)guid);
|
|
||||||
fnvlist_add_boolean(outnvl, buf);
|
|
||||||
}
|
}
|
||||||
if (dryrun || client) {
|
if (dryrun || client) {
|
||||||
entry = next;
|
return (err);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t chain_map_zap = spa->spa_dsl_pool->dp_chain_map_obj;
|
||||||
|
dmu_tx_t *tx = dmu_tx_create_mos(spa->spa_dsl_pool);
|
||||||
|
dmu_tx_hold_zap(tx, chain_map_zap, B_TRUE, NULL);
|
||||||
|
dmu_tx_assign(tx, TXG_WAIT);
|
||||||
|
uint64_t keybuf[2];
|
||||||
|
keybuf[0] = entry->scmp_guid;
|
||||||
|
|
||||||
avl_tree_t *os_tree = &entry->scmp_os_tree;
|
avl_tree_t *os_tree = &entry->scmp_os_tree;
|
||||||
spa_chain_map_os_t *os = NULL;
|
spa_chain_map_os_t *os = NULL;
|
||||||
void *cookie = NULL;
|
void *cookie = NULL;
|
||||||
|
@ -11688,20 +11770,73 @@ spa_recycle(spa_t *spa, boolean_t dryrun, nvlist_t *outnvl)
|
||||||
arg.smcfca_end = NULL;
|
arg.smcfca_end = NULL;
|
||||||
arg.smcfca_guid = os->scmo_id;
|
arg.smcfca_guid = os->scmo_id;
|
||||||
arg.smcfca_txg = spa->spa_syncing_txg;
|
arg.smcfca_txg = spa->spa_syncing_txg;
|
||||||
int this_err = zil_parse_raw(spa, &os->scmo_chain_head,
|
(void) zil_parse_raw(spa, &os->scmo_chain_head,
|
||||||
spa_chain_map_free_blk_cb,
|
spa_chain_map_free_blk_cb, spa_chain_map_free_lr_cb, &arg);
|
||||||
spa_chain_map_free_lr_cb, &arg);
|
|
||||||
if (this_err != 0 && err == 0)
|
keybuf[1] = os->scmo_id;
|
||||||
err = this_err;
|
zap_remove_uint64(spa->spa_dsl_pool->dp_meta_objset,
|
||||||
|
chain_map_zap, keybuf, sizeof (keybuf) / sizeof (uint64_t),
|
||||||
|
tx);
|
||||||
kmem_free(os, sizeof (*os));
|
kmem_free(os, sizeof (*os));
|
||||||
}
|
}
|
||||||
avl_remove(t, entry);
|
dmu_tx_commit(tx);
|
||||||
avl_destroy(&entry->scmp_os_tree);
|
avl_destroy(&entry->scmp_os_tree);
|
||||||
|
kmem_free(search, sizeof (*search));
|
||||||
|
|
||||||
|
avl_remove(&spa->spa_chain_map, entry);
|
||||||
kmem_free(entry, sizeof (*entry));
|
kmem_free(entry, sizeof (*entry));
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spa_recycle_all(spa_t *spa, boolean_t dryrun, nvlist_t *outnvl)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
if (!spa_is_shared_log(spa)) {
|
||||||
|
return (SET_ERROR(ENOTSUP));
|
||||||
|
}
|
||||||
|
mutex_enter(&spa->spa_chain_map_lock);
|
||||||
|
avl_tree_t *t = &spa->spa_chain_map;
|
||||||
|
spa_chain_map_pool_t *entry = avl_first(t);
|
||||||
|
while (entry != NULL) {
|
||||||
|
spa_chain_map_pool_t *next = AVL_NEXT(t, entry);
|
||||||
|
|
||||||
|
int this_err = spa_recycle_one(spa, entry, dryrun, outnvl);
|
||||||
|
if (this_err != 0 && err == 0)
|
||||||
|
err = this_err;
|
||||||
|
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
mutex_exit(&spa->spa_chain_map_lock);
|
mutex_exit(&spa->spa_chain_map_lock);
|
||||||
kmem_free(search, sizeof (*search));
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spa_recycle_clients(spa_t *spa, nvlist_t *clients, boolean_t dryrun,
|
||||||
|
nvlist_t *outnvl)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
if (!spa_is_shared_log(spa)) {
|
||||||
|
return (SET_ERROR(ENOTSUP));
|
||||||
|
}
|
||||||
|
mutex_enter(&spa->spa_chain_map_lock);
|
||||||
|
for (nvpair_t *pair = nvlist_next_nvpair(clients, NULL);
|
||||||
|
pair != NULL; pair = nvlist_next_nvpair(clients, pair)) {
|
||||||
|
avl_tree_t *t = &spa->spa_chain_map;
|
||||||
|
spa_chain_map_pool_t *entry = avl_first(t);
|
||||||
|
while (entry != NULL) {
|
||||||
|
spa_chain_map_pool_t *next = AVL_NEXT(t, entry);
|
||||||
|
|
||||||
|
if (strcmp(entry->scmp_name, nvpair_name(pair)) != 0) {
|
||||||
|
entry = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = spa_recycle_one(spa, entry, dryrun, outnvl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_exit(&spa->spa_chain_map_lock);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,6 +482,7 @@ spa_uses_shared_log(const spa_t *spa)
|
||||||
return (spa->spa_uses_shared_log);
|
return (spa->spa_uses_shared_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ==========================================================================
|
* ==========================================================================
|
||||||
* SPA config locking
|
* SPA config locking
|
||||||
|
@ -825,8 +826,8 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
|
||||||
sizeof (metaslab_t), offsetof(metaslab_t, ms_spa_txg_node));
|
sizeof (metaslab_t), offsetof(metaslab_t, ms_spa_txg_node));
|
||||||
avl_create(&spa->spa_sm_logs_by_txg, spa_log_sm_sort_by_txg,
|
avl_create(&spa->spa_sm_logs_by_txg, spa_log_sm_sort_by_txg,
|
||||||
sizeof (spa_log_sm_t), offsetof(spa_log_sm_t, sls_node));
|
sizeof (spa_log_sm_t), offsetof(spa_log_sm_t, sls_node));
|
||||||
avl_create(&spa->spa_registered_clients, spa_guid_compare,
|
list_create(&spa->spa_registered_clients, sizeof (spa_t),
|
||||||
sizeof (spa_t), offsetof(spa_t, spa_client_avl));
|
offsetof(spa_t, spa_client_node));
|
||||||
list_create(&spa->spa_log_summary, sizeof (log_summary_entry_t),
|
list_create(&spa->spa_log_summary, sizeof (log_summary_entry_t),
|
||||||
offsetof(log_summary_entry_t, lse_node));
|
offsetof(log_summary_entry_t, lse_node));
|
||||||
|
|
||||||
|
@ -931,7 +932,7 @@ spa_remove(spa_t *spa)
|
||||||
|
|
||||||
avl_destroy(&spa->spa_metaslabs_by_flushed);
|
avl_destroy(&spa->spa_metaslabs_by_flushed);
|
||||||
avl_destroy(&spa->spa_sm_logs_by_txg);
|
avl_destroy(&spa->spa_sm_logs_by_txg);
|
||||||
avl_destroy(&spa->spa_registered_clients);
|
list_destroy(&spa->spa_registered_clients);
|
||||||
list_destroy(&spa->spa_log_summary);
|
list_destroy(&spa->spa_log_summary);
|
||||||
list_destroy(&spa->spa_config_list);
|
list_destroy(&spa->spa_config_list);
|
||||||
list_destroy(&spa->spa_leaf_list);
|
list_destroy(&spa->spa_leaf_list);
|
||||||
|
|
|
@ -332,7 +332,7 @@ zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
|
||||||
if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
|
if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
|
||||||
uint64_t *thiskey =
|
uint64_t *thiskey =
|
||||||
kmem_alloc(array_numints * sizeof (*thiskey), KM_SLEEP);
|
kmem_alloc(array_numints * sizeof (*thiskey), KM_SLEEP);
|
||||||
ASSERT(zn->zn_key_intlen == sizeof (*thiskey));
|
ASSERT3S(zn->zn_key_intlen, ==, sizeof (*thiskey));
|
||||||
|
|
||||||
zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
|
zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
|
||||||
sizeof (*thiskey), array_numints, thiskey);
|
sizeof (*thiskey), array_numints, thiskey);
|
||||||
|
@ -342,7 +342,7 @@ zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
|
||||||
return (match);
|
return (match);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(zn->zn_key_intlen == 1);
|
ASSERT3S(zn->zn_key_intlen, ==, 1);
|
||||||
if (zn->zn_matchtype & MT_NORMALIZE) {
|
if (zn->zn_matchtype & MT_NORMALIZE) {
|
||||||
char *thisname = kmem_alloc(array_numints, KM_SLEEP);
|
char *thisname = kmem_alloc(array_numints, KM_SLEEP);
|
||||||
|
|
||||||
|
|
|
@ -353,19 +353,24 @@ zpl_earlier_version(const char *name, int version)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zfs_log_history(zfs_cmd_t *zc)
|
zfs_log_history_string(const char *pool, const char *buf)
|
||||||
{
|
{
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
char *buf;
|
if (spa_open(pool, &spa, FTAG) == 0) {
|
||||||
|
|
||||||
if ((buf = history_str_get(zc)) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
|
|
||||||
if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
|
if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
|
||||||
(void) spa_history_log(spa, buf);
|
(void) spa_history_log(spa, buf);
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
zfs_log_history(zfs_cmd_t *zc)
|
||||||
|
{
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if ((buf = history_str_get(zc)) == NULL)
|
||||||
|
return;
|
||||||
|
zfs_log_history_string(zc->zc_name, buf);
|
||||||
history_str_free(buf);
|
history_str_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1502,7 +1507,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
|
||||||
*/
|
*/
|
||||||
if (!error && (error = zfs_set_prop_nvlist(spa_name,
|
if (!error && (error = zfs_set_prop_nvlist(spa_name,
|
||||||
ZPROP_SRC_LOCAL, rootprops, NULL)) != 0) {
|
ZPROP_SRC_LOCAL, rootprops, NULL)) != 0) {
|
||||||
(void) spa_destroy(spa_name);
|
(void) spa_destroy(spa_name, NULL);
|
||||||
unload_wkey = B_FALSE; /* spa_destroy() unloads wrapping keys */
|
unload_wkey = B_FALSE; /* spa_destroy() unloads wrapping keys */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1521,7 +1526,23 @@ zfs_ioc_pool_destroy(zfs_cmd_t *zc)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
zfs_log_history(zc);
|
zfs_log_history(zc);
|
||||||
error = spa_destroy(zc->zc_name);
|
error = spa_destroy(zc->zc_name, NULL);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const zfs_ioc_key_t zfs_keys_pool_destroy_new[] = {
|
||||||
|
{ZPOOL_HIST_CMD, DATA_TYPE_STRING, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_ioc_pool_destroy_new(const char *pool, nvlist_t *innvl, nvlist_t *outnvl)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
zfs_log_history_string(pool, fnvlist_lookup_string(innvl,
|
||||||
|
ZPOOL_HIST_CMD));
|
||||||
|
error = spa_destroy(pool, outnvl);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -1571,7 +1592,28 @@ zfs_ioc_pool_export(zfs_cmd_t *zc)
|
||||||
boolean_t hardforce = (boolean_t)zc->zc_guid;
|
boolean_t hardforce = (boolean_t)zc->zc_guid;
|
||||||
|
|
||||||
zfs_log_history(zc);
|
zfs_log_history(zc);
|
||||||
error = spa_export(zc->zc_name, NULL, force, hardforce);
|
error = spa_export(zc->zc_name, NULL, force, hardforce, NULL);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const zfs_ioc_key_t zfs_keys_pool_export_new[] = {
|
||||||
|
{ZPOOL_HIST_CMD, DATA_TYPE_STRING, 0},
|
||||||
|
{ZPOOL_EXPORT_FORCE, DATA_TYPE_BOOLEAN_VALUE, 0},
|
||||||
|
{ZPOOL_EXPORT_HARDFORCE, DATA_TYPE_BOOLEAN_VALUE, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
zfs_ioc_pool_export_new(const char *pool, nvlist_t *innvl, nvlist_t *outnvl)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
zfs_log_history_string(pool,
|
||||||
|
fnvlist_lookup_string(innvl, ZPOOL_HIST_CMD));
|
||||||
|
error = spa_export(pool, NULL,
|
||||||
|
fnvlist_lookup_boolean_value(innvl, ZPOOL_EXPORT_FORCE),
|
||||||
|
fnvlist_lookup_boolean_value(innvl, ZPOOL_EXPORT_HARDFORCE),
|
||||||
|
outnvl);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
@ -7103,6 +7145,7 @@ error:
|
||||||
|
|
||||||
static const zfs_ioc_key_t zfs_keys_pool_recycle[] = {
|
static const zfs_ioc_key_t zfs_keys_pool_recycle[] = {
|
||||||
{ZPOOL_RECYCLE_DRYRUN, DATA_TYPE_BOOLEAN_VALUE, 0},
|
{ZPOOL_RECYCLE_DRYRUN, DATA_TYPE_BOOLEAN_VALUE, 0},
|
||||||
|
{ZPOOL_RECYCLE_CLIENTS, DATA_TYPE_NVLIST, ZK_OPTIONAL},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -7111,6 +7154,7 @@ zfs_ioc_pool_recycle(const char *pool, nvlist_t *innvl, nvlist_t *outnvl)
|
||||||
int err;
|
int err;
|
||||||
boolean_t rc, dryrun = B_FALSE;
|
boolean_t rc, dryrun = B_FALSE;
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
|
nvlist_t *clients = NULL;
|
||||||
|
|
||||||
if ((err = spa_open(pool, &spa, FTAG)) != 0)
|
if ((err = spa_open(pool, &spa, FTAG)) != 0)
|
||||||
return (err);
|
return (err);
|
||||||
|
@ -7120,9 +7164,14 @@ zfs_ioc_pool_recycle(const char *pool, nvlist_t *innvl, nvlist_t *outnvl)
|
||||||
&rc);
|
&rc);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
dryrun = rc;
|
dryrun = rc;
|
||||||
|
nvlist_lookup_nvlist(innvl, ZPOOL_RECYCLE_CLIENTS,
|
||||||
|
&clients);
|
||||||
|
}
|
||||||
|
if (clients) {
|
||||||
|
err = spa_recycle_clients(spa, clients, dryrun, outnvl);
|
||||||
|
} else {
|
||||||
|
err = spa_recycle_all(spa, dryrun, outnvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = spa_recycle(spa, dryrun, outnvl);
|
|
||||||
|
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
|
|
||||||
|
@ -7435,6 +7484,16 @@ zfs_ioctl_init(void)
|
||||||
POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE,
|
POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE,
|
||||||
zfs_keys_pool_recycle, ARRAY_SIZE(zfs_keys_pool_recycle));
|
zfs_keys_pool_recycle, ARRAY_SIZE(zfs_keys_pool_recycle));
|
||||||
|
|
||||||
|
zfs_ioctl_register("zpool_destroy_new", ZFS_IOC_POOL_DESTROY_NEW,
|
||||||
|
zfs_ioc_pool_destroy_new, zfs_secpolicy_config, POOL_NAME,
|
||||||
|
POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE,
|
||||||
|
zfs_keys_pool_destroy_new, ARRAY_SIZE(zfs_keys_pool_destroy_new));
|
||||||
|
|
||||||
|
zfs_ioctl_register("zpool_export_new", ZFS_IOC_POOL_EXPORT_NEW,
|
||||||
|
zfs_ioc_pool_export_new, zfs_secpolicy_config, POOL_NAME,
|
||||||
|
POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE,
|
||||||
|
zfs_keys_pool_export_new, ARRAY_SIZE(zfs_keys_pool_export_new));
|
||||||
|
|
||||||
/* IOCTLS that use the legacy function signature */
|
/* IOCTLS that use the legacy function signature */
|
||||||
|
|
||||||
zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
|
zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
|
||||||
|
|
|
@ -453,7 +453,8 @@ zil_kstat_values_update(zil_kstat_values_t *zs, zil_sums_t *zil_sums)
|
||||||
static int
|
static int
|
||||||
zil_parse_raw_impl(spa_t *spa, const blkptr_t *bp,
|
zil_parse_raw_impl(spa_t *spa, const blkptr_t *bp,
|
||||||
zil_parse_raw_blk_func_t *parse_blk_func,
|
zil_parse_raw_blk_func_t *parse_blk_func,
|
||||||
zil_parse_raw_lr_func_t *parse_lr_func, void *arg, zio_flag_t zio_flags)
|
zil_parse_raw_lr_func_t *parse_lr_func, void *arg, zio_flag_t zio_flags,
|
||||||
|
boolean_t decrypt)
|
||||||
{
|
{
|
||||||
(void) parse_lr_func;
|
(void) parse_lr_func;
|
||||||
blkptr_t next_blk = {{{{0}}}};
|
blkptr_t next_blk = {{{{0}}}};
|
||||||
|
@ -468,7 +469,7 @@ zil_parse_raw_impl(spa_t *spa, const blkptr_t *bp,
|
||||||
* parse function frees the block, we still have next_blk so we
|
* parse function frees the block, we still have next_blk so we
|
||||||
* can continue the chain.
|
* can continue the chain.
|
||||||
*/
|
*/
|
||||||
int read_error = zil_read_log_block(spa, B_FALSE, zio_flags,
|
int read_error = zil_read_log_block(spa, decrypt, zio_flags,
|
||||||
&blk, &next_blk, &lrp, &end, &abuf);
|
&blk, &next_blk, &lrp, &end, &abuf);
|
||||||
|
|
||||||
error = parse_blk_func(spa, &blk, arg);
|
error = parse_blk_func(spa, &blk, arg);
|
||||||
|
@ -502,13 +503,17 @@ zil_parse_raw_impl(spa_t *spa, const blkptr_t *bp,
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because we don't have access to the zilog_t, we cannot know when the chain
|
||||||
|
* is supposed to end. As a result, all IOs need to be marked as speculative.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
zil_parse_raw(spa_t *spa, const blkptr_t *bp,
|
zil_parse_raw(spa_t *spa, const blkptr_t *bp,
|
||||||
zil_parse_raw_blk_func_t *parse_blk_func,
|
zil_parse_raw_blk_func_t *parse_blk_func,
|
||||||
zil_parse_raw_lr_func_t *parse_lr_func, void *arg)
|
zil_parse_raw_lr_func_t *parse_lr_func, void *arg)
|
||||||
{
|
{
|
||||||
return (zil_parse_raw_impl(spa, bp, parse_blk_func, parse_lr_func, arg,
|
return (zil_parse_raw_impl(spa, bp, parse_blk_func, parse_lr_func, arg,
|
||||||
0));
|
ZIO_FLAG_SPECULATIVE | ZIO_FLAG_SCRUB, B_FALSE));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct parse_arg {
|
struct parse_arg {
|
||||||
|
@ -517,7 +522,6 @@ struct parse_arg {
|
||||||
zil_parse_lr_func_t *parse_lr_func;
|
zil_parse_lr_func_t *parse_lr_func;
|
||||||
void *arg;
|
void *arg;
|
||||||
uint64_t txg;
|
uint64_t txg;
|
||||||
boolean_t decrypt;
|
|
||||||
uint64_t blk_seq;
|
uint64_t blk_seq;
|
||||||
uint64_t claim_blk_seq;
|
uint64_t claim_blk_seq;
|
||||||
uint64_t claim_lr_seq;
|
uint64_t claim_lr_seq;
|
||||||
|
@ -594,7 +598,6 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
|
||||||
arg2.parse_blk_func = parse_blk_func;
|
arg2.parse_blk_func = parse_blk_func;
|
||||||
arg2.parse_lr_func = parse_lr_func;
|
arg2.parse_lr_func = parse_lr_func;
|
||||||
arg2.txg = txg;
|
arg2.txg = txg;
|
||||||
arg2.decrypt = decrypt;
|
|
||||||
arg2.zilog = zilog;
|
arg2.zilog = zilog;
|
||||||
arg2.error = 0;
|
arg2.error = 0;
|
||||||
arg2.blk_seq = 0;
|
arg2.blk_seq = 0;
|
||||||
|
@ -615,7 +618,7 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
|
||||||
zil_bp_tree_init(zilog);
|
zil_bp_tree_init(zilog);
|
||||||
|
|
||||||
int error = zil_parse_raw_impl(zilog->zl_io_spa, &zh->zh_log,
|
int error = zil_parse_raw_impl(zilog->zl_io_spa, &zh->zh_log,
|
||||||
parse_blk_wrapper, parse_lr_wrapper, &arg2, zio_flags);
|
parse_blk_wrapper, parse_lr_wrapper, &arg2, zio_flags, decrypt);
|
||||||
|
|
||||||
// If this happens, we got an error from zil_read_log_block_spa
|
// If this happens, we got an error from zil_read_log_block_spa
|
||||||
if (error != 0 && error != EINTR && claimed) {
|
if (error != 0 && error != EINTR && claimed) {
|
||||||
|
@ -1212,6 +1215,49 @@ zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx)
|
||||||
zil_free_log_record, tx, zilog->zl_header->zh_claim_txg, B_FALSE);
|
zil_free_log_record, tx, zilog->zl_header->zh_claim_txg, B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function's only job is to clear the zil chain for the given dataset.
|
||||||
|
* It is called when we're using a shared log pool and we import discarding
|
||||||
|
* logs.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zil_clear(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg)
|
||||||
|
{
|
||||||
|
dmu_tx_t *tx = txarg;
|
||||||
|
zilog_t *zilog;
|
||||||
|
zil_header_t *zh;
|
||||||
|
objset_t *os;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
ASSERT3U(spa_get_log_state(dp->dp_spa), ==, SPA_LOG_CLEAR);
|
||||||
|
|
||||||
|
error = dmu_objset_own_obj(dp, ds->ds_object,
|
||||||
|
DMU_OST_ANY, B_FALSE, B_FALSE, FTAG, &os);
|
||||||
|
if (error != 0) {
|
||||||
|
/*
|
||||||
|
* EBUSY indicates that the objset is inconsistent, in which
|
||||||
|
* case it can not have a ZIL.
|
||||||
|
*/
|
||||||
|
if (error != EBUSY) {
|
||||||
|
cmn_err(CE_WARN, "can't open objset for %llu, error %u",
|
||||||
|
(unsigned long long)ds->ds_object, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
zilog = dmu_objset_zil(os);
|
||||||
|
zh = zil_header_in_syncing_context(zilog);
|
||||||
|
ASSERT3U(tx->tx_txg, ==, spa_first_txg(zilog->zl_spa));
|
||||||
|
|
||||||
|
BP_ZERO(&zh->zh_log);
|
||||||
|
if (os->os_encrypted)
|
||||||
|
os->os_next_write_raw[tx->tx_txg & TXG_MASK] = B_TRUE;
|
||||||
|
dsl_dataset_dirty(dmu_objset_ds(os), tx);
|
||||||
|
dmu_objset_disown(os, B_FALSE, FTAG);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zil_claim(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg)
|
zil_claim(dsl_pool_t *dp, dsl_dataset_t *ds, void *txarg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -930,7 +930,7 @@ tags = ['functional', 'scrub_mirror']
|
||||||
|
|
||||||
[tests/functional/shared_log]
|
[tests/functional/shared_log]
|
||||||
tests = ['shared_log_001_pos', 'shared_log_002_pos', 'shared_log_003_pos', 'shared_log_004_pos',
|
tests = ['shared_log_001_pos', 'shared_log_002_pos', 'shared_log_003_pos', 'shared_log_004_pos',
|
||||||
'shared_log_005_pos', 'shared_log_006_neg']
|
'shared_log_005_pos', 'shared_log_006_neg', 'shared_log_007_pos', 'shared_log_008_pos']
|
||||||
tags = ['functional', 'shared_log']
|
tags = ['functional', 'shared_log']
|
||||||
|
|
||||||
[tests/functional/slog]
|
[tests/functional/slog]
|
||||||
|
|
|
@ -1586,10 +1586,10 @@ function create_pool #pool devs_list
|
||||||
|
|
||||||
if is_global_zone ; then
|
if is_global_zone ; then
|
||||||
[[ -d /$pool ]] && rm -rf /$pool
|
[[ -d /$pool ]] && rm -rf /$pool
|
||||||
log_must zpool create -f $pool $@
|
zpool create -f $pool $@
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 0
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return 0 if destroy successfully or the pool exists; $? otherwise
|
# Return 0 if destroy successfully or the pool exists; $? otherwise
|
||||||
|
|
|
@ -1953,6 +1953,8 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
|
||||||
functional/shared_log/shared_log_004_pos.ksh \
|
functional/shared_log/shared_log_004_pos.ksh \
|
||||||
functional/shared_log/shared_log_005_pos.ksh \
|
functional/shared_log/shared_log_005_pos.ksh \
|
||||||
functional/shared_log/shared_log_006_neg.ksh \
|
functional/shared_log/shared_log_006_neg.ksh \
|
||||||
|
functional/shared_log/shared_log_007_pos.ksh \
|
||||||
|
functional/shared_log/shared_log_008_pos.ksh \
|
||||||
functional/slog/cleanup.ksh \
|
functional/slog/cleanup.ksh \
|
||||||
functional/slog/setup.ksh \
|
functional/slog/setup.ksh \
|
||||||
functional/slog/slog_001_pos.ksh \
|
functional/slog/slog_001_pos.ksh \
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
|
|
||||||
verify_runnable "global"
|
verify_runnable "global"
|
||||||
|
|
||||||
|
zpool import $LOGPOOL
|
||||||
|
zpool import ${LOGPOOL}2
|
||||||
|
zpool import $TESTPOOL
|
||||||
|
zpool import $TESTPOOL2
|
||||||
if datasetexists $TESTPOOL ; then
|
if datasetexists $TESTPOOL ; then
|
||||||
log_must zpool destroy -f $TESTPOOL
|
log_must zpool destroy -f $TESTPOOL
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
# Copyright (c) 2023 by Delphix. All rights reserved.
|
# Copyright (c) 2023 by Delphix. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
export LOGPOOL="${TESTPOOL}_log"
|
. $STF_SUITE/include/libtest.shlib
|
||||||
IFS=' ' read -r -a array <<< "$DISKS"
|
|
||||||
|
|
||||||
export DISK0="${array[0]}"
|
export LOGPOOL="${TESTPOOL}_log"
|
||||||
export DISK1="${array[1]}"
|
read -r DISK0 DISK1 DISK2 _ <<<"$DISKS"
|
||||||
export DISK2="${array[2]}"
|
export DISK0 DISK1 DISK2
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
|
|
||||||
function cleanup
|
function cleanup
|
||||||
{
|
{
|
||||||
|
zpool import $LOGPOOL
|
||||||
|
zpool import ${LOGPOOL}2
|
||||||
|
zpool import -m $TESTPOOL
|
||||||
|
zpool import -m $TESTPOOL2
|
||||||
poolexists $TESTPOOL && destroy_pool $TESTPOOL
|
poolexists $TESTPOOL && destroy_pool $TESTPOOL
|
||||||
poolexists $TESTPOOL2 && destroy_pool $TESTPOOL2
|
poolexists $TESTPOOL2 && destroy_pool $TESTPOOL2
|
||||||
poolexists $LOGPOOL && destroy_pool $LOGPOOL
|
poolexists $LOGPOOL && destroy_pool $LOGPOOL
|
||||||
|
|
|
@ -44,5 +44,7 @@ log_onexit cleanup
|
||||||
log_must create_pool $LOGPOOL -L "$DISK0"
|
log_must create_pool $LOGPOOL -L "$DISK0"
|
||||||
log_must create_pool $TESTPOOL -l $LOGPOOL "$DISK1"
|
log_must create_pool $TESTPOOL -l $LOGPOOL "$DISK1"
|
||||||
log_must verify_shared_log $TESTPOOL $LOGPOOL
|
log_must verify_shared_log $TESTPOOL $LOGPOOL
|
||||||
|
verify_pool $LOGPOOL
|
||||||
|
verify_pool $TESTPOOL
|
||||||
|
|
||||||
log_pass "Creating a pool with a shared log succeeds."
|
log_pass "Creating a pool with a shared log succeeds."
|
||||||
|
|
|
@ -55,5 +55,7 @@ log_must dd if=/dev/urandom of="$mntpnt/f1" bs=8k count=128
|
||||||
log_must zpool export $TESTPOOL
|
log_must zpool export $TESTPOOL
|
||||||
log_must zpool import $TESTPOOL
|
log_must zpool import $TESTPOOL
|
||||||
log_must dd if=/dev/urandom of="$mntpnt/f1" bs=8k count=128
|
log_must dd if=/dev/urandom of="$mntpnt/f1" bs=8k count=128
|
||||||
|
verify_pool $LOGPOOL
|
||||||
|
verify_pool $TESTPOOL
|
||||||
|
|
||||||
log_pass "Using a pool with a shared log device succeeds at basic operations."
|
log_pass "Using a pool with a shared log device succeeds at basic operations."
|
||||||
|
|
|
@ -58,5 +58,7 @@ log_must zpool export $LOGPOOL
|
||||||
log_must zpool import $LOGPOOL
|
log_must zpool import $LOGPOOL
|
||||||
log_must zpool import $TESTPOOL
|
log_must zpool import $TESTPOOL
|
||||||
log_must dd if=/dev/urandom of="$mntpnt/f2" bs=8k count=128
|
log_must dd if=/dev/urandom of="$mntpnt/f2" bs=8k count=128
|
||||||
|
verify_pool $LOGPOOL
|
||||||
|
verify_pool $TESTPOOL
|
||||||
|
|
||||||
log_pass "Shared log pool can be exported and imported."
|
log_pass "Shared log pool can be exported and imported."
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
# 3. Export client and provider
|
# 3. Export client and provider
|
||||||
# 4. Import client with -m
|
# 4. Import client with -m
|
||||||
# 5. Export client
|
# 5. Export client
|
||||||
# 6. Import client with -m and new pool
|
# 6. Import client with -m and new provider
|
||||||
#
|
#
|
||||||
|
|
||||||
verify_runnable "global"
|
verify_runnable "global"
|
||||||
|
@ -63,5 +63,8 @@ log_must zpool import $LOGPOOL
|
||||||
log_must zpool import -m -L ${LOGPOOL}2 $TESTPOOL
|
log_must zpool import -m -L ${LOGPOOL}2 $TESTPOOL
|
||||||
log_must verify_shared_log $TESTPOOL ${LOGPOOL}2
|
log_must verify_shared_log $TESTPOOL ${LOGPOOL}2
|
||||||
log_must dd if=/dev/urandom of="$mntpnt/f3" bs=8k count=128
|
log_must dd if=/dev/urandom of="$mntpnt/f3" bs=8k count=128
|
||||||
|
verify_pool $LOGPOOL
|
||||||
|
verify_pool $LOGPOOL2
|
||||||
|
verify_pool $TESTPOOL
|
||||||
|
|
||||||
log_pass "Client pools can be reimported without provider, with flag."
|
log_pass "Client pools can be reimported without provider, with flag."
|
||||||
|
|
|
@ -31,9 +31,14 @@
|
||||||
# Negative shared log testing.
|
# Negative shared log testing.
|
||||||
#
|
#
|
||||||
# STRATEGY:
|
# STRATEGY:
|
||||||
# 1. Create shared log pool & client
|
# 1. Attempt to create a client pool with a missing shared log pool
|
||||||
# 2. Write some data to the client pool
|
# 2. Attempt to create a client pool with mis-named shared log pool
|
||||||
# 3. Scrub client and provider pools
|
# 3. Attempt to create a client pool with a shared log and a log device
|
||||||
|
# 4. Attempt to use a client pool after the shared log has been destroyed
|
||||||
|
# 5. Attempt to create a client pool when the feature is disabled
|
||||||
|
# 6. Attempt to export/destroy an active shared log
|
||||||
|
# 7. Attempt to reguid a client/log pool
|
||||||
|
# 8. Attempt to checkpoint a client/log pool
|
||||||
#
|
#
|
||||||
|
|
||||||
verify_runnable "global"
|
verify_runnable "global"
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/shared_log/shared_log.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION:
|
||||||
|
# Test fault behavior of shared log pool
|
||||||
|
#
|
||||||
|
# STRATEGY:
|
||||||
|
# 1. Create shared log pool & client
|
||||||
|
# 2. Fault the provider pool
|
||||||
|
# 3. Verify the client pool also faults
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
log_assert "Test fault behavior of shared log pools."
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
typeset FS="$TESTPOOL/fs"
|
||||||
|
|
||||||
|
log_must create_pool $LOGPOOL -L "$DISK0"
|
||||||
|
log_must create_pool $TESTPOOL -l $LOGPOOL "$DISK1"
|
||||||
|
log_must zinject -d "$DISK0" -A degrade $LOGPOOL
|
||||||
|
log_must eval "zpool status -e $TESTPOOL | grep DEGRADED"
|
||||||
|
|
||||||
|
log_pass "Test fault behavior of shared log pools."
|
|
@ -0,0 +1,81 @@
|
||||||
|
#!/bin/ksh -p
|
||||||
|
#
|
||||||
|
# CDDL HEADER START
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the terms of the
|
||||||
|
# Common Development and Distribution License (the "License").
|
||||||
|
# You may not use this file except in compliance with the License.
|
||||||
|
#
|
||||||
|
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||||
|
# or https://opensource.org/licenses/CDDL-1.0.
|
||||||
|
# See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
#
|
||||||
|
# When distributing Covered Code, include this CDDL HEADER in each
|
||||||
|
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||||
|
# If applicable, add the following below this CDDL HEADER, with the
|
||||||
|
# fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
# information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
|
#
|
||||||
|
# CDDL HEADER END
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 by Delphix. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
. $STF_SUITE/tests/functional/shared_log/shared_log.kshlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# DESCRIPTION:
|
||||||
|
# Test zpool recycle
|
||||||
|
#
|
||||||
|
# STRATEGY:
|
||||||
|
# 1. Create shared log pool & clients
|
||||||
|
# 2. Verify zpool recycle -a doesn't recycle anything
|
||||||
|
# 3. Export clients
|
||||||
|
# 4. Verify zpool recycle -a recycles everything
|
||||||
|
# 5. Re-add clients and export both
|
||||||
|
# 6. Verify zpool recycle of a single client works as expected
|
||||||
|
# 7. Re-add client and export it
|
||||||
|
# 8. Verify zpool recycle of multiple clients works as expected
|
||||||
|
#
|
||||||
|
|
||||||
|
verify_runnable "global"
|
||||||
|
|
||||||
|
log_assert "Test zpool recycle."
|
||||||
|
log_onexit cleanup
|
||||||
|
|
||||||
|
typeset FS="$TESTPOOL/fs"
|
||||||
|
|
||||||
|
log_must create_pool $LOGPOOL -L "$DISK0"
|
||||||
|
log_must create_pool $TESTPOOL -l $LOGPOOL "$DISK1"
|
||||||
|
log_must create_pool ${TESTPOOL}2 -l $LOGPOOL "$DISK2"
|
||||||
|
log_must zfs create -o sync=always ${TESTPOOL}/fs
|
||||||
|
log_must zfs create -o sync=always ${TESTPOOL}2/fs
|
||||||
|
log_must dd if=/dev/urandom of=/${TESTPOOL}/fs/f1 bs=128k count=128
|
||||||
|
log_must dd if=/dev/urandom of=/${TESTPOOL}2/fs/f1 bs=128k count=128
|
||||||
|
log_must eval "zpool recycle -a -v $LOGPOOL | grep '\\[\\]' >/dev/null"
|
||||||
|
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool export ${TESTPOOL}2
|
||||||
|
log_must zpool recycle -a -v $LOGPOOL
|
||||||
|
log_mustnot zpool import $TESTPOOL
|
||||||
|
log_mustnot zpool import ${TESTPOOL}2
|
||||||
|
|
||||||
|
log_must zpool import -m -L $LOGPOOL $TESTPOOL
|
||||||
|
log_must zpool import -m -L $LOGPOOL ${TESTPOOL}2
|
||||||
|
log_must dd if=/dev/urandom of=/${TESTPOOL}/fs/f1 bs=128k count=128
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool export ${TESTPOOL}2
|
||||||
|
log_must zpool recycle $LOGPOOL $TESTPOOL
|
||||||
|
log_mustnot zpool import $TESTPOOL
|
||||||
|
|
||||||
|
log_must zpool import -m -L $LOGPOOL $TESTPOOL
|
||||||
|
log_must dd if=/dev/urandom of=/${TESTPOOL}/fs/f1 bs=128k count=128
|
||||||
|
log_must zpool export $TESTPOOL
|
||||||
|
log_must zpool recycle $LOGPOOL $TESTPOOL ${TESTPOOL2}
|
||||||
|
log_mustnot zpool import $TESTPOOL
|
||||||
|
log_mustnot zpool import ${TESTPOOL}2
|
||||||
|
|
||||||
|
log_pass "Test zpool recycle."
|
Loading…
Reference in New Issue