aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Wilson <[email protected]>2013-08-07 10:24:34 -0800
committerBrian Behlendorf <[email protected]>2013-11-05 12:17:07 -0800
commit621dd7bb2c970838bcf2226ac365c517af7a4bb1 (patch)
treefd3dc57f0179a014959a4316f08694d953dab8a1
parent383fc4a9970ede483dc4bd7579f1c62942d1312f (diff)
Illumos #3949, #3950, #3952, #3953
3949 ztest fault injection should avoid resilvering devices 3950 ztest: deadman fires when we're doing a scan 3951 ztest hang when running dedup test 3952 ztest: ztest_reguid test and ztest_fault_inject don't place nice together Reviewed by: Matthew Ahrens <[email protected]> Reviewed by: Adam Leventhal <[email protected]> Approved by: Richard Lowe <[email protected]> References: https://www.illumos.org/issues/3949 https://www.illumos.org/issues/3950 https://www.illumos.org/issues/3951 https://www.illumos.org/issues/3952 illumos/illumos-gate@2c1e2b44148432fb7a509dd216a99299b6740250 Ported-by: Richard Yao <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #1775 Porting notes: 1. The deadman thread was removed from ztest during the original port because it depended on Solaris thr_create() interface. This functionality should be reintroduced using the more portable pthreads.
-rw-r--r--cmd/ztest/ztest.c21
-rw-r--r--module/zfs/spa.c10
-rw-r--r--module/zfs/vdev_file.c5
3 files changed, 30 insertions, 6 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index 0a7ca1c16..572af3e0b 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -366,7 +366,7 @@ ztest_info_t ztest_info[] = {
{ ztest_fault_inject, 1, &zopt_sometimes },
{ ztest_ddt_repair, 1, &zopt_sometimes },
{ ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
- { ztest_reguid, 1, &zopt_sometimes },
+ { ztest_reguid, 1, &zopt_rarely },
{ ztest_spa_rename, 1, &zopt_rarely },
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_spa_upgrade, 1, &zopt_rarely },
@@ -4914,6 +4914,14 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
ASSERT(leaves >= 1);
/*
+ * Grab the name lock as reader. There are some operations
+ * which don't like to have their vdevs changed while
+ * they are in progress (i.e. spa_change_guid). Those
+ * operations will have grabbed the name lock as writer.
+ */
+ (void) rw_enter(&ztest_name_lock, RW_READER);
+
+ /*
* We need SCL_STATE here because we're going to look at vd0->vdev_tsd.
*/
spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
@@ -4942,7 +4950,14 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
if (vd0 != NULL && vd0->vdev_top->vdev_islog)
islog = B_TRUE;
- if (vd0 != NULL && maxfaults != 1) {
+ /*
+ * If the top-level vdev needs to be resilvered
+ * then we only allow faults on the device that is
+ * resilvering.
+ */
+ if (vd0 != NULL && maxfaults != 1 &&
+ (!vdev_resilver_needed(vd0->vdev_top, NULL, NULL) ||
+ vd0->vdev_resilvering)) {
/*
* Make vd0 explicitly claim to be unreadable,
* or unwriteable, or reach behind its back
@@ -4973,6 +4988,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
if (sav->sav_count == 0) {
spa_config_exit(spa, SCL_STATE, FTAG);
+ (void) rw_exit(&ztest_name_lock);
goto out;
}
vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
@@ -4986,6 +5002,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
}
spa_config_exit(spa, SCL_STATE, FTAG);
+ (void) rw_exit(&ztest_name_lock);
/*
* If we can tolerate two or more faults, or we're dealing
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index 6bd640b40..6b9b079df 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -752,6 +752,7 @@ spa_change_guid(spa_t *spa)
int error;
uint64_t guid;
+ mutex_enter(&spa->spa_vdev_top_lock);
mutex_enter(&spa_namespace_lock);
guid = spa_generate_guid(NULL);
@@ -764,6 +765,7 @@ spa_change_guid(spa_t *spa)
}
mutex_exit(&spa_namespace_lock);
+ mutex_exit(&spa->spa_vdev_top_lock);
return (error);
}
@@ -4737,7 +4739,6 @@ spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done)
if (pvd->vdev_ops == &vdev_spare_ops)
cvd->vdev_unspare = B_FALSE;
vdev_remove_parent(cvd);
- cvd->vdev_resilvering = B_FALSE;
}
@@ -5369,6 +5370,13 @@ spa_vdev_resilver_done_hunt(vdev_t *vd)
return (oldvd);
}
+ if (vd->vdev_resilvering && vdev_dtl_empty(vd, DTL_MISSING) &&
+ vdev_dtl_empty(vd, DTL_OUTAGE)) {
+ ASSERT(vd->vdev_ops->vdev_op_leaf);
+ vd->vdev_resilvering = B_FALSE;
+ vdev_config_dirty(vd->vdev_top);
+ }
+
/*
* Check for a completed replacement. We always consider the first
* vdev in the list to be the oldest vdev, and the last one to be
diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c
index 5eadc560d..c0d062b0e 100644
--- a/module/zfs/vdev_file.c
+++ b/module/zfs/vdev_file.c
@@ -162,7 +162,6 @@ vdev_file_io_strategy(void *arg)
static int
vdev_file_io_start(zio_t *zio)
{
- spa_t *spa = zio->io_spa;
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
@@ -185,8 +184,8 @@ vdev_file_io_start(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
}
- spa_taskq_dispatch_ent(spa, ZIO_TYPE_FREE, ZIO_TASKQ_ISSUE,
- vdev_file_io_strategy, zio, 0, &zio->io_tqent);
+ VERIFY3U(taskq_dispatch(system_taskq, vdev_file_io_strategy, zio,
+ TQ_SLEEP), !=, 0);
return (ZIO_PIPELINE_STOP);
}