mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Rebase master to b105
This commit is contained in:
+74
-43
@@ -87,8 +87,8 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"Usage: %s [-udibcsv] [-U cachefile_path] "
|
||||
"[-S user:cksumalg] "
|
||||
"Usage: %s [-udibcsvL] [-U cachefile_path] [-t txg]\n"
|
||||
"\t [-S user:cksumalg] "
|
||||
"dataset [object...]\n"
|
||||
" %s -C [pool]\n"
|
||||
" %s -l dev\n"
|
||||
@@ -108,6 +108,8 @@ usage(void)
|
||||
"dump blkptr signatures\n");
|
||||
(void) fprintf(stderr, " -v verbose (applies to all others)\n");
|
||||
(void) fprintf(stderr, " -l dump label contents\n");
|
||||
(void) fprintf(stderr, " -L disable leak tracking (do not "
|
||||
"load spacemaps)\n");
|
||||
(void) fprintf(stderr, " -U cachefile_path -- use alternate "
|
||||
"cachefile\n");
|
||||
(void) fprintf(stderr, " -R read and display block from a "
|
||||
@@ -115,6 +117,8 @@ usage(void)
|
||||
(void) fprintf(stderr, " -e Pool is exported/destroyed/"
|
||||
"has altroot\n");
|
||||
(void) fprintf(stderr, " -p <Path to vdev dir> (use with -e)\n");
|
||||
(void) fprintf(stderr, " -t <txg> highest txg to use when "
|
||||
"searching for uberblocks\n");
|
||||
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
||||
"to make only that option verbose\n");
|
||||
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
|
||||
@@ -516,45 +520,53 @@ dump_metaslabs(spa_t *spa)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
|
||||
{
|
||||
char *prefix = (void *)sm;
|
||||
|
||||
(void) printf("%s [%llu,%llu) length %llu\n",
|
||||
prefix,
|
||||
(u_longlong_t)start,
|
||||
(u_longlong_t)(start + size),
|
||||
(u_longlong_t)(size));
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dtl(vdev_t *vd, int indent)
|
||||
{
|
||||
avl_tree_t *t = &vd->vdev_dtl_map.sm_root;
|
||||
space_seg_t *ss;
|
||||
vdev_t *pvd;
|
||||
int c;
|
||||
spa_t *spa = vd->vdev_spa;
|
||||
boolean_t required;
|
||||
char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
|
||||
char prefix[256];
|
||||
|
||||
spa_vdev_state_enter(spa);
|
||||
required = vdev_dtl_required(vd);
|
||||
(void) spa_vdev_state_exit(spa, NULL, 0);
|
||||
|
||||
if (indent == 0)
|
||||
(void) printf("\nDirty time logs:\n\n");
|
||||
|
||||
(void) printf("\t%*s%s\n", indent, "",
|
||||
(void) printf("\t%*s%s [%s]\n", indent, "",
|
||||
vd->vdev_path ? vd->vdev_path :
|
||||
vd->vdev_parent ? vd->vdev_ops->vdev_op_type :
|
||||
spa_name(vd->vdev_spa));
|
||||
vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
|
||||
required ? "DTL-required" : "DTL-expendable");
|
||||
|
||||
for (ss = avl_first(t); ss; ss = AVL_NEXT(t, ss)) {
|
||||
/*
|
||||
* Everything in this DTL must appear in all parent DTL unions.
|
||||
*/
|
||||
for (pvd = vd; pvd; pvd = pvd->vdev_parent)
|
||||
ASSERT(vdev_dtl_contains(&pvd->vdev_dtl_map,
|
||||
ss->ss_start, ss->ss_end - ss->ss_start));
|
||||
(void) printf("\t%*soutage [%llu,%llu] length %llu\n",
|
||||
indent, "",
|
||||
(u_longlong_t)ss->ss_start,
|
||||
(u_longlong_t)ss->ss_end - 1,
|
||||
(u_longlong_t)(ss->ss_end - ss->ss_start));
|
||||
for (int t = 0; t < DTL_TYPES; t++) {
|
||||
space_map_t *sm = &vd->vdev_dtl[t];
|
||||
if (sm->sm_space == 0)
|
||||
continue;
|
||||
(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
|
||||
indent + 2, "", name[t]);
|
||||
mutex_enter(sm->sm_lock);
|
||||
space_map_walk(sm, dump_dtl_seg, (void *)prefix);
|
||||
mutex_exit(sm->sm_lock);
|
||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0)
|
||||
dump_spacemap(spa->spa_meta_objset,
|
||||
&vd->vdev_dtl_smo, sm);
|
||||
}
|
||||
|
||||
(void) printf("\n");
|
||||
|
||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0) {
|
||||
dump_spacemap(vd->vdev_spa->spa_meta_objset, &vd->vdev_dtl,
|
||||
&vd->vdev_dtl_map);
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
for (c = 0; c < vd->vdev_children; c++)
|
||||
for (int c = 0; c < vd->vdev_children; c++)
|
||||
dump_dtl(vd->vdev_child[c], indent + 4);
|
||||
}
|
||||
|
||||
@@ -668,7 +680,8 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
|
||||
break;
|
||||
fill += cbp->blk_fill;
|
||||
}
|
||||
ASSERT3U(fill, ==, bp->blk_fill);
|
||||
if (!err)
|
||||
ASSERT3U(fill, ==, bp->blk_fill);
|
||||
(void) arc_buf_remove_ref(buf, &buf);
|
||||
}
|
||||
|
||||
@@ -1481,8 +1494,9 @@ zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, dmu_object_type_t type)
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
|
||||
NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
|
||||
if (!dump_opt['L'])
|
||||
VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
|
||||
NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1557,9 +1571,11 @@ dump_block_stats(spa_t *spa)
|
||||
int c, e;
|
||||
|
||||
if (!dump_opt['S']) {
|
||||
(void) printf("\nTraversing all blocks to %sverify"
|
||||
" nothing leaked ...\n",
|
||||
dump_opt['c'] ? "verify checksums and " : "");
|
||||
(void) printf("\nTraversing all blocks %s%s%s%s...\n",
|
||||
(dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
|
||||
dump_opt['c'] ? "checksums " : "",
|
||||
(dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
|
||||
!dump_opt['L'] ? "nothing leaked " : "");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1570,7 +1586,8 @@ dump_block_stats(spa_t *spa)
|
||||
* it's not part of any space map) is a double allocation,
|
||||
* reference to a freed block, or an unclaimed log block.
|
||||
*/
|
||||
zdb_leak_init(spa);
|
||||
if (!dump_opt['L'])
|
||||
zdb_leak_init(spa);
|
||||
|
||||
/*
|
||||
* If there's a deferred-free bplist, process that first.
|
||||
@@ -1612,7 +1629,8 @@ dump_block_stats(spa_t *spa)
|
||||
/*
|
||||
* Report any leaked segments.
|
||||
*/
|
||||
zdb_leak_fini(spa);
|
||||
if (!dump_opt['L'])
|
||||
zdb_leak_fini(spa);
|
||||
|
||||
/*
|
||||
* If we're interested in printing out the blkptr signatures,
|
||||
@@ -1638,14 +1656,16 @@ dump_block_stats(spa_t *spa)
|
||||
tzb = &zcb.zcb_type[ZB_TOTAL][DMU_OT_TOTAL];
|
||||
|
||||
if (tzb->zb_asize == alloc + logalloc) {
|
||||
(void) printf("\n\tNo leaks (block sum matches space"
|
||||
" maps exactly)\n");
|
||||
if (!dump_opt['L'])
|
||||
(void) printf("\n\tNo leaks (block sum matches space"
|
||||
" maps exactly)\n");
|
||||
} else {
|
||||
(void) printf("block traversal size %llu != alloc %llu "
|
||||
"(leaked %lld)\n",
|
||||
"(%s %lld)\n",
|
||||
(u_longlong_t)tzb->zb_asize,
|
||||
(u_longlong_t)alloc + logalloc,
|
||||
(u_longlong_t)(alloc + logalloc - tzb->zb_asize));
|
||||
(dump_opt['L']) ? "unreachable" : "leaked",
|
||||
(longlong_t)(alloc + logalloc - tzb->zb_asize));
|
||||
leaks = 1;
|
||||
}
|
||||
|
||||
@@ -2235,7 +2255,7 @@ main(int argc, char **argv)
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
while ((c = getopt(argc, argv, "udibcsvCS:U:lRep:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "udibcsvCLS:U:lRep:t:")) != -1) {
|
||||
switch (c) {
|
||||
case 'u':
|
||||
case 'd':
|
||||
@@ -2249,6 +2269,9 @@ main(int argc, char **argv)
|
||||
dump_opt[c]++;
|
||||
dump_all = 0;
|
||||
break;
|
||||
case 'L':
|
||||
dump_opt[c]++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
@@ -2279,6 +2302,14 @@ main(int argc, char **argv)
|
||||
else
|
||||
usage();
|
||||
break;
|
||||
case 't':
|
||||
ub_max_txg = strtoull(optarg, NULL, 0);
|
||||
if (ub_max_txg < TXG_INITIAL) {
|
||||
(void) fprintf(stderr, "incorrect txg "
|
||||
"specified: %s\n", optarg);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
||||
+14
-18
@@ -370,18 +370,12 @@ usage(boolean_t requested)
|
||||
|
||||
zfs_deleg_permissions();
|
||||
} else {
|
||||
/*
|
||||
* TRANSLATION NOTE:
|
||||
* "zfs set|get" must not be localised this is the
|
||||
* command name and arguments.
|
||||
*/
|
||||
|
||||
(void) fprintf(fp,
|
||||
gettext("\nFor the property list, run: zfs set|get\n"));
|
||||
|
||||
gettext("\nFor the property list, run: %s\n"),
|
||||
"zfs set|get");
|
||||
(void) fprintf(fp,
|
||||
gettext("\nFor the delegated permission list, run:"
|
||||
" zfs allow|unallow\n"));
|
||||
gettext("\nFor the delegated permission list, run: %s\n"),
|
||||
"zfs allow|unallow");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -419,7 +413,6 @@ parseprop(nvlist_t *props)
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2584,14 +2577,15 @@ zfs_print_allows(char *ds)
|
||||
for (curperms = perms; curperms; curperms = curperms->z_next) {
|
||||
|
||||
(void) snprintf(banner, sizeof (banner),
|
||||
"Permission sets on (%s)", curperms->z_setpoint);
|
||||
gettext("Permission sets on (%s)"), curperms->z_setpoint);
|
||||
allowcb.a_treeoffset =
|
||||
offsetof(zfs_allow_node_t, z_localdescend);
|
||||
allowcb.a_permcnt = 0;
|
||||
zfs_iter_perms(&curperms->z_sets, banner, &allowcb);
|
||||
|
||||
(void) snprintf(banner, sizeof (banner),
|
||||
"Create time permissions on (%s)", curperms->z_setpoint);
|
||||
gettext("Create time permissions on (%s)"),
|
||||
curperms->z_setpoint);
|
||||
allowcb.a_treeoffset =
|
||||
offsetof(zfs_allow_node_t, z_localdescend);
|
||||
allowcb.a_permcnt = 0;
|
||||
@@ -2599,7 +2593,7 @@ zfs_print_allows(char *ds)
|
||||
|
||||
|
||||
(void) snprintf(banner, sizeof (banner),
|
||||
"Local permissions on (%s)", curperms->z_setpoint);
|
||||
gettext("Local permissions on (%s)"), curperms->z_setpoint);
|
||||
allowcb.a_treeoffset = offsetof(zfs_allow_node_t, z_local);
|
||||
allowcb.a_permcnt = 0;
|
||||
zfs_iter_perms(&curperms->z_user, banner, &allowcb);
|
||||
@@ -2607,7 +2601,8 @@ zfs_print_allows(char *ds)
|
||||
zfs_iter_perms(&curperms->z_everyone, banner, &allowcb);
|
||||
|
||||
(void) snprintf(banner, sizeof (banner),
|
||||
"Descendent permissions on (%s)", curperms->z_setpoint);
|
||||
gettext("Descendent permissions on (%s)"),
|
||||
curperms->z_setpoint);
|
||||
allowcb.a_treeoffset = offsetof(zfs_allow_node_t, z_descend);
|
||||
allowcb.a_permcnt = 0;
|
||||
zfs_iter_perms(&curperms->z_user, banner, &allowcb);
|
||||
@@ -2615,7 +2610,7 @@ zfs_print_allows(char *ds)
|
||||
zfs_iter_perms(&curperms->z_everyone, banner, &allowcb);
|
||||
|
||||
(void) snprintf(banner, sizeof (banner),
|
||||
"Local+Descendent permissions on (%s)",
|
||||
gettext("Local+Descendent permissions on (%s)"),
|
||||
curperms->z_setpoint);
|
||||
allowcb.a_treeoffset =
|
||||
offsetof(zfs_allow_node_t, z_localdescend);
|
||||
@@ -3071,7 +3066,6 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
||||
sizeof (shareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARESMB, smbshareopts,
|
||||
sizeof (smbshareopts), NULL, NULL, 0, B_FALSE) == 0);
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
|
||||
if (op == OP_SHARE && strcmp(shareopts, "off") == 0 &&
|
||||
strcmp(smbshareopts, "off") == 0) {
|
||||
@@ -3081,7 +3075,8 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
||||
(void) fprintf(stderr, gettext("cannot share '%s': "
|
||||
"legacy share\n"), zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use share(1M) to "
|
||||
"share this filesystem\n"));
|
||||
"share this filesystem, or set "
|
||||
"sharenfs property on\n"));
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -3119,6 +3114,7 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
|
||||
* noauto no return 0
|
||||
* noauto yes pass through
|
||||
*/
|
||||
canmount = zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT);
|
||||
if (canmount == ZFS_CANMOUNT_OFF) {
|
||||
if (!explicit)
|
||||
return (0);
|
||||
|
||||
+10
-2
@@ -877,17 +877,21 @@ int
|
||||
zpool_do_export(int argc, char **argv)
|
||||
{
|
||||
boolean_t force = B_FALSE;
|
||||
boolean_t hardforce = B_FALSE;
|
||||
int c;
|
||||
zpool_handle_t *zhp;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "f")) != -1) {
|
||||
while ((c = getopt(argc, argv, "fF")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
force = B_TRUE;
|
||||
break;
|
||||
case 'F':
|
||||
hardforce = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
@@ -917,8 +921,12 @@ zpool_do_export(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zpool_export(zhp, force) != 0)
|
||||
if (hardforce) {
|
||||
if (zpool_export_force(zhp) != 0)
|
||||
ret = 1;
|
||||
} else if (zpool_export(zhp, force) != 0) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
zpool_close(zhp);
|
||||
}
|
||||
|
||||
+73
-60
@@ -419,10 +419,10 @@ ztest_random(uint64_t range)
|
||||
return (r % range);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
ztest_record_enospc(char *s)
|
||||
{
|
||||
dprintf("ENOSPC doing: %s\n", s ? s : "<unknown>");
|
||||
ztest_shared->zs_enospc_count++;
|
||||
}
|
||||
|
||||
@@ -698,15 +698,9 @@ ztest_random_compress(void)
|
||||
return ((uint8_t)ztest_random(ZIO_COMPRESS_FUNCTIONS));
|
||||
}
|
||||
|
||||
typedef struct ztest_replay {
|
||||
objset_t *zr_os;
|
||||
uint64_t zr_assign;
|
||||
} ztest_replay_t;
|
||||
|
||||
static int
|
||||
ztest_replay_create(ztest_replay_t *zr, lr_create_t *lr, boolean_t byteswap)
|
||||
ztest_replay_create(objset_t *os, lr_create_t *lr, boolean_t byteswap)
|
||||
{
|
||||
objset_t *os = zr->zr_os;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
|
||||
@@ -715,7 +709,7 @@ ztest_replay_create(ztest_replay_t *zr, lr_create_t *lr, boolean_t byteswap)
|
||||
|
||||
tx = dmu_tx_create(os);
|
||||
dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
|
||||
error = dmu_tx_assign(tx, zr->zr_assign);
|
||||
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
return (error);
|
||||
@@ -732,16 +726,15 @@ ztest_replay_create(ztest_replay_t *zr, lr_create_t *lr, boolean_t byteswap)
|
||||
(void) printf("replay create of %s object %llu"
|
||||
" in txg %llu = %d\n",
|
||||
osname, (u_longlong_t)lr->lr_doid,
|
||||
(u_longlong_t)zr->zr_assign, error);
|
||||
(u_longlong_t)dmu_tx_get_txg(tx), error);
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
ztest_replay_remove(ztest_replay_t *zr, lr_remove_t *lr, boolean_t byteswap)
|
||||
ztest_replay_remove(objset_t *os, lr_remove_t *lr, boolean_t byteswap)
|
||||
{
|
||||
objset_t *os = zr->zr_os;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
|
||||
@@ -750,7 +743,7 @@ ztest_replay_remove(ztest_replay_t *zr, lr_remove_t *lr, boolean_t byteswap)
|
||||
|
||||
tx = dmu_tx_create(os);
|
||||
dmu_tx_hold_free(tx, lr->lr_doid, 0, DMU_OBJECT_END);
|
||||
error = dmu_tx_assign(tx, zr->zr_assign);
|
||||
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
return (error);
|
||||
@@ -977,7 +970,7 @@ ztest_vdev_attach_detach(ztest_args_t *za)
|
||||
uint64_t leaves = MAX(zopt_mirrors, 1) * zopt_raidz;
|
||||
uint64_t leaf, top;
|
||||
uint64_t ashift = ztest_get_ashift();
|
||||
uint64_t oldguid;
|
||||
uint64_t oldguid, pguid;
|
||||
size_t oldsize, newsize;
|
||||
char oldpath[MAXPATHLEN], newpath[MAXPATHLEN];
|
||||
int replacing;
|
||||
@@ -1009,10 +1002,16 @@ ztest_vdev_attach_detach(ztest_args_t *za)
|
||||
* Locate this vdev.
|
||||
*/
|
||||
oldvd = rvd->vdev_child[top];
|
||||
if (zopt_mirrors >= 1)
|
||||
if (zopt_mirrors >= 1) {
|
||||
ASSERT(oldvd->vdev_ops == &vdev_mirror_ops);
|
||||
ASSERT(oldvd->vdev_children >= zopt_mirrors);
|
||||
oldvd = oldvd->vdev_child[leaf / zopt_raidz];
|
||||
if (zopt_raidz > 1)
|
||||
}
|
||||
if (zopt_raidz > 1) {
|
||||
ASSERT(oldvd->vdev_ops == &vdev_raidz_ops);
|
||||
ASSERT(oldvd->vdev_children == zopt_raidz);
|
||||
oldvd = oldvd->vdev_child[leaf % zopt_raidz];
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're already doing an attach or replace, oldvd may be a
|
||||
@@ -1020,8 +1019,8 @@ ztest_vdev_attach_detach(ztest_args_t *za)
|
||||
*/
|
||||
while (oldvd->vdev_children != 0) {
|
||||
oldvd_has_siblings = B_TRUE;
|
||||
ASSERT(oldvd->vdev_children == 2);
|
||||
oldvd = oldvd->vdev_child[ztest_random(2)];
|
||||
ASSERT(oldvd->vdev_children >= 2);
|
||||
oldvd = oldvd->vdev_child[ztest_random(oldvd->vdev_children)];
|
||||
}
|
||||
|
||||
oldguid = oldvd->vdev_guid;
|
||||
@@ -1029,16 +1028,17 @@ ztest_vdev_attach_detach(ztest_args_t *za)
|
||||
oldvd_is_log = oldvd->vdev_top->vdev_islog;
|
||||
(void) strcpy(oldpath, oldvd->vdev_path);
|
||||
pvd = oldvd->vdev_parent;
|
||||
pguid = pvd->vdev_guid;
|
||||
|
||||
/*
|
||||
* If oldvd has siblings, then half of the time, detach it.
|
||||
*/
|
||||
if (oldvd_has_siblings && ztest_random(2) == 0) {
|
||||
spa_config_exit(spa, SCL_VDEV, FTAG);
|
||||
error = spa_vdev_detach(spa, oldguid, B_FALSE);
|
||||
if (error != 0 && error != ENODEV && error != EBUSY)
|
||||
fatal(0, "detach (%s) returned %d",
|
||||
oldpath, error);
|
||||
error = spa_vdev_detach(spa, oldguid, pguid, B_FALSE);
|
||||
if (error != 0 && error != ENODEV && error != EBUSY &&
|
||||
error != ENOTSUP)
|
||||
fatal(0, "detach (%s) returned %d", oldpath, error);
|
||||
(void) mutex_unlock(&ztest_shared->zs_vdev_lock);
|
||||
return;
|
||||
}
|
||||
@@ -1138,7 +1138,6 @@ ztest_vdev_attach_detach(ztest_args_t *za)
|
||||
/*
|
||||
* Verify that dynamic LUN growth works as expected.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
void
|
||||
ztest_vdev_LUN_growth(ztest_args_t *za)
|
||||
{
|
||||
@@ -1278,7 +1277,6 @@ ztest_dmu_objset_create_destroy(ztest_args_t *za)
|
||||
zilog_t *zilog;
|
||||
uint64_t seq;
|
||||
uint64_t objects;
|
||||
ztest_replay_t zr;
|
||||
|
||||
(void) rw_rdlock(&ztest_shared->zs_name_lock);
|
||||
(void) snprintf(name, 100, "%s/%s_temp_%llu", za->za_pool, za->za_pool,
|
||||
@@ -1295,8 +1293,7 @@ ztest_dmu_objset_create_destroy(ztest_args_t *za)
|
||||
*/
|
||||
if (ztest_random(2) == 0 &&
|
||||
dmu_objset_open(name, DMU_OST_OTHER, DS_MODE_OWNER, &os) == 0) {
|
||||
zr.zr_os = os;
|
||||
zil_replay(os, &zr, &zr.zr_assign, ztest_replay_vector, NULL);
|
||||
zil_replay(os, os, ztest_replay_vector);
|
||||
dmu_objset_close(os);
|
||||
}
|
||||
|
||||
@@ -2059,8 +2056,6 @@ ztest_dmu_write_parallel(ztest_args_t *za)
|
||||
error = dmu_buf_hold(os, ZTEST_DIROBJ, blkoff, FTAG, &db);
|
||||
za->za_dbuf = db;
|
||||
if (error) {
|
||||
dprintf("dmu_buf_hold(%s, %d, %llx) = %d\n",
|
||||
osname, ZTEST_DIROBJ, blkoff, error);
|
||||
(void) mutex_unlock(lp);
|
||||
return;
|
||||
}
|
||||
@@ -2071,11 +2066,8 @@ ztest_dmu_write_parallel(ztest_args_t *za)
|
||||
|
||||
(void) mutex_unlock(lp);
|
||||
|
||||
if (error) {
|
||||
dprintf("dmu_sync(%s, %d, %llx) = %d\n",
|
||||
osname, ZTEST_DIROBJ, off, error);
|
||||
if (error)
|
||||
return;
|
||||
}
|
||||
|
||||
if (blk.blk_birth == 0) /* concurrent free */
|
||||
return;
|
||||
@@ -2584,8 +2576,6 @@ ztest_fault_inject(ztest_args_t *za)
|
||||
maxfaults = INT_MAX; /* no limit on cache devices */
|
||||
}
|
||||
|
||||
dprintf("damaging %s and %s\n", path0, pathrand);
|
||||
|
||||
spa_config_exit(spa, SCL_STATE, FTAG);
|
||||
|
||||
if (maxfaults == 0)
|
||||
@@ -2595,10 +2585,13 @@ ztest_fault_inject(ztest_args_t *za)
|
||||
* If we can tolerate two or more faults, randomly online/offline vd0.
|
||||
*/
|
||||
if (maxfaults >= 2 && guid0 != 0) {
|
||||
if (ztest_random(10) < 6)
|
||||
(void) vdev_offline(spa, guid0, B_TRUE);
|
||||
else
|
||||
(void) vdev_online(spa, guid0, B_FALSE, NULL);
|
||||
if (ztest_random(10) < 6) {
|
||||
int flags = (ztest_random(2) == 0 ?
|
||||
ZFS_OFFLINE_TEMPORARY : 0);
|
||||
VERIFY(vdev_offline(spa, guid0, flags) != EBUSY);
|
||||
} else {
|
||||
(void) vdev_online(spa, guid0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2853,7 +2846,7 @@ ztest_walk_pool_directory(char *header)
|
||||
static void
|
||||
ztest_spa_import_export(char *oldname, char *newname)
|
||||
{
|
||||
nvlist_t *config;
|
||||
nvlist_t *config, *newconfig;
|
||||
uint64_t pool_guid;
|
||||
spa_t *spa;
|
||||
int error;
|
||||
@@ -2875,6 +2868,12 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||
if (error)
|
||||
fatal(0, "spa_open('%s') = %d", oldname, error);
|
||||
|
||||
/*
|
||||
* Kick off a scrub to tickle scrub/export races.
|
||||
*/
|
||||
if (ztest_random(2) == 0)
|
||||
(void) spa_scrub(spa, POOL_SCRUB_EVERYTHING);
|
||||
|
||||
pool_guid = spa_guid(spa);
|
||||
spa_close(spa, FTAG);
|
||||
|
||||
@@ -2883,12 +2882,19 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||
/*
|
||||
* Export it.
|
||||
*/
|
||||
error = spa_export(oldname, &config, B_FALSE);
|
||||
error = spa_export(oldname, &config, B_FALSE, B_FALSE);
|
||||
if (error)
|
||||
fatal(0, "spa_export('%s') = %d", oldname, error);
|
||||
|
||||
ztest_walk_pool_directory("pools after export");
|
||||
|
||||
/*
|
||||
* Try to import it.
|
||||
*/
|
||||
newconfig = spa_tryimport(config);
|
||||
ASSERT(newconfig != NULL);
|
||||
nvlist_free(newconfig);
|
||||
|
||||
/*
|
||||
* Import it under the new name.
|
||||
*/
|
||||
@@ -2931,22 +2937,25 @@ ztest_spa_import_export(char *oldname, char *newname)
|
||||
nvlist_free(config);
|
||||
}
|
||||
|
||||
static void
|
||||
ztest_resume(spa_t *spa)
|
||||
{
|
||||
if (spa_suspended(spa)) {
|
||||
spa_vdev_state_enter(spa);
|
||||
vdev_clear(spa, NULL);
|
||||
(void) spa_vdev_state_exit(spa, NULL, 0);
|
||||
zio_resume(spa);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
ztest_resume(void *arg)
|
||||
ztest_resume_thread(void *arg)
|
||||
{
|
||||
spa_t *spa = arg;
|
||||
|
||||
while (!ztest_exiting) {
|
||||
(void) poll(NULL, 0, 1000);
|
||||
|
||||
if (!spa_suspended(spa))
|
||||
continue;
|
||||
|
||||
spa_vdev_state_enter(spa);
|
||||
vdev_clear(spa, NULL);
|
||||
(void) spa_vdev_state_exit(spa, NULL, 0);
|
||||
|
||||
zio_resume(spa);
|
||||
ztest_resume(spa);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
@@ -3088,10 +3097,20 @@ ztest_run(char *pool)
|
||||
*/
|
||||
VERIFY(spa_open(pool, &spa, FTAG) == 0);
|
||||
|
||||
/*
|
||||
* We don't expect the pool to suspend unless maxfaults == 0,
|
||||
* in which case ztest_fault_inject() temporarily takes away
|
||||
* the only valid replica.
|
||||
*/
|
||||
if (zopt_maxfaults == 0)
|
||||
spa->spa_failmode = ZIO_FAILURE_MODE_WAIT;
|
||||
else
|
||||
spa->spa_failmode = ZIO_FAILURE_MODE_PANIC;
|
||||
|
||||
/*
|
||||
* Create a thread to periodically resume suspended I/O.
|
||||
*/
|
||||
VERIFY(thr_create(0, 0, ztest_resume, spa, THR_BOUND,
|
||||
VERIFY(thr_create(0, 0, ztest_resume_thread, spa, THR_BOUND,
|
||||
&resume_tid) == 0);
|
||||
|
||||
/*
|
||||
@@ -3140,7 +3159,6 @@ ztest_run(char *pool)
|
||||
za[t].za_kill = za[0].za_kill;
|
||||
|
||||
if (t < zopt_datasets) {
|
||||
ztest_replay_t zr;
|
||||
int test_future = FALSE;
|
||||
(void) rw_rdlock(&ztest_shared->zs_name_lock);
|
||||
(void) snprintf(name, 100, "%s/%s_%d", pool, pool, d);
|
||||
@@ -3164,9 +3182,8 @@ ztest_run(char *pool)
|
||||
(void) rw_unlock(&ztest_shared->zs_name_lock);
|
||||
if (test_future)
|
||||
ztest_dmu_check_future_leak(&za[t]);
|
||||
zr.zr_os = za[d].za_os;
|
||||
zil_replay(zr.zr_os, &zr, &zr.zr_assign,
|
||||
ztest_replay_vector, NULL);
|
||||
zil_replay(za[d].za_os, za[d].za_os,
|
||||
ztest_replay_vector);
|
||||
za[d].za_zilog = zil_open(za[d].za_os, NULL);
|
||||
}
|
||||
|
||||
@@ -3211,6 +3228,7 @@ ztest_run(char *pool)
|
||||
/* Kill the resume thread */
|
||||
ztest_exiting = B_TRUE;
|
||||
VERIFY(thr_join(resume_tid, NULL, NULL) == 0);
|
||||
ztest_resume(spa);
|
||||
|
||||
/*
|
||||
* Right before closing the pool, kick off a bunch of async I/O;
|
||||
@@ -3306,11 +3324,6 @@ main(int argc, char **argv)
|
||||
|
||||
process_options(argc, argv);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
/*
|
||||
* Blow away any existing copy of zpool.cache
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user