summaryrefslogtreecommitdiffstats
path: root/cmd/ztest
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/ztest')
-rw-r--r--cmd/ztest/ztest.c113
1 files changed, 104 insertions, 9 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
index 83a8b4f3c..78ad7e8de 100644
--- a/cmd/ztest/ztest.c
+++ b/cmd/ztest/ztest.c
@@ -345,6 +345,7 @@ ztest_func_t ztest_reguid;
ztest_func_t ztest_spa_upgrade;
ztest_func_t ztest_device_removal;
ztest_func_t ztest_remap_blocks;
+ztest_func_t ztest_spa_checkpoint_create_discard;
ztest_func_t ztest_fletcher;
ztest_func_t ztest_fletcher_incr;
ztest_func_t ztest_verify_dnode_bt;
@@ -397,6 +398,7 @@ ztest_info_t ztest_info[] = {
ZTI_INIT(ztest_vdev_aux_add_remove, 1, &ztest_opts.zo_vdevtime),
ZTI_INIT(ztest_device_removal, 1, &zopt_sometimes),
ZTI_INIT(ztest_remap_blocks, 1, &zopt_sometimes),
+ ZTI_INIT(ztest_spa_checkpoint_create_discard, 1, &zopt_rarely),
ZTI_INIT(ztest_fletcher, 1, &zopt_rarely),
ZTI_INIT(ztest_fletcher_incr, 1, &zopt_rarely),
ZTI_INIT(ztest_verify_dnode_bt, 1, &zopt_sometimes),
@@ -446,6 +448,7 @@ static ztest_ds_t *ztest_ds;
static kmutex_t ztest_vdev_lock;
static boolean_t ztest_device_removal_active = B_FALSE;
+static kmutex_t ztest_checkpoint_lock;
/*
* The ztest_name_lock protects the pool and dataset namespace used by
@@ -2864,6 +2867,62 @@ ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
mutex_exit(&ztest_vdev_lock);
}
+static void
+ztest_spa_checkpoint(spa_t *spa)
+{
+ ASSERT(MUTEX_HELD(&ztest_checkpoint_lock));
+
+ int error = spa_checkpoint(spa->spa_name);
+
+ switch (error) {
+ case 0:
+ case ZFS_ERR_DEVRM_IN_PROGRESS:
+ case ZFS_ERR_DISCARDING_CHECKPOINT:
+ case ZFS_ERR_CHECKPOINT_EXISTS:
+ break;
+ case ENOSPC:
+ ztest_record_enospc(FTAG);
+ break;
+ default:
+ fatal(0, "spa_checkpoint(%s) = %d", spa->spa_name, error);
+ }
+}
+
+static void
+ztest_spa_discard_checkpoint(spa_t *spa)
+{
+ ASSERT(MUTEX_HELD(&ztest_checkpoint_lock));
+
+ int error = spa_checkpoint_discard(spa->spa_name);
+
+ switch (error) {
+ case 0:
+ case ZFS_ERR_DISCARDING_CHECKPOINT:
+ case ZFS_ERR_NO_CHECKPOINT:
+ break;
+ default:
+ fatal(0, "spa_discard_checkpoint(%s) = %d",
+ spa->spa_name, error);
+ }
+
+}
+
+/* ARGSUSED */
+void
+ztest_spa_checkpoint_create_discard(ztest_ds_t *zd, uint64_t id)
+{
+ spa_t *spa = ztest_spa;
+
+ mutex_enter(&ztest_checkpoint_lock);
+ if (ztest_random(2) == 0) {
+ ztest_spa_checkpoint(spa);
+ } else {
+ ztest_spa_discard_checkpoint(spa);
+ }
+ mutex_exit(&ztest_checkpoint_lock);
+}
+
+
static vdev_t *
vdev_lookup_by_path(vdev_t *vd, const char *path)
{
@@ -2953,6 +3012,8 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
case EEXIST: /* Generic zil_reset() error */
case EBUSY: /* Replay required */
case EACCES: /* Crypto key not loaded */
+ case ZFS_ERR_CHECKPOINT_EXISTS:
+ case ZFS_ERR_DISCARDING_CHECKPOINT:
break;
default:
fatal(0, "spa_vdev_remove() = %d", error);
@@ -2971,10 +3032,15 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
error = spa_vdev_add(spa, nvroot);
nvlist_free(nvroot);
- if (error == ENOSPC)
+ switch (error) {
+ case 0:
+ break;
+ case ENOSPC:
ztest_record_enospc("spa_vdev_add");
- else if (error != 0)
+ break;
+ default:
fatal(0, "spa_vdev_add() = %d", error);
+ }
}
mutex_exit(&ztest_vdev_lock);
@@ -3048,8 +3114,13 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
nvlist_t *nvroot = make_vdev_root(NULL, aux, NULL,
(ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
error = spa_vdev_add(spa, nvroot);
- if (error != 0)
+
+ switch (error) {
+ case 0:
+ break;
+ default:
fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
+ }
nvlist_free(nvroot);
} else {
/*
@@ -3061,8 +3132,16 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
(void) vdev_online(spa, guid, 0, NULL);
error = spa_vdev_remove(spa, guid, B_FALSE);
- if (error != 0 && error != EBUSY)
+
+ switch (error) {
+ case 0:
+ case EBUSY:
+ case ZFS_ERR_CHECKPOINT_EXISTS:
+ case ZFS_ERR_DISCARDING_CHECKPOINT:
+ break;
+ default:
fatal(0, "spa_vdev_remove(%llu) = %d", guid, error);
+ }
}
mutex_exit(&ztest_vdev_lock);
@@ -3166,7 +3245,6 @@ ztest_split_pool(ztest_ds_t *zd, uint64_t id)
--zs->zs_mirrors;
}
mutex_exit(&ztest_vdev_lock);
-
}
/*
@@ -3271,7 +3349,8 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
spa_config_exit(spa, SCL_ALL, FTAG);
error = spa_vdev_detach(spa, oldguid, pguid, B_FALSE);
if (error != 0 && error != ENODEV && error != EBUSY &&
- error != ENOTSUP)
+ error != ENOTSUP && error != ZFS_ERR_CHECKPOINT_EXISTS &&
+ error != ZFS_ERR_DISCARDING_CHECKPOINT)
fatal(0, "detach (%s) returned %d", oldpath, error);
goto out;
}
@@ -3362,6 +3441,10 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
if (error == EOVERFLOW || error == EBUSY)
expected_error = error;
+ if (error == ZFS_ERR_CHECKPOINT_EXISTS ||
+ error == ZFS_ERR_DISCARDING_CHECKPOINT)
+ expected_error = error;
+
/* XXX workaround 6690467 */
if (error != expected_error && expected_error != EBUSY) {
fatal(0, "attach (%s %llu, %s %llu, %d) "
@@ -3556,6 +3639,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
uint64_t top;
uint64_t old_class_space, new_class_space, old_ms_count, new_ms_count;
+ mutex_enter(&ztest_checkpoint_lock);
mutex_enter(&ztest_vdev_lock);
spa_config_enter(spa, SCL_STATE, spa, RW_READER);
@@ -3566,8 +3650,9 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
* when the device removal completes).
*/
if (ztest_device_removal_active) {
- spa_config_exit(spa, SCL_STATE, FTAG);
+ spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
+ mutex_exit(&ztest_checkpoint_lock);
return;
}
@@ -3597,6 +3682,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
psize == 0 || psize >= 4 * ztest_opts.zo_vdev_size) {
spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
+ mutex_exit(&ztest_checkpoint_lock);
return;
}
ASSERT(psize > 0);
@@ -3622,6 +3708,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
}
spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
+ mutex_exit(&ztest_checkpoint_lock);
return;
}
@@ -3656,6 +3743,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
}
spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
+ mutex_exit(&ztest_checkpoint_lock);
return;
}
@@ -3686,6 +3774,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
spa_config_exit(spa, SCL_STATE, spa);
mutex_exit(&ztest_vdev_lock);
+ mutex_exit(&ztest_checkpoint_lock);
}
/*
@@ -5722,7 +5811,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
*/
fd = open(pathrand, O_RDWR);
- if (fd == -1) /* we hit a gap in the device namespace */
+ if (fd == -1) /* we hit a gap in the device namespace */
goto out;
fsize = lseek(fd, 0, SEEK_END);
@@ -6645,6 +6734,7 @@ ztest_run(ztest_shared_t *zs)
* Initialize parent/child shared state.
*/
mutex_init(&ztest_vdev_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&ztest_checkpoint_lock, NULL, MUTEX_DEFAULT, NULL);
VERIFY0(pthread_rwlock_init(&ztest_name_lock, NULL));
zs->zs_thread_start = gethrtime();
@@ -6696,7 +6786,7 @@ ztest_run(ztest_shared_t *zs)
spa->spa_deadman_failmode = ZIO_FAILURE_MODE_PANIC;
/*
- * Verify that we can safely inquire about about any object,
+ * Verify that we can safely inquire about any object,
* whether it's allocated or not. To make it interesting,
* we probe a 5-wide window around each power of two.
* This hits all edge cases, including zero and the max.
@@ -6804,6 +6894,7 @@ ztest_run(ztest_shared_t *zs)
mutex_destroy(&zcl.zcl_callbacks_lock);
(void) pthread_rwlock_destroy(&ztest_name_lock);
mutex_destroy(&ztest_vdev_lock);
+ mutex_destroy(&ztest_checkpoint_lock);
}
static void
@@ -6953,6 +7044,7 @@ ztest_import(ztest_shared_t *zs)
int error;
mutex_init(&ztest_vdev_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&ztest_checkpoint_lock, NULL, MUTEX_DEFAULT, NULL);
VERIFY0(pthread_rwlock_init(&ztest_name_lock, NULL));
kernel_init(FREAD | FWRITE);
@@ -6984,6 +7076,7 @@ ztest_import(ztest_shared_t *zs)
(void) pthread_rwlock_destroy(&ztest_name_lock);
mutex_destroy(&ztest_vdev_lock);
+ mutex_destroy(&ztest_checkpoint_lock);
}
/*
@@ -6998,6 +7091,7 @@ ztest_init(ztest_shared_t *zs)
int i;
mutex_init(&ztest_vdev_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&ztest_checkpoint_lock, NULL, MUTEX_DEFAULT, NULL);
VERIFY0(pthread_rwlock_init(&ztest_name_lock, NULL));
kernel_init(FREAD | FWRITE);
@@ -7049,6 +7143,7 @@ ztest_init(ztest_shared_t *zs)
(void) pthread_rwlock_destroy(&ztest_name_lock);
mutex_destroy(&ztest_vdev_lock);
+ mutex_destroy(&ztest_checkpoint_lock);
}
static void