]> granicus.if.org Git - zfs/commitdiff
Fix ztest deadlock in ztest_zil_remount()
authorTom Caputi <tcaputi@datto.com>
Tue, 4 Dec 2018 17:43:31 +0000 (12:43 -0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 4 Dec 2018 17:43:31 +0000 (09:43 -0800)
This patch fixes a small race condition in ztest_zil_remount()
that could result in a deadlock. ztest_device_removal() calls
spa_vdev_remove() which may eventually call spa_reset_logs().
If ztest_zil_remount() attempts to call zil_close() while this
is happening, it may fail when it asserts !zilog_is_dirty(zilog).
This patch simply adds locking to correct the issue.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #8154

cmd/ztest/ztest.c

index 111d45b9d9fa5a3c6f89b18a213d648c9e9745b2..0d9495a28782e800a690eaf59c01a254beed8e86 100644 (file)
@@ -2673,6 +2673,13 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
 {
        objset_t *os = zd->zd_os;
 
+       /*
+        * We hold the ztest_vdev_lock so we don't cause problems with
+        * other threads that wish to remove a log device, such as
+        * ztest_device_removal().
+        */
+       mutex_enter(&ztest_vdev_lock);
+
        /*
         * We grab the zd_dirobj_lock to ensure that no other thread is
         * updating the zil (i.e. adding in-memory log records) and the
@@ -2690,6 +2697,7 @@ ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
 
        (void) pthread_rwlock_unlock(&zd->zd_zilog_lock);
        mutex_exit(&zd->zd_dirobj_lock);
+       mutex_exit(&ztest_vdev_lock);
 }
 
 /*