xref: /illumos-gate/usr/src/cmd/ztest/ztest.c (revision a0fbb7fb)
1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5441d80aaSlling  * Common Development and Distribution License (the "License").
6441d80aaSlling  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
21fa9e4066Sahrens /*
2247cb52daSJeff Bonwick  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23663207adSDon Brady  * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
24e9103aaeSGarrett D'Amore  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
25a7a845e4SSteven Hartland  * Copyright (c) 2013 Steven Hartland. All rights reserved.
26c3d26abcSMatthew Ahrens  * Copyright (c) 2014 Integros [integros.com]
270a055120SJason King  * Copyright 2017 Joyent, Inc.
28663207adSDon Brady  * Copyright (c) 2017, Intel Corporation.
29f06dce2cSAndrew Stormont  * Copyright 2017 RackTop Systems.
30fa9e4066Sahrens  */
32fa9e4066Sahrens /*
33fa9e4066Sahrens  * The objective of this program is to provide a DMU/ZAP/SPA stress test
34fa9e4066Sahrens  * that runs entirely in userland, is easy to use, and easy to extend.
35fa9e4066Sahrens  *
36fa9e4066Sahrens  * The overall design of the ztest program is as follows:
37fa9e4066Sahrens  *
38fa9e4066Sahrens  * (1) For each major functional area (e.g. adding vdevs to a pool,
39fa9e4066Sahrens  *     creating and destroying datasets, reading and writing objects, etc)
40fa9e4066Sahrens  *     we have a simple routine to test that functionality.  These
41fa9e4066Sahrens  *     individual routines do not have to do anything "stressful".
42fa9e4066Sahrens  *
43fa9e4066Sahrens  * (2) We turn these simple functionality tests into a stress test by
44fa9e4066Sahrens  *     running them all in parallel, with as many threads as desired,
45fa9e4066Sahrens  *     and spread across as many datasets, objects, and vdevs as desired.
46fa9e4066Sahrens  *
47fa9e4066Sahrens  * (3) While all this is happening, we inject faults into the pool to
48fa9e4066Sahrens  *     verify that self-healing data really works.
49fa9e4066Sahrens  *
50fa9e4066Sahrens  * (4) Every time we open a dataset, we change its checksum and compression
51fa9e4066Sahrens  *     functions.  Thus even individual objects vary from block to block
52fa9e4066Sahrens  *     in which checksum they use and whether they're compressed.
53fa9e4066Sahrens  *
54fa9e4066Sahrens  * (5) To verify that we never lose on-disk consistency after a crash,
55fa9e4066Sahrens  *     we run the entire test in a child of the main process.
56fa9e4066Sahrens  *     At random times, the child self-immolates with a SIGKILL.
57fa9e4066Sahrens  *     This is the software equivalent of pulling the power cord.
58fa9e4066Sahrens  *     The parent then runs the test again, using the existing
595d7b4d43SMatthew Ahrens  *     storage pool, as many times as desired. If backwards compatibility
60420dfc95SChris Siden  *     testing is enabled ztest will sometimes run the "older" version
61420dfc95SChris Siden  *     of ztest after a SIGKILL.
62fa9e4066Sahrens  *
63fa9e4066Sahrens  * (6) To verify that we don't have future leaks or temporal incursions,
64fa9e4066Sahrens  *     many of the functional tests record the transaction group number
65fa9e4066Sahrens  *     as part of their data.  When reading old data, they verify that
66fa9e4066Sahrens  *     the transaction group number is less than the current, open txg.
67fa9e4066Sahrens  *     If you add a new test, please do this if applicable.
68fa9e4066Sahrens  *
69fa9e4066Sahrens  * When run with no arguments, ztest runs for about five minutes and
70fa9e4066Sahrens  * produces no output if successful.  To get a little bit of information,
71fa9e4066Sahrens  * specify -V.  To get more information, specify -VV, and so on.
72fa9e4066Sahrens  *
73fa9e4066Sahrens  * To turn this into an overnight stress test, use -T to specify run time.
74fa9e4066Sahrens  *
75fa9e4066Sahrens  * You can ask more more vdevs [-v], datasets [-d], or threads [-t]
76fa9e4066Sahrens  * to increase the pool capacity, fanout, and overall stress level.
77fa9e4066Sahrens  *
78420dfc95SChris Siden  * Use the -k option to set the desired frequency of kills.
79420dfc95SChris Siden  *
80420dfc95SChris Siden  * When ztest invokes itself it passes all relevant information through a
81420dfc95SChris Siden  * temporary file which is mmap-ed in the child process. This allows shared
82420dfc95SChris Siden  * memory to survive the exec syscall. The ztest_shared_hdr_t struct is always
83420dfc95SChris Siden  * stored at offset 0 of this file and contains information on the size and
84420dfc95SChris Siden  * number of shared structures in the file. The information stored in this file
85420dfc95SChris Siden  * must remain backwards compatible with older versions of ztest so that
86420dfc95SChris Siden  * ztest can invoke them during backwards compatibility testing (-B).
87fa9e4066Sahrens  */
89fa9e4066Sahrens #include <sys/zfs_context.h>
90fa9e4066Sahrens #include <sys/spa.h>
91fa9e4066Sahrens #include <sys/dmu.h>
92fa9e4066Sahrens #include <sys/txg.h>
932fdbea25SAleksandr Guzovskiy #include <sys/dbuf.h>
94fa9e4066Sahrens #include <sys/zap.h>
95fa9e4066Sahrens #include <sys/dmu_objset.h>
96fa9e4066Sahrens #include <sys/poll.h>
97fa9e4066Sahrens #include <sys/stat.h>
98fa9e4066Sahrens #include <sys/time.h>
99fa9e4066Sahrens #include <sys/wait.h>
100fa9e4066Sahrens #include <sys/mman.h>
101fa9e4066Sahrens #include <sys/resource.h>
102fa9e4066Sahrens #include <sys/zio.h>
103fa9e4066Sahrens #include <sys/zil.h>
104b24ab676SJeff Bonwick #include <sys/zil_impl.h>
105fa9e4066Sahrens #include <sys/vdev_impl.h>
106e14bb325SJeff Bonwick #include <sys/vdev_file.h>
107094e47e9SGeorge Wilson #include <sys/vdev_initialize.h>
108084fd14fSBrian Behlendorf #include <sys/vdev_trim.h>
109fa9e4066Sahrens #include <sys/spa_impl.h>
11088ecc943SGeorge Wilson #include <sys/metaslab_impl.h>
111fa9e4066Sahrens #include <sys/dsl_prop.h>
1124f5064b7SMark J Musante #include <sys/dsl_dataset.h>
1133b2aab18SMatthew Ahrens #include <sys/dsl_destroy.h>
1143f9d6ad7SLin Ling #include <sys/dsl_scan.h>
115cde58dbcSMatthew Ahrens #include <sys/zio_checksum.h>
116fa9e4066Sahrens #include <sys/refcount.h>
117ad135b5dSChristopher Siden #include <sys/zfeature.h>
1183b2aab18SMatthew Ahrens #include <sys/dsl_userhold.h>
119770499e1SDan Kimmel #include <sys/abd.h>
120fa9e4066Sahrens #include <stdio.h>
121004388ebScasper #include <stdio_ext.h>
122fa9e4066Sahrens #include <stdlib.h>
123fa9e4066Sahrens #include <unistd.h>
124fa9e4066Sahrens #include <signal.h>
125fa9e4066Sahrens #include <umem.h>
126fa9e4066Sahrens #include <dlfcn.h>
127fa9e4066Sahrens #include <ctype.h>
128fa9e4066Sahrens #include <math.h>
129fa9e4066Sahrens #include <sys/fs/zfs.h>
130b24ab676SJeff Bonwick #include <libnvpair.h>
131d8ab6e12SDon Brady #include <libzutil.h>
1320a055120SJason King #include <libcmdutils.h>
134741652b0SEtienne Dechamps static int ztest_fd_data = -1;
135741652b0SEtienne Dechamps static int ztest_fd_rand = -1;
136420dfc95SChris Siden 
137420dfc95SChris Siden typedef struct ztest_shared_hdr {
138420dfc95SChris Siden 	uint64_t	zh_hdr_size;
139420dfc95SChris Siden 	uint64_t	zh_opts_size;
140420dfc95SChris Siden 	uint64_t	zh_size;
141420dfc95SChris Siden 	uint64_t	zh_stats_size;
142420dfc95SChris Siden 	uint64_t	zh_stats_count;
143420dfc95SChris Siden 	uint64_t	zh_ds_size;
144420dfc95SChris Siden 	uint64_t	zh_ds_count;
145420dfc95SChris Siden } ztest_shared_hdr_t;
146420dfc95SChris Siden 
147420dfc95SChris Siden static ztest_shared_hdr_t *ztest_shared_hdr;
148420dfc95SChris Siden 
149663207adSDon Brady enum ztest_class_state {
150663207adSDon Brady 	ZTEST_VDEV_CLASS_OFF,
151663207adSDon Brady 	ZTEST_VDEV_CLASS_ON,
152663207adSDon Brady 	ZTEST_VDEV_CLASS_RND
153663207adSDon Brady };
154663207adSDon Brady 
155420dfc95SChris Siden typedef struct ztest_shared_opts {
1569adfa60dSMatthew Ahrens 	char zo_pool[ZFS_MAX_DATASET_NAME_LEN];
1579adfa60dSMatthew Ahrens 	char zo_dir[ZFS_MAX_DATASET_NAME_LEN];
158420dfc95SChris Siden 	char zo_alt_ztest[MAXNAMELEN];
159420dfc95SChris Siden 	char zo_alt_libpath[MAXNAMELEN];
160420dfc95SChris Siden 	uint64_t zo_vdevs;
161420dfc95SChris Siden 	uint64_t zo_vdevtime;
162420dfc95SChris Siden 	size_t zo_vdev_size;
163420dfc95SChris Siden 	int zo_ashift;
164420dfc95SChris Siden 	int zo_mirrors;
165420dfc95SChris Siden 	int zo_raidz;
166420dfc95SChris Siden 	int zo_raidz_parity;
167420dfc95SChris Siden 	int zo_datasets;
168420dfc95SChris Siden 	int zo_threads;
169420dfc95SChris Siden 	uint64_t zo_passtime;
170420dfc95SChris Siden 	uint64_t zo_killrate;
171420dfc95SChris Siden 	int zo_verbose;
172420dfc95SChris Siden 	int zo_init;
173420dfc95SChris Siden 	uint64_t zo_time;
174420dfc95SChris Siden 	uint64_t zo_maxloops;
175243952c7SMatt Ahrens 	uint64_t zo_metaslab_force_ganging;
176e0f1c0afSOlaf Faaland 	int zo_mmp_test;
177663207adSDon Brady 	int zo_special_vdevs;
178420dfc95SChris Siden } ztest_shared_opts_t;
179420dfc95SChris Siden 
180420dfc95SChris Siden static const ztest_shared_opts_t ztest_opts_defaults = {
181420dfc95SChris Siden 	.zo_pool = { 'z', 't', 'e', 's', 't', '\0' },
182420dfc95SChris Siden 	.zo_dir = { '/', 't', 'm', 'p', '\0' },
183420dfc95SChris Siden 	.zo_alt_ztest = { '\0' },
184420dfc95SChris Siden 	.zo_alt_libpath = { '\0' },
185420dfc95SChris Siden 	.zo_vdevs = 5,
186420dfc95SChris Siden 	.zo_ashift = SPA_MINBLOCKSHIFT,
187420dfc95SChris Siden 	.zo_mirrors = 2,
188420dfc95SChris Siden 	.zo_raidz = 4,
189420dfc95SChris Siden 	.zo_raidz_parity = 1,
1908363e80aSGeorge Wilson 	.zo_vdev_size = SPA_MINDEVSIZE * 4,	/* 256m default size */
191420dfc95SChris Siden 	.zo_datasets = 7,
192420dfc95SChris Siden 	.zo_threads = 23,
193420dfc95SChris Siden 	.zo_passtime = 60,		/* 60 seconds */
194420dfc95SChris Siden 	.zo_killrate = 70,		/* 70% kill rate */
195420dfc95SChris Siden 	.zo_verbose = 0,
196e0f1c0afSOlaf Faaland 	.zo_mmp_test = 0,
197420dfc95SChris Siden 	.zo_init = 1,
198420dfc95SChris Siden 	.zo_time = 300,			/* 5 minutes */
199420dfc95SChris Siden 	.zo_maxloops = 50,		/* max loops during spa_freeze() */
200663207adSDon Brady 	.zo_metaslab_force_ganging = 32 << 10,
201663207adSDon Brady 	.zo_special_vdevs = ZTEST_VDEV_CLASS_RND,
202420dfc95SChris Siden };
203420dfc95SChris Siden 
204243952c7SMatt Ahrens extern uint64_t metaslab_force_ganging;
205420dfc95SChris Siden extern uint64_t metaslab_df_alloc_threshold;
20669962b56SMatthew Ahrens extern uint64_t zfs_deadman_synctime_ms;
20730beaff4SGeorge Wilson extern int metaslab_preload_limit;
208dcbf3bd6SGeorge Wilson extern boolean_t zfs_compressed_arc_enabled;
209770499e1SDan Kimmel extern boolean_t zfs_abd_scatter_enabled;
21054811da5SToomas Soome extern int dmu_object_alloc_chunk_shift;
21117f11284SSerapheim Dimitropoulos extern boolean_t zfs_force_some_double_word_sm_entries;
212a21fe349SBrian Behlendorf extern unsigned long zfs_reconstruct_indirect_damage_fraction;
213420dfc95SChris Siden 
214420dfc95SChris Siden static ztest_shared_opts_t *ztest_shared_opts;
215420dfc95SChris Siden static ztest_shared_opts_t ztest_opts;
216eb633035STom Caputi static char *ztest_wkeydata = "abcdefghijklmnopqrstuvwxyz012345";
217420dfc95SChris Siden 
218420dfc95SChris Siden typedef struct ztest_shared_ds {
219420dfc95SChris Siden 	uint64_t	zd_seq;
220420dfc95SChris Siden } ztest_shared_ds_t;
221420dfc95SChris Siden 
222420dfc95SChris Siden static ztest_shared_ds_t *ztest_shared_ds;
223420dfc95SChris Siden #define	ZTEST_GET_SHARED_DS(d) (&ztest_shared_ds[d])
225b24ab676SJeff Bonwick #define	BT_MAGIC	0x123456789abcdefULL
226420dfc95SChris Siden #define	MAXFAULTS() \
227420dfc95SChris Siden 	(MAX(zs->zs_mirrors, 1) * (ztest_opts.zo_raidz_parity + 1) - 1)
228b24ab676SJeff Bonwick 
229b24ab676SJeff Bonwick enum ztest_io_type {
230b24ab676SJeff Bonwick 	ZTEST_IO_WRITE_TAG,
231b24ab676SJeff Bonwick 	ZTEST_IO_WRITE_PATTERN,
232b24ab676SJeff Bonwick 	ZTEST_IO_WRITE_ZEROES,
233b24ab676SJeff Bonwick 	ZTEST_IO_TRUNCATE,
234b24ab676SJeff Bonwick 	ZTEST_IO_SETATTR,
23580901aeaSGeorge Wilson 	ZTEST_IO_REWRITE,
236b24ab676SJeff Bonwick 	ZTEST_IO_TYPES
237b24ab676SJeff Bonwick };
238b24ab676SJeff Bonwick 
239e05725b1Sbonwick typedef struct ztest_block_tag {
240b24ab676SJeff Bonwick 	uint64_t	bt_magic;
241e05725b1Sbonwick 	uint64_t	bt_objset;
242e05725b1Sbonwick 	uint64_t	bt_object;
24354811da5SToomas Soome 	uint64_t	bt_dnodesize;
244e05725b1Sbonwick 	uint64_t	bt_offset;
245b24ab676SJeff Bonwick 	uint64_t	bt_gen;
246e05725b1Sbonwick 	uint64_t	bt_txg;
247b24ab676SJeff Bonwick 	uint64_t	bt_crtxg;
248e05725b1Sbonwick } ztest_block_tag_t;
250b24ab676SJeff Bonwick typedef struct bufwad {
251b24ab676SJeff Bonwick 	uint64_t	bw_index;
252b24ab676SJeff Bonwick 	uint64_t	bw_txg;
253b24ab676SJeff Bonwick 	uint64_t	bw_data;
254b24ab676SJeff Bonwick } bufwad_t;
255b24ab676SJeff Bonwick 
256b24ab676SJeff Bonwick /*
25779315247SMatthew Ahrens  * It would be better to use a rangelock_t per object.  Unfortunately
25879315247SMatthew Ahrens  * the rangelock_t is not a drop-in replacement for rl_t, because we
25979315247SMatthew Ahrens  * still need to map from object ID to rangelock_t.
260b24ab676SJeff Bonwick  */
261b24ab676SJeff Bonwick typedef enum {
262b24ab676SJeff Bonwick 	RL_READER,
263b24ab676SJeff Bonwick 	RL_WRITER,
264b24ab676SJeff Bonwick 	RL_APPEND
265b24ab676SJeff Bonwick } rl_type_t;
266b24ab676SJeff Bonwick 
267b24ab676SJeff Bonwick typedef struct rll {
268b24ab676SJeff Bonwick 	void		*rll_writer;
269b24ab676SJeff Bonwick 	int		rll_readers;
270f06dce2cSAndrew Stormont 	kmutex_t	rll_lock;
271f06dce2cSAndrew Stormont 	kcondvar_t	rll_cv;
272b24ab676SJeff Bonwick } rll_t;
273b24ab676SJeff Bonwick 
274b24ab676SJeff Bonwick typedef struct rl {
275b24ab676SJeff Bonwick 	uint64_t	rl_object;
276b24ab676SJeff Bonwick 	uint64_t	rl_offset;
277b24ab676SJeff Bonwick 	uint64_t	rl_size;
278b24ab676SJeff Bonwick 	rll_t		*rl_lock;
279b24ab676SJeff Bonwick } rl_t;
280b24ab676SJeff Bonwick 
281b24ab676SJeff Bonwick #define	ZTEST_RANGE_LOCKS	64
282b24ab676SJeff Bonwick #define	ZTEST_OBJECT_LOCKS	64
283b24ab676SJeff Bonwick 
284b24ab676SJeff Bonwick /*
285b24ab676SJeff Bonwick  * Object descriptor.  Used as a template for object lookup/create/remove.
286b24ab676SJeff Bonwick  */
287b24ab676SJeff Bonwick typedef struct ztest_od {
288b24ab676SJeff Bonwick 	uint64_t	od_dir;
289b24ab676SJeff Bonwick 	uint64_t	od_object;
290b24ab676SJeff Bonwick 	dmu_object_type_t od_type;
291b24ab676SJeff Bonwick 	dmu_object_type_t od_crtype;
292b24ab676SJeff Bonwick 	uint64_t	od_blocksize;
293b24ab676SJeff Bonwick 	uint64_t	od_crblocksize;
29454811da5SToomas Soome 	uint64_t	od_crdnodesize;
295b24ab676SJeff Bonwick 	uint64_t	od_gen;
296b24ab676SJeff Bonwick 	uint64_t	od_crgen;
2979adfa60dSMatthew Ahrens 	char		od_name[ZFS_MAX_DATASET_NAME_LEN];
298b24ab676SJeff Bonwick } ztest_od_t;
300b24ab676SJeff Bonwick /*
301b24ab676SJeff Bonwick  * Per-dataset state.
302b24ab676SJeff Bonwick  */
303b24ab676SJeff Bonwick typedef struct ztest_ds {
304420dfc95SChris Siden 	ztest_shared_ds_t *zd_shared;
305b24ab676SJeff Bonwick 	objset_t	*zd_os;
306f06dce2cSAndrew Stormont 	krwlock_t	zd_zilog_lock;
307b24ab676SJeff Bonwick 	zilog_t		*zd_zilog;
308b24ab676SJeff Bonwick 	ztest_od_t	*zd_od;		/* debugging aid */
3099adfa60dSMatthew Ahrens 	char		zd_name[ZFS_MAX_DATASET_NAME_LEN];
310f06dce2cSAndrew Stormont 	kmutex_t	zd_dirobj_lock;
311b24ab676SJeff Bonwick 	rll_t		zd_object_lock[ZTEST_OBJECT_LOCKS];
312b24ab676SJeff Bonwick 	rll_t		zd_range_lock[ZTEST_RANGE_LOCKS];
313b24ab676SJeff Bonwick } ztest_ds_t;
314b24ab676SJeff Bonwick 
315b24ab676SJeff Bonwick /*
316b24ab676SJeff Bonwick  * Per-iteration state.
317b24ab676SJeff Bonwick  */
318b24ab676SJeff Bonwick typedef void ztest_func_t(ztest_ds_t *zd, uint64_t id);
319b24ab676SJeff Bonwick 
320b24ab676SJeff Bonwick typedef struct ztest_info {
321b24ab676SJeff Bonwick 	ztest_func_t	*zi_func;	/* test function */
322b24ab676SJeff Bonwick 	uint64_t	zi_iters;	/* iterations per execution */
323b24ab676SJeff Bonwick 	uint64_t	*zi_interval;	/* execute every <interval> seconds */
324b24ab676SJeff Bonwick } ztest_info_t;
326420dfc95SChris Siden typedef struct ztest_shared_callstate {
327420dfc95SChris Siden 	uint64_t	zc_count;	/* per-pass count */
328420dfc95SChris Siden 	uint64_t	zc_time;	/* per-pass time */
329420dfc95SChris Siden 	uint64_t	zc_next;	/* next time to call this function */
330420dfc95SChris Siden } ztest_shared_callstate_t;
331420dfc95SChris Siden 
332420dfc95SChris Siden static ztest_shared_callstate_t *ztest_shared_callstate;
333420dfc95SChris Siden #define	ZTEST_GET_SHARED_CALLSTATE(c) (&ztest_shared_callstate[c])
334420dfc95SChris Siden 
335fa9e4066Sahrens /*
336fa9e4066Sahrens  * Note: these aren't static because we want dladdr() to work.
337fa9e4066Sahrens  */
338fa9e4066Sahrens ztest_func_t ztest_dmu_read_write;
339fa9e4066Sahrens ztest_func_t ztest_dmu_write_parallel;
340fa9e4066Sahrens ztest_func_t ztest_dmu_object_alloc_free;
34154811da5SToomas Soome ztest_func_t ztest_dmu_object_next_chunk;
342d20e665cSRicardo M. Correia ztest_func_t ztest_dmu_commit_callbacks;
343fa9e4066Sahrens ztest_func_t ztest_zap;
344fa9e4066Sahrens ztest_func_t ztest_zap_parallel;
345b24ab676SJeff Bonwick ztest_func_t ztest_zil_commit;
346c9ba2a43SEric Schrock ztest_func_t ztest_zil_remount;
347b24ab676SJeff Bonwick ztest_func_t ztest_dmu_read_write_zcopy;
348fa9e4066Sahrens ztest_func_t ztest_dmu_objset_create_destroy;
349b24ab676SJeff Bonwick ztest_func_t ztest_dmu_prealloc;
350b24ab676SJeff Bonwick ztest_func_t ztest_fzap;
351fa9e4066Sahrens ztest_func_t ztest_dmu_snapshot_create_destroy;
352b24ab676SJeff Bonwick ztest_func_t ztest_dsl_prop_get_set;
353b24ab676SJeff Bonwick ztest_func_t ztest_spa_prop_get_set;
354fa9e4066Sahrens ztest_func_t ztest_spa_create_destroy;
355fa9e4066Sahrens ztest_func_t ztest_fault_inject;
356b24ab676SJeff Bonwick ztest_func_t ztest_ddt_repair;
357b24ab676SJeff Bonwick ztest_func_t ztest_dmu_snapshot_hold;
358e0f1c0afSOlaf Faaland ztest_func_t ztest_mmp_enable_disable;
359b24ab676SJeff Bonwick ztest_func_t ztest_scrub;
360b24ab676SJeff Bonwick ztest_func_t ztest_dsl_dataset_promote_busy;
361fa9e4066Sahrens ztest_func_t ztest_vdev_attach_detach;
362fa9e4066Sahrens ztest_func_t ztest_vdev_LUN_growth;
363fa9e4066Sahrens ztest_func_t ztest_vdev_add_remove;
364663207adSDon Brady ztest_func_t ztest_vdev_class_add;
365e14bb325SJeff Bonwick ztest_func_t ztest_vdev_aux_add_remove;
3661195e687SMark J Musante ztest_func_t ztest_split_pool;
367e9103aaeSGarrett D'Amore ztest_func_t ztest_reguid;
36825345e46SGeorge Wilson ztest_func_t ztest_spa_upgrade;
3695cabbc6bSPrashanth Sreenivasa ztest_func_t ztest_device_removal;
3705cabbc6bSPrashanth Sreenivasa ztest_func_t ztest_remap_blocks;
37186714001SSerapheim Dimitropoulos ztest_func_t ztest_spa_checkpoint_create_discard;
372094e47e9SGeorge Wilson ztest_func_t ztest_initialize;
373084fd14fSBrian Behlendorf ztest_func_t ztest_trim;
37454811da5SToomas Soome ztest_func_t ztest_verify_dnode_bt;
376b24ab676SJeff Bonwick uint64_t zopt_always = 0ULL * NANOSEC;		/* all the time */
377b24ab676SJeff Bonwick uint64_t zopt_incessant = 1ULL * NANOSEC / 10;	/* every 1/10 second */
378b24ab676SJeff Bonwick uint64_t zopt_often = 1ULL * NANOSEC;		/* every second */
379b24ab676SJeff Bonwick uint64_t zopt_sometimes = 10ULL * NANOSEC;	/* every 10 seconds */
380b24ab676SJeff Bonwick uint64_t zopt_rarely = 60ULL * NANOSEC;		/* every 60 seconds */
382fa9e4066Sahrens ztest_info_t ztest_info[] = {
383e05725b1Sbonwick 	{ ztest_dmu_read_write,			1,	&zopt_always	},
384b24ab676SJeff Bonwick 	{ ztest_dmu_write_parallel,		10,	&zopt_always	},
385e05725b1Sbonwick 	{ ztest_dmu_object_alloc_free,		1,	&zopt_always	},
38654811da5SToomas Soome 	{ ztest_dmu_object_next_chunk,		1,	&zopt_sometimes	},
387b24ab676SJeff Bonwick 	{ ztest_dmu_commit_callbacks,		1,	&zopt_always	},
388e05725b1Sbonwick 	{ ztest_zap,				30,	&zopt_always	},
389e05725b1Sbonwick 	{ ztest_zap_parallel,			100,	&zopt_always	},
3901195e687SMark J Musante 	{ ztest_split_pool,			1,	&zopt_always	},
391b24ab676SJeff Bonwick 	{ ztest_zil_commit,			1,	&zopt_incessant	},
392c9ba2a43SEric Schrock 	{ ztest_zil_remount,			1,	&zopt_sometimes	},
393b24ab676SJeff Bonwick 	{ ztest_dmu_read_write_zcopy,		1,	&zopt_often	},
394b24ab676SJeff Bonwick 	{ ztest_dmu_objset_create_destroy,	1,	&zopt_often	},
395b24ab676SJeff Bonwick 	{ ztest_dsl_prop_get_set,		1,	&zopt_often	},
396b24ab676SJeff Bonwick 	{ ztest_spa_prop_get_set,		1,	&zopt_sometimes	},
397b24ab676SJeff Bonwick #if 0
398b24ab676SJeff Bonwick 	{ ztest_dmu_prealloc,			1,	&zopt_sometimes	},
399b24ab676SJeff Bonwick #endif
400b24ab676SJeff Bonwick 	{ ztest_fzap,				1,	&zopt_sometimes	},
401b24ab676SJeff Bonwick 	{ ztest_dmu_snapshot_create_destroy,	1,	&zopt_sometimes	},
402b24ab676SJeff Bonwick 	{ ztest_spa_create_destroy,		1,	&zopt_sometimes	},
403a3874b8bSToomas Soome 	{ ztest_fault_inject,			1,	&zopt_incessant	},
404b24ab676SJeff Bonwick 	{ ztest_ddt_repair,			1,	&zopt_sometimes	},
4055c987a37SChris Kirby 	{ ztest_dmu_snapshot_hold,		1,	&zopt_sometimes	},
406e0f1c0afSOlaf Faaland 	{ ztest_mmp_enable_disable,		1,	&zopt_sometimes	},
4072c1e2b44SGeorge Wilson 	{ ztest_reguid,				1,	&zopt_rarely	},
408a3874b8bSToomas Soome 	{ ztest_scrub,				1,	&zopt_often	},
40925345e46SGeorge Wilson 	{ ztest_spa_upgrade,			1,	&zopt_rarely	},
410b24ab676SJeff Bonwick 	{ ztest_dsl_dataset_promote_busy,	1,	&zopt_rarely	},
411a3874b8bSToomas Soome 	{ ztest_vdev_attach_detach,		1,	&zopt_incessant	},
412e14bb325SJeff Bonwick 	{ ztest_vdev_LUN_growth,		1,	&zopt_rarely	},
413420dfc95SChris Siden 	{ ztest_vdev_add_remove,		1,
414420dfc95SChris Siden 	    &ztest_opts.zo_vdevtime				},
415663207adSDon Brady 	{ ztest_vdev_class_add,			1,
416663207adSDon Brady 	    &ztest_opts.zo_vdevtime				},
417420dfc95SChris Siden 	{ ztest_vdev_aux_add_remove,		1,
418420dfc95SChris Siden 	    &ztest_opts.zo_vdevtime				},
4195cabbc6bSPrashanth Sreenivasa 	{ ztest_device_removal,			1,	&zopt_sometimes	},
42086714001SSerapheim Dimitropoulos 	{ ztest_remap_blocks,			1,	&zopt_sometimes },
421094e47e9SGeorge Wilson 	{ ztest_spa_checkpoint_create_discard,	1,	&zopt_rarely	},
42254811da5SToomas Soome 	{ ztest_initialize,			1,	&zopt_sometimes },
423084fd14fSBrian Behlendorf 	{ ztest_trim,				1,	&zopt_sometimes },
42454811da5SToomas Soome 	{ ztest_verify_dnode_bt,		1,	&zopt_sometimes }
425fa9e4066Sahrens };
427fa9e4066Sahrens #define	ZTEST_FUNCS	(sizeof (ztest_info) / sizeof (ztest_info_t))
429d20e665cSRicardo M. Correia /*
430d20e665cSRicardo M. Correia  * The following struct is used to hold a list of uncalled commit callbacks.
431d20e665cSRicardo M. Correia  * The callbacks are ordered by txg number.
432d20e665cSRicardo M. Correia  */
433d20e665cSRicardo M. Correia typedef struct ztest_cb_list {
434f06dce2cSAndrew Stormont 	kmutex_t zcl_callbacks_lock;
435d20e665cSRicardo M. Correia 	list_t	zcl_callbacks;
436d20e665cSRicardo M. Correia } ztest_cb_list_t;
437d20e665cSRicardo M. Correia 
438fa9e4066Sahrens /*
439fa9e4066Sahrens  * Stuff we need to share writably between parent and child.
440fa9e4066Sahrens  */
441fa9e4066Sahrens typedef struct ztest_shared {
442420dfc95SChris Siden 	boolean_t	zs_do_init;
443b24ab676SJeff Bonwick 	hrtime_t	zs_proc_start;
444b24ab676SJeff Bonwick 	hrtime_t	zs_proc_stop;
445b24ab676SJeff Bonwick 	hrtime_t	zs_thread_start;
446b24ab676SJeff Bonwick 	hrtime_t	zs_thread_stop;
447b24ab676SJeff Bonwick 	hrtime_t	zs_thread_kill;
448b24ab676SJeff Bonwick 	uint64_t	zs_enospc_count;
44988ecc943SGeorge Wilson 	uint64_t	zs_vdev_next_leaf;
450e14bb325SJeff Bonwick 	uint64_t	zs_vdev_aux;
451fa9e4066Sahrens 	uint64_t	zs_alloc;
452fa9e4066Sahrens 	uint64_t	zs_space;
4531195e687SMark J Musante 	uint64_t	zs_splits;
4541195e687SMark J Musante 	uint64_t	zs_mirrors;
455420dfc95SChris Siden 	uint64_t	zs_metaslab_sz;
456420dfc95SChris Siden 	uint64_t	zs_metaslab_df_alloc_threshold;
457420dfc95SChris Siden 	uint64_t	zs_guid;
458fa9e4066Sahrens } ztest_shared_t;
460b24ab676SJeff Bonwick #define	ID_PARALLEL	-1ULL
461b24ab676SJeff Bonwick 
462fa9e4066Sahrens static char ztest_dev_template[] = "%s/%s.%llua";
463e14bb325SJeff Bonwick static char ztest_aux_template[] = "%s/%s.%s.%llu";
464b24ab676SJeff Bonwick ztest_shared_t *ztest_shared;
466420dfc95SChris Siden static spa_t *ztest_spa = NULL;
467420dfc95SChris Siden static ztest_ds_t *ztest_ds;
468420dfc95SChris Siden 
469f06dce2cSAndrew Stormont static kmutex_t ztest_vdev_lock;
4703a4b1be9SMatthew Ahrens static boolean_t ztest_device_removal_active = B_FALSE;
47154811da5SToomas Soome static kmutex_t ztest_checkpoint_lock;
472dfbb9432SGeorge Wilson 
473dfbb9432SGeorge Wilson /*
474dfbb9432SGeorge Wilson  * The ztest_name_lock protects the pool and dataset namespace used by
475dfbb9432SGeorge Wilson  * the individual tests. To modify the namespace, consumers must grab
476dfbb9432SGeorge Wilson  * this lock as writer. Grabbing the lock as reader will ensure that the
477dfbb9432SGeorge Wilson  * namespace does not change while the lock is held.
478dfbb9432SGeorge Wilson  */
479f06dce2cSAndrew Stormont static krwlock_t ztest_name_lock;
481420dfc95SChris Siden static boolean_t ztest_dump_core = B_TRUE;
482e14bb325SJeff Bonwick static boolean_t ztest_exiting;
484d20e665cSRicardo M. Correia /* Global commit callback list */
485d20e665cSRicardo M. Correia static ztest_cb_list_t zcl;
486d20e665cSRicardo M. Correia 
487b24ab676SJeff Bonwick enum ztest_object {
488b24ab676SJeff Bonwick 	ZTEST_META_DNODE = 0,
489b24ab676SJeff Bonwick 	ZTEST_DIROBJ,
490b24ab676SJeff Bonwick 	ZTEST_OBJECTS
491b24ab676SJeff Bonwick };
4931ce825d8Sraf static void usage(boolean_t) __NORETURN;
495fa9e4066Sahrens /*
496fa9e4066Sahrens  * These libumem hooks provide a reasonable set of defaults for the allocator's
497fa9e4066Sahrens  * debugging facilities.
498fa9e4066Sahrens  */
499fa9e4066Sahrens const char *
_umem_debug_init()500fa9e4066Sahrens _umem_debug_init()
501fa9e4066Sahrens {
502fa9e4066Sahrens 	return ("default,verbose"); /* $UMEM_DEBUG setting */
503fa9e4066Sahrens }
505fa9e4066Sahrens const char *
_umem_logging_init(void)506fa9e4066Sahrens _umem_logging_init(void)
507fa9e4066Sahrens {
508fa9e4066Sahrens 	return ("fail,contents"); /* $UMEM_LOGGING setting */
509fa9e4066Sahrens }
511fa9e4066Sahrens #define	FATAL_MSG_SZ	1024
513fa9e4066Sahrens char *fatal_msg;
515fa9e4066Sahrens static void
fatal(int do_perror,char * message,...)516fa9e4066Sahrens fatal(int do_perror, char *message, ...)
517fa9e4066Sahrens {
518fa9e4066Sahrens 	va_list args;
519fa9e4066Sahrens 	int save_errno = errno;
520fa9e4066Sahrens 	char buf[FATAL_MSG_SZ];
522fa9e4066Sahrens 	(void) fflush(stdout);
524fa9e4066Sahrens 	va_start(args, message);
525fa9e4066Sahrens 	(void) sprintf(buf, "ztest: ");
526fa9e4066Sahrens 	/* LINTED */
527fa9e4066Sahrens 	(void) vsprintf(buf + strlen(buf), message, args);
528fa9e4066Sahrens 	va_end(args);
529fa9e4066Sahrens 	if (do_perror) {
530fa9e4066Sahrens 		(void) snprintf(buf + strlen(buf), FATAL_MSG_SZ - strlen(buf),
531fa9e4066Sahrens 		    ": %s", strerror(save_errno));
532fa9e4066Sahrens 	}
533fa9e4066Sahrens 	(void) fprintf(stderr, "%s\n", buf);
534fa9e4066Sahrens 	fatal_msg = buf;			/* to ease debugging */
535fa9e4066Sahrens 	if (ztest_dump_core)
536fa9e4066Sahrens 		abort();
537fa9e4066Sahrens 	exit(3);
538fa9e4066Sahrens }
540fa9e4066Sahrens static int
str2shift(const char * buf)541fa9e4066Sahrens str2shift(const char *buf)
542fa9e4066Sahrens {
543fa9e4066Sahrens 	const char *ends = "BKMGTPEZ";
544fa9e4066Sahrens 	int i;
546fa9e4066Sahrens 	if (buf[0] == '\0')
547fa9e4066Sahrens 		return (0);
548fa9e4066Sahrens 	for (i = 0; i < strlen(ends); i++) {
549fa9e4066Sahrens 		if (toupper(buf[0]) == ends[i])
550fa9e4066Sahrens 			break;
551fa9e4066Sahrens 	}
552f1b4288bSvb 	if (i == strlen(ends)) {
553f1b4288bSvb 		(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n",
554f1b4288bSvb 		    buf);
555f1b4288bSvb 		usage(B_FALSE);
556f1b4288bSvb 	}
557fa9e4066Sahrens 	if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
558fa9e4066Sahrens 		return (10*i);
559fa9e4066Sahrens 	}
560f1b4288bSvb 	(void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n", buf);
561f1b4288bSvb 	usage(B_FALSE);
562f1b4288bSvb 	/* NOTREACHED */
563fa9e4066Sahrens }
565fa9e4066Sahrens static uint64_t
nicenumtoull(const char * buf)566fa9e4066Sahrens nicenumtoull(const char *buf)
567fa9e4066Sahrens {
568fa9e4066Sahrens 	char *end;
569fa9e4066Sahrens 	uint64_t val;
571fa9e4066Sahrens 	val = strtoull(buf, &end, 0);
572fa9e4066Sahrens 	if (end == buf) {
573f1b4288bSvb 		(void) fprintf(stderr, "ztest: bad numeric value: %s\n", buf);
574f1b4288bSvb 		usage(B_FALSE);
575fa9e4066Sahrens 	} else if (end[0] == '.') {
576fa9e4066Sahrens 		double fval = strtod(buf, &end);
577fa9e4066Sahrens 		fval *= pow(2, str2shift(end));
578f1b4288bSvb 		if (fval > UINT64_MAX) {
579f1b4288bSvb 			(void) fprintf(stderr, "ztest: value too large: %s\n",
580f1b4288bSvb 			    buf);
581f1b4288bSvb 			usage(B_FALSE);
582f1b4288bSvb 		}
583fa9e4066Sahrens 		val = (uint64_t)fval;
584fa9e4066Sahrens 	} else {
585fa9e4066Sahrens 		int shift = str2shift(end);
586f1b4288bSvb 		if (shift >= 64 || (val << shift) >> shift != val) {
587f1b4288bSvb 			(void) fprintf(stderr, "ztest: value too large: %s\n",
588f1b4288bSvb 			    buf);
589f1b4288bSvb 			usage(B_FALSE);
590f1b4288bSvb 		}
591fa9e4066Sahrens 		val <<= shift;
592fa9e4066Sahrens 	}
593fa9e4066Sahrens 	return (val);
594fa9e4066Sahrens }
596fa9e4066Sahrens static void
usage(boolean_t requested)597f1b4288bSvb usage(boolean_t requested)
598fa9e4066Sahrens {
599420dfc95SChris Siden 	const ztest_shared_opts_t *zo = &ztest_opts_defaults;
600420dfc95SChris Siden 
6010a055120SJason King 	char nice_vdev_size[NN_NUMBUF_SZ];
602243952c7SMatt Ahrens 	char nice_force_ganging[NN_NUMBUF_SZ];
603f1b4288bSvb 	FILE *fp = requested ? stdout : stderr;
6050a055120SJason King 	nicenum(zo->zo_vdev_size, nice_vdev_size, sizeof (nice_vdev_size));
606243952c7SMatt Ahrens 	nicenum(zo->zo_metaslab_force_ganging, nice_force_ganging,
607243952c7SMatt Ahrens 	    sizeof (nice_force_ganging));
609f1b4288bSvb 	(void) fprintf(fp, "Usage: %s\n"
610fa9e4066Sahrens 	    "\t[-v vdevs (default: %llu)]\n"
611fa9e4066Sahrens 	    "\t[-s size_of_each_vdev (default: %s)]\n"
6122215e990SMark J Musante 	    "\t[-a alignment_shift (default: %d)] use 0 for random\n"
613fa9e4066Sahrens 	    "\t[-m mirror_copies (default: %d)]\n"
614fa9e4066Sahrens 	    "\t[-r raidz_disks (default: %d)]\n"
61599653d4eSeschrock 	    "\t[-R raidz_parity (default: %d)]\n"
616fa9e4066Sahrens 	    "\t[-d datasets (default: %d)]\n"
617fa9e4066Sahrens 	    "\t[-t threads (default: %d)]\n"
618fa9e4066Sahrens 	    "\t[-g gang_block_threshold (default: %s)]\n"
6192215e990SMark J Musante 	    "\t[-i init_count (default: %d)] initialize pool i times\n"
6202215e990SMark J Musante 	    "\t[-k kill_percentage (default: %llu%%)]\n"
621fa9e4066Sahrens 	    "\t[-p pool_name (default: %s)]\n"
6222215e990SMark J Musante 	    "\t[-f dir (default: %s)] file directory for vdev files\n"
623e0f1c0afSOlaf Faaland 	    "\t[-M] Multi-host simulate pool imported on remote host\n"
6242215e990SMark J Musante 	    "\t[-V] verbose (use multiple times for ever more blather)\n"
6252215e990SMark J Musante 	    "\t[-E] use existing pool instead of creating new one\n"
6262215e990SMark J Musante 	    "\t[-T time (default: %llu sec)] total run time\n"
6272215e990SMark J Musante 	    "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
6282215e990SMark J Musante 	    "\t[-P passtime (default: %llu sec)] time per pass\n"
629420dfc95SChris Siden 	    "\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
630663207adSDon Brady 	    "\t[-C vdev class state (default: random)] special=on|off|random\n"
6310e60744cSPavel Zakharov 	    "\t[-o variable=value] ... set global variable to an unsigned\n"
6320e60744cSPavel Zakharov 	    "\t    32-bit integer value\n"
633f1b4288bSvb 	    "\t[-h] (print help)\n"
634fa9e4066Sahrens 	    "",
635420dfc95SChris Siden 	    zo->zo_pool,
636420dfc95SChris Siden 	    (u_longlong_t)zo->zo_vdevs,			/* -v */
6370a4e9518Sgw 	    nice_vdev_size,				/* -s */
638420dfc95SChris Siden 	    zo->zo_ashift,				/* -a */
639420dfc95SChris Siden 	    zo->zo_mirrors,				/* -m */
640420dfc95SChris Siden 	    zo->zo_raidz,				/* -r */
641420dfc95SChris Siden 	    zo->zo_raidz_parity,			/* -R */
642420dfc95SChris Siden 	    zo->zo_datasets,				/* -d */
643420dfc95SChris Siden 	    zo->zo_threads,				/* -t */
644243952c7SMatt Ahrens 	    nice_force_ganging,				/* -g */
645420dfc95SChris Siden 	    zo->zo_init,				/* -i */
646420dfc95SChris Siden 	    (u_longlong_t)zo->zo_killrate,		/* -k */
647420dfc95SChris Siden 	    zo->zo_pool,				/* -p */
648420dfc95SChris Siden 	    zo->zo_dir,					/* -f */
649420dfc95SChris Siden 	    (u_longlong_t)zo->zo_time,			/* -T */
650420dfc95SChris Siden 	    (u_longlong_t)zo->zo_maxloops,		/* -F */
651420dfc95SChris Siden 	    (u_longlong_t)zo->zo_passtime);
652f1b4288bSvb 	exit(requested ? 0 : 1);
653fa9e4066Sahrens }
655663207adSDon Brady 
656663207adSDon Brady static void
ztest_parse_name_value(const char * input,ztest_shared_opts_t * zo)657663207adSDon Brady ztest_parse_name_value(const char *input, ztest_shared_opts_t *zo)
658663207adSDon Brady {
659663207adSDon Brady 	char name[32];
660663207adSDon Brady 	char *value;
661663207adSDon Brady 	int state = ZTEST_VDEV_CLASS_RND;
662663207adSDon Brady 
663663207adSDon Brady 	(void) strlcpy(name, input, sizeof (name));
664663207adSDon Brady 
665663207adSDon Brady 	value = strchr(name, '=');
666663207adSDon Brady 	if (value == NULL) {
667663207adSDon Brady 		(void) fprintf(stderr, "missing value in property=value "
668663207adSDon Brady 		    "'-C' argument (%s)\n", input);
669663207adSDon Brady 		usage(B_FALSE);
670663207adSDon Brady 	}
671663207adSDon Brady 	*(value) = '\0';
672663207adSDon Brady 	value++;
673663207adSDon Brady 
674663207adSDon Brady 	if (strcmp(value, "on") == 0) {
675663207adSDon Brady 		state = ZTEST_VDEV_CLASS_ON;
676663207adSDon Brady 	} else if (strcmp(value, "off") == 0) {
677663207adSDon Brady 		state = ZTEST_VDEV_CLASS_OFF;
678663207adSDon Brady 	} else if (strcmp(value, "random") == 0) {
679663207adSDon Brady 		state = ZTEST_VDEV_CLASS_RND;
680663207adSDon Brady 	} else {
681663207adSDon Brady 		(void) fprintf(stderr, "invalid property value '%s'\n", value);
682663207adSDon Brady 		usage(B_FALSE);
683663207adSDon Brady 	}
684663207adSDon Brady 
685663207adSDon Brady 	if (strcmp(name, "special") == 0) {
686663207adSDon Brady 		zo->zo_special_vdevs = state;
687663207adSDon Brady 	} else {
688663207adSDon Brady 		(void) fprintf(stderr, "invalid property name '%s'\n", name);
689663207adSDon Brady 		usage(B_FALSE);
690663207adSDon Brady 	}
691663207adSDon Brady 	if (zo->zo_verbose >= 3)
692663207adSDon Brady 		(void) printf("%s vdev state is '%s'\n", name, value);
693663207adSDon Brady }
694663207adSDon Brady 
695fa9e4066Sahrens static void
process_options(int argc,char ** argv)696fa9e4066Sahrens process_options(int argc, char **argv)
697fa9e4066Sahrens {
698420dfc95SChris Siden 	char *path;
699420dfc95SChris Siden 	ztest_shared_opts_t *zo = &ztest_opts;
700420dfc95SChris Siden 
701fa9e4066Sahrens 	int opt;
702fa9e4066Sahrens 	uint64_t value;
703420dfc95SChris Siden 	char altdir[MAXNAMELEN] = { 0 };