]> granicus.if.org Git - zfs/commitdiff
Illumos #3949, #3950, #3952, #3953
authorGeorge Wilson <george.wilson@delphix.com>
Wed, 7 Aug 2013 18:24:34 +0000 (10:24 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 5 Nov 2013 20:17:07 +0000 (12:17 -0800)
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 <mahrens@delphix.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>
Approved by: Richard Lowe <richlowe@richlowe.net>

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 <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
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.

cmd/ztest/ztest.c
module/zfs/spa.c
module/zfs/vdev_file.c

index 0a7ca1c164aa82b8368a7a20ea0cda68befb89cb..572af3e0bb41aab7c0151ad5e7e59769e06670d8 100644 (file)
@@ -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    },
@@ -4913,6 +4913,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.
         */
@@ -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
index 6bd640b404a713a9fccc219089c3a0a462f72b6c..6b9b079df4489f0c9eaaf842934964e0f5889579 100644 (file)
@@ -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
index 5eadc560d730ba6ae213286d23c8fd5d461639b9..c0d062b0e445ae373d28c5ebfa7c6f2840802e83 100644 (file)
@@ -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);
 }