#include <sys/fs/zfs.h>
#include <zfs_fletcher.h>
#include <libnvpair.h>
-#include <libzfs.h>
+#include <libzutil.h>
#include <sys/crypto/icp.h>
#ifdef __GLIBC__
#include <execinfo.h> /* for backtrace() */
uint64_t zo_metaslab_force_ganging;
int zo_mmp_test;
int zo_special_vdevs;
+ int zo_dump_dbgmsg;
} ztest_shared_opts_t;
static const ztest_shared_opts_t ztest_opts_defaults = {
.zo_init = 1,
.zo_time = 300, /* 5 minutes */
.zo_maxloops = 50, /* max loops during spa_freeze() */
- .zo_metaslab_force_ganging = 32 << 10,
+ .zo_metaslab_force_ganging = 64 << 10,
.zo_special_vdevs = ZTEST_VDEV_CLASS_RND,
};
static pthread_rwlock_t ztest_name_lock;
static boolean_t ztest_dump_core = B_TRUE;
-static boolean_t ztest_dump_debug_buffer = B_FALSE;
static boolean_t ztest_exiting;
/* Global commit callback list */
static void
dump_debug_buffer(void)
{
- if (!ztest_dump_debug_buffer)
+ ssize_t ret __attribute__((unused));
+
+ if (!ztest_opts.zo_dump_dbgmsg)
return;
- (void) printf("\n");
+ /*
+ * We use write() instead of printf() so that this function
+ * is safe to call from a signal handler.
+ */
+ ret = write(STDOUT_FILENO, "\n", 1);
zfs_dbgmsg_print("ztest");
}
(void) fprintf(stderr, "%s\n", buf);
fatal_msg = buf; /* to ease debugging */
- dump_debug_buffer();
-
if (ztest_dump_core)
abort();
+ else
+ dump_debug_buffer();
+
exit(3);
}
usage(B_FALSE);
break;
case 'G':
- ztest_dump_debug_buffer = B_TRUE;
+ zo->zo_dump_dbgmsg = 1;
break;
case 'h':
usage(B_TRUE);
ztest_device_removal_active = B_TRUE;
mutex_exit(&ztest_vdev_lock);
+ /*
+ * spa->spa_vdev_removal is created in a sync task that
+ * is initiated via dsl_sync_task_nowait(). Since the
+ * task may not run before spa_vdev_remove() returns, we
+ * must wait at least 1 txg to ensure that the removal
+ * struct has been created.
+ */
+ txg_wait_synced(spa_get_dsl(spa), 0);
+
while (spa->spa_vdev_removal != NULL)
txg_wait_synced(spa_get_dsl(spa), 0);
} else {
static void
ztest_import(ztest_shared_t *zs)
{
- libzfs_handle_t *hdl;
importargs_t args = { 0 };
spa_t *spa;
nvlist_t *cfg = NULL;
VERIFY0(pthread_rwlock_init(&ztest_name_lock, NULL));
kernel_init(FREAD | FWRITE);
- hdl = libzfs_init();
searchdirs[0] = ztest_opts.zo_dir;
args.paths = nsearch;
args.path = searchdirs;
args.can_be_active = B_FALSE;
- error = zpool_tryimport(hdl, name, &cfg, &args);
+ error = zpool_find_config(NULL, name, &cfg, &args,
+ &libzpool_config_ops);
if (error)
(void) fatal(0, "No pools found\n");
1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift;
spa_close(spa, FTAG);
- libzfs_fini(hdl);
kernel_fini();
if (!ztest_opts.zo_mmp_test) {
* Verify that even extensively damaged split blocks with many
* segments can be reconstructed in a reasonable amount of time
* when reconstruction is known to be possible.
+ *
+ * Note: the lower this value is, the more damage we inflict, and
+ * the more time ztest spends in recovering that damage. We chose
+ * to induce damage 1/100th of the time so recovery is tested but
+ * not so frequently that ztest doesn't get to test other code paths.
*/
- zfs_reconstruct_indirect_damage_fraction = 4;
+ zfs_reconstruct_indirect_damage_fraction = 100;
action.sa_handler = sig_handler;
sigemptyset(&action.sa_mask);