ztest.c revision aab80726335c76a7cae32c7300890248d73a51e3
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * Common Development and Distribution License (the "License").
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
47cb52daa729f19e298c85a84e8df069365c5232Jeff Bonwick * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
aab80726335c76a7cae32c7300890248d73a51e3George Wilson * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
a7a845e4bf22fd1b2a284729ccd95c7370a0438cSteven Hartland * Copyright (c) 2013 Steven Hartland. All rights reserved.
c3d26abc9ee97b4f60233556aadeb57e0bd30bb9Matthew Ahrens * Copyright (c) 2014 Integros [integros.com]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The objective of this program is to provide a DMU/ZAP/SPA stress test
fa9e4066f08beec538e775443c5be79dd423fcabahrens * that runs entirely in userland, is easy to use, and easy to extend.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The overall design of the ztest program is as follows:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (1) For each major functional area (e.g. adding vdevs to a pool,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * creating and destroying datasets, reading and writing objects, etc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we have a simple routine to test that functionality. These
fa9e4066f08beec538e775443c5be79dd423fcabahrens * individual routines do not have to do anything "stressful".
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (2) We turn these simple functionality tests into a stress test by
fa9e4066f08beec538e775443c5be79dd423fcabahrens * running them all in parallel, with as many threads as desired,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and spread across as many datasets, objects, and vdevs as desired.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (3) While all this is happening, we inject faults into the pool to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * verify that self-healing data really works.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (4) Every time we open a dataset, we change its checksum and compression
fa9e4066f08beec538e775443c5be79dd423fcabahrens * functions. Thus even individual objects vary from block to block
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in which checksum they use and whether they're compressed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (5) To verify that we never lose on-disk consistency after a crash,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we run the entire test in a child of the main process.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * At random times, the child self-immolates with a SIGKILL.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This is the software equivalent of pulling the power cord.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The parent then runs the test again, using the existing
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens * storage pool, as many times as desired. If backwards compatibility
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * testing is enabled ztest will sometimes run the "older" version
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * of ztest after a SIGKILL.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (6) To verify that we don't have future leaks or temporal incursions,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * many of the functional tests record the transaction group number
fa9e4066f08beec538e775443c5be79dd423fcabahrens * as part of their data. When reading old data, they verify that
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the transaction group number is less than the current, open txg.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If you add a new test, please do this if applicable.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When run with no arguments, ztest runs for about five minutes and
fa9e4066f08beec538e775443c5be79dd423fcabahrens * produces no output if successful. To get a little bit of information,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * specify -V. To get more information, specify -VV, and so on.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * To turn this into an overnight stress test, use -T to specify run time.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can ask more more vdevs [-v], datasets [-d], or threads [-t]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to increase the pool capacity, fanout, and overall stress level.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * Use the -k option to set the desired frequency of kills.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * When ztest invokes itself it passes all relevant information through a
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * temporary file which is mmap-ed in the child process. This allows shared
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * memory to survive the exec syscall. The ztest_shared_hdr_t struct is always
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * stored at offset 0 of this file and contains information on the size and
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * number of shared structures in the file. The information stored in this file
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * must remain backwards compatible with older versions of ztest so that
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * ztest can invoke them during backwards compatibility testing (-B).
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidentypedef struct ztest_shared_hdr {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidentypedef struct ztest_shared_opts {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenstatic const ztest_shared_opts_t ztest_opts_defaults = {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden .zo_maxloops = 50, /* max loops during spa_freeze() */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidentypedef struct ztest_shared_ds {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden#define ZTEST_GET_SHARED_DS(d) (&ztest_shared_ds[d])
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (MAX(zs->zs_mirrors, 1) * (ztest_opts.zo_raidz_parity + 1) - 1)
e05725b117836db173257fae43fb0746eb857fb5bonwicktypedef struct ztest_block_tag {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct bufwad {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * XXX -- fix zfs range locks to be generic so we can use them here.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef enum {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct rll {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct rl {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Object descriptor. Used as a template for object lookup/create/remove.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct ztest_od {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Per-dataset state.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct ztest_ds {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Per-iteration state.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef void ztest_func_t(ztest_ds_t *zd, uint64_t id);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwicktypedef struct ztest_info {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t zi_iters; /* iterations per execution */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t *zi_interval; /* execute every <interval> seconds */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden uint64_t zc_next; /* next time to call this function */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenstatic ztest_shared_callstate_t *ztest_shared_callstate;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden#define ZTEST_GET_SHARED_CALLSTATE(c) (&ztest_shared_callstate[c])
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Note: these aren't static because we want dladdr() to work.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickuint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickuint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickuint64_t zopt_often = 1ULL * NANOSEC; /* every second */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickuint64_t zopt_sometimes = 10ULL * NANOSEC; /* every 10 seconds */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickuint64_t zopt_rarely = 60ULL * NANOSEC; /* every 60 seconds */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dmu_write_parallel, 10, &zopt_always },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dmu_commit_callbacks, 1, &zopt_always },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dmu_read_write_zcopy, 1, &zopt_often },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dmu_objset_create_destroy, 1, &zopt_often },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_spa_prop_get_set, 1, &zopt_sometimes },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_spa_create_destroy, 1, &zopt_sometimes },
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby { ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick { ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens { ztest_vdev_attach_detach, 1, &zopt_sometimes },
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t))
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * The following struct is used to hold a list of uncalled commit callbacks.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * The callbacks are ordered by txg number.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Stuff we need to share writably between parent and child.
fa9e4066f08beec538e775443c5be79dd423fcabahrenstypedef struct ztest_shared {
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwickstatic char ztest_aux_template[] = "%s/%s.%s.%llu";
dfbb943217bf8ab22a1a9d2e9dca01d4da95ee0bGeorge Wilson * The ztest_name_lock protects the pool and dataset namespace used by
dfbb943217bf8ab22a1a9d2e9dca01d4da95ee0bGeorge Wilson * the individual tests. To modify the namespace, consumers must grab
dfbb943217bf8ab22a1a9d2e9dca01d4da95ee0bGeorge Wilson * this lock as writer. Grabbing the lock as reader will ensure that the
dfbb943217bf8ab22a1a9d2e9dca01d4da95ee0bGeorge Wilson * namespace does not change while the lock is held.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia/* Global commit callback list */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * These libumem hooks provide a reasonable set of defaults for the allocator's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * debugging facilities.
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ("default,verbose"); /* $UMEM_DEBUG setting */
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst char *
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ("fail,contents"); /* $UMEM_LOGGING setting */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* LINTED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) snprintf(buf + strlen(buf), FATAL_MSG_SZ - strlen(buf),
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
f1b4288b3b466065edd5eb9868399db6a4ff283evb (void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0')) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (10*i);
f1b4288b3b466065edd5eb9868399db6a4ff283evb (void) fprintf(stderr, "ztest: invalid bytes suffix: %s\n", buf);
f1b4288b3b466065edd5eb9868399db6a4ff283evb /* NOTREACHED */
f1b4288b3b466065edd5eb9868399db6a4ff283evb (void) fprintf(stderr, "ztest: bad numeric value: %s\n", buf);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden const ztest_shared_opts_t *zo = &ztest_opts_defaults;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden nicenum(zo->zo_metaslab_gang_bang, nice_gang_bang);
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-v vdevs (default: %llu)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-s size_of_each_vdev (default: %s)]\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-a alignment_shift (default: %d)] use 0 for random\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-m mirror_copies (default: %d)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-r raidz_disks (default: %d)]\n"
99653d4ee642c6528e88224f12409a5f23060994eschrock "\t[-R raidz_parity (default: %d)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-d datasets (default: %d)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-t threads (default: %d)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-g gang_block_threshold (default: %s)]\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-i init_count (default: %d)] initialize pool i times\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-k kill_percentage (default: %llu%%)]\n"
fa9e4066f08beec538e775443c5be79dd423fcabahrens "\t[-p pool_name (default: %s)]\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-f dir (default: %s)] file directory for vdev files\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-V] verbose (use multiple times for ever more blather)\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-E] use existing pool instead of creating new one\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-T time (default: %llu sec)] total run time\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
2215e990accbb747e6562e1cf14b772c9341dd35Mark J Musante "\t[-P passtime (default: %llu sec)] time per pass\n"
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden "\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
f1b4288b3b466065edd5eb9868399db6a4ff283evb "\t[-h] (print help)\n"
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zo->zo_metaslab_gang_bang = MAX(SPA_MINBLOCKSIZE << 1,
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) strlcpy(altdir, optarg, sizeof (altdir));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zo->zo_raidz_parity = MIN(zo->zo_raidz_parity, zo->zo_raidz - 1);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (zo->zo_vdevs > 0 ? zo->zo_time * NANOSEC / zo->zo_vdevs :
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps realaltdir = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps VERIFY(NULL != realpath(getexecname(), cmd));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden fatal(B_TRUE, "invalid alternate ztest path: %s",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * 'cmd' should be of the form "<anything>/usr/bin/<isa>/ztest".
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * We want to extract <isa> to determine if we should use
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * 32 or 64 bit binaries.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) snprintf(zo->zo_alt_ztest, sizeof (zo->zo_alt_ztest),
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden "%s/usr/bin/%.*s/ztest", realaltdir, isalen, isa);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) snprintf(zo->zo_alt_libpath, sizeof (zo->zo_alt_libpath),
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden } else if (0 != access(zo->zo_alt_libpath, X_OK)) {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden fatal(B_TRUE, "invalid alternate lib directory %s",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(ztest_spa));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa));
b4952e17e8858d3225793b28788278de9fe6038dGeorge Wilson * Before we kill off ztest, make sure that the config is updated.
b4952e17e8858d3225793b28788278de9fe6038dGeorge Wilson * See comment above spa_config_sync().
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (r % range);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
25345e466695fbe736faa53b8f3413d8e8f81981George Wilsonmake_vdev_file(char *path, char *aux, char *pool, size_t size, uint64_t ashift)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson pool == NULL ? ztest_opts.zo_pool : pool, vdev);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666);
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_TYPE, VDEV_TYPE_FILE) == 0);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick VERIFY(nvlist_add_string(file, ZPOOL_CONFIG_PATH, path) == 0);
ecc2d604e885a75cc75e647b5641af99d5a6f4a6bonwick VERIFY(nvlist_add_uint64(file, ZPOOL_CONFIG_ASHIFT, ashift) == 0);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilsonmake_vdev_raidz(char *path, char *aux, char *pool, size_t size,
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson return (make_vdev_file(path, aux, pool, size, ashift));
fa9e4066f08beec538e775443c5be79dd423fcabahrens child = umem_alloc(r * sizeof (nvlist_t *), UMEM_NOFAIL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < r; c++)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson child[c] = make_vdev_file(path, aux, pool, size, ashift);
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_alloc(&raidz, NV_UNIQUE_NAME, 0) == 0);
99653d4ee642c6528e88224f12409a5f23060994eschrock VERIFY(nvlist_add_uint64(raidz, ZPOOL_CONFIG_NPARITY,
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_add_nvlist_array(raidz, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < r; c++)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilsonmake_vdev_mirror(char *path, char *aux, char *pool, size_t size,
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson return (make_vdev_raidz(path, aux, pool, size, ashift, r));
fa9e4066f08beec538e775443c5be79dd423fcabahrens child = umem_alloc(m * sizeof (nvlist_t *), UMEM_NOFAIL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < m; c++)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson child[c] = make_vdev_raidz(path, aux, pool, size, ashift, r);
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_add_nvlist_array(mirror, ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < m; c++)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilsonmake_vdev_root(char *path, char *aux, char *pool, size_t size, uint64_t ashift,
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson int log, int r, int m, int t)
fa9e4066f08beec538e775443c5be79dd423fcabahrens child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick for (c = 0; c < t; c++) {
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson child[c] = make_vdev_mirror(path, aux, pool, size, ashift,
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(nvlist_add_string(root, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) == 0);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick VERIFY(nvlist_add_nvlist_array(root, aux ? aux : ZPOOL_CONFIG_CHILDREN,
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (c = 0; c < t; c++)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * Find a random spa version. Returns back a random spa version in the
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * range [initial_version, SPA_VERSION_FEATURES].
25345e466695fbe736faa53b8f3413d8e8f81981George Wilsonztest_random_spa_version(uint64_t initial_version)
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson ztest_random(SPA_VERSION_BEFORE_FEATURES - version + 1);
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * Choose a block size >= the ashift.
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens * If the SPA supports new MAXBLOCKSIZE, test up to 1MB blocks.
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens if (spa_maxblocksize(ztest_spa) == SPA_MAXBLOCKSIZE)
81cd5c555f505484180a62ca5a2fbb00d70c57d6Matthew Ahrens block_shift = ztest_random(maxbs - ztest_spa->spa_max_ashift + 1);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_random(DN_MAX_INDBLKSHIFT - DN_MIN_INDBLKSHIFT + 1));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_random_vdev_top(spa_t *spa, boolean_t log_ok)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(spa_config_held(spa, SCL_ALL, RW_READER) != 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick } while (tvd->vdev_ishole || (tvd->vdev_islog && !log_ok) ||
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick tvd->vdev_mg == NULL || tvd->vdev_mg->mg_class == NULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick value = zfs_prop_random_value(prop, ztest_random(-1ULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick } while (prop == ZFS_PROP_CHECKSUM && value == ZIO_CHECKSUM_OFF);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), value);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_prop_get_integer(osname, propname, &curval, setpoint));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenztest_spa_prop_set_uint64(zpool_prop_t prop, uint64_t value)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(nvlist_add_uint64(props, zpool_prop_to_name(prop), value) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(_mutex_init(&rll->rll_lock, USYNC_THREAD, NULL) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(cond_init(&rll->rll_cv, USYNC_THREAD, NULL) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) cond_wait(&rll->rll_cv, &rll->rll_lock);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick while (rll->rll_writer != NULL || rll->rll_readers)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) cond_wait(&rll->rll_cv, &rll->rll_lock);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (rll->rll_writer == NULL && rll->rll_readers == 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_object_lock(ztest_ds_t *zd, uint64_t object, rl_type_t type)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rll_t *rll = &zd->zd_object_lock[object & (ZTEST_OBJECT_LOCKS - 1)];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_object_unlock(ztest_ds_t *zd, uint64_t object)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rll_t *rll = &zd->zd_object_lock[object & (ZTEST_OBJECT_LOCKS - 1)];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_range_lock(ztest_ds_t *zd, uint64_t object, uint64_t offset,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t hash = object ^ (offset % (ZTEST_RANGE_LOCKS + 1));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rll_t *rll = &zd->zd_range_lock[hash & (ZTEST_RANGE_LOCKS - 1)];
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenztest_zd_init(ztest_ds_t *zd, ztest_shared_ds_t *szd, objset_t *os)
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock VERIFY(rwlock_init(&zd->zd_zilog_lock, USYNC_THREAD, NULL) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(_mutex_init(&zd->zd_dirobj_lock, USYNC_THREAD, NULL) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int l = 0; l < ZTEST_RANGE_LOCKS; l++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(_mutex_destroy(&zd->zd_dirobj_lock) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int l = 0; l < ZTEST_OBJECT_LOCKS; l++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int l = 0; l < ZTEST_RANGE_LOCKS; l++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick#define TXG_MIGHTWAIT (ztest_random(10) == 0 ? TXG_NOWAIT : TXG_WAIT)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_tx_assign(dmu_tx_t *tx, uint64_t txg_how, const char *tag)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Attempt to assign tx to some transaction group.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_pattern_set(void *buf, uint64_t size, uint64_t value)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t *ip_end = (uint64_t *)((uintptr_t)buf + (uintptr_t)size);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_pattern_match(void *buf, uint64_t size, uint64_t value)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t *ip_end = (uint64_t *)((uintptr_t)buf + (uintptr_t)size);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (diff == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_bt_generate(ztest_block_tag_t *bt, objset_t *os, uint64_t object,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_bt_verify(ztest_block_tag_t *bt, objset_t *os, uint64_t object,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t offset, uint64_t gen, uint64_t txg, uint64_t crtxg)
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens ASSERT3U(bt->bt_objset, ==, dmu_objset_id(os));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT3U(doi.doi_bonus_size, >=, sizeof (*bt));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bt = (void *)((char *)db->db_data + doi.doi_bonus_size - sizeof (*bt));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * ZIL logging ops
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_log_create(ztest_ds_t *zd, dmu_tx_t *tx, lr_create_t *lr)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick char *name = (void *)(lr + 1); /* name follows lr */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx = zil_itx_create(TX_CREATE, sizeof (*lr) + namesize);
5002558f6bfef3915c7f3b4ecb7c19c7f044bf5bNeil Perrinztest_log_remove(ztest_ds_t *zd, dmu_tx_t *tx, lr_remove_t *lr, uint64_t object)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick char *name = (void *)(lr + 1); /* name follows lr */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx = zil_itx_create(TX_REMOVE, sizeof (*lr) + namesize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx_wr_state_t write_state = ztest_random(WR_NUM_STATES);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (*lr) + (write_state == WR_COPIED ? lr->lr_length : 0));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_read(zd->zd_os, lr->lr_foid, lr->lr_offset, lr->lr_length,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ((lr_write_t *)&itx->itx_lr) + 1, DMU_READ_NO_PREFETCH) != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx->itx_sod += (write_state == WR_NEED_COPY ? lr->lr_length : 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_log_truncate(ztest_ds_t *zd, dmu_tx_t *tx, lr_truncate_t *lr)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx = zil_itx_create(TX_TRUNCATE, sizeof (*lr));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_log_setattr(ztest_ds_t *zd, dmu_tx_t *tx, lr_setattr_t *lr)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick itx = zil_itx_create(TX_SETATTR, sizeof (*lr));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * ZIL replay ops
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_replay_create(ztest_ds_t *zd, lr_create_t *lr, boolean_t byteswap)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick char *name = (void *)(lr + 1); /* name follows lr */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_zap(tx, lr->lr_doid, B_TRUE, name);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, B_TRUE, NULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(dmu_objset_zil(os)->zl_replay == !!lr->lr_foid);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_object_set_blocksize(os, lr->lr_foid,
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_gen, txg, txg);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_add(os, lr->lr_doid, name, sizeof (uint64_t), 1,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_replay_remove(ztest_ds_t *zd, lr_remove_t *lr, boolean_t byteswap)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick char *name = (void *)(lr + 1); /* name follows lr */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zap_lookup(os, lr->lr_doid, name, sizeof (object), 1, &object));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_object_info(os, object, &doi));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_zap(tx, lr->lr_doid, B_FALSE, name);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_object_free(os, object, tx));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_remove(os, lr->lr_doid, name, tx));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_replay_write(ztest_ds_t *zd, lr_write_t *lr, boolean_t byteswap)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick /* If it's a dmu_sync() block, write the whole block */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rl = ztest_range_lock(zd, lr->lr_foid, offset, length, RL_WRITER);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, lr->lr_foid, offset, length);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_random(8) == 0 && length == doi.doi_data_block_size &&
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Usually, verify the old data before writing new data --
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * but not always, because we also want to verify correct
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * behavior when the data was not recently read into cache.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Writes can appear to be newer than the bonus buffer because
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * the ztest_get_data() callback does a dmu_read() of the
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * open-context data, which may be different than the data
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * as it was when the write was generated.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Set the bt's gen/txg to the bonus buffer's gen/txg
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * so that all of the usual ASSERTs will work.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_bt_generate(bt, os, lr->lr_foid, offset, gen, txg, crtxg);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_write(os, lr->lr_foid, offset, length, data, tx);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_replay_truncate(ztest_ds_t *zd, lr_truncate_t *lr, boolean_t byteswap)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rl = ztest_range_lock(zd, lr->lr_foid, lr->lr_offset, lr->lr_length,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_free(tx, lr->lr_foid, lr->lr_offset, lr->lr_length);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(dmu_free_range(os, lr->lr_foid, lr->lr_offset,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_replay_setattr(ztest_ds_t *zd, lr_setattr_t *lr, boolean_t byteswap)
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_bonus_hold(os, lr->lr_foid, FTAG, &db));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Randomly change the size and increment the generation.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr->lr_size = (ztest_random(db->db_size / sizeof (*bbt)) + 1) *
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that the current bonus buffer is not newer than our txg.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_bt_verify(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_bt_generate(bbt, os, lr->lr_foid, -1ULL, lr->lr_mode, txg, crtxg);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickzil_replay_func_t *ztest_replay_vector[TX_MAX_TYPE] = {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * ZIL get_data callbacks
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zgd->zgd_rl = ztest_range_lock(zd, object, offset, size,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = dmu_read(os, object, offset, size, buf,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zgd->zgd_rl = ztest_range_lock(zd, object, offset, size,
47cb52daa729f19e298c85a84e8df069365c5232Jeff Bonwick error = dmu_buf_hold(os, object, offset, zgd, &db,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickstatic void *
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr = umem_zalloc(lrsize + namesize, UMEM_NOFAIL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_lr_free(void *lr, size_t lrsize, char *name)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Lookup a bunch of objects. Returns the number of objects not found.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_lookup(ztest_ds_t *zd, ztest_od_t *od, int count)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = zap_lookup(zd->zd_os, od->od_dir, od->od_name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(missing == 0); /* there should be no gaps */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_object_lock(zd, od->od_object, RL_READER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_create(ztest_ds_t *zd, ztest_od_t *od, int count)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr_create_t *lr = ztest_lr_alloc(sizeof (*lr), od->od_name);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr->lr_foid = 0; /* 0 to allocate, > 0 to claim */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_replay_create(zd, lr, B_FALSE) != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_remove(ztest_ds_t *zd, ztest_od_t *od, int count)
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson * No object was found.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr_remove_t *lr = ztest_lr_alloc(sizeof (*lr), od->od_name);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if ((error = ztest_replay_remove(zd, lr, B_FALSE)) != 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_write(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick lr = ztest_lr_alloc(sizeof (*lr) + size, NULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_truncate(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = ztest_replay_truncate(zd, lr, B_FALSE);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_prealloc(ztest_ds_t *zd, uint64_t object, uint64_t offset, uint64_t size)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rl = ztest_range_lock(zd, object, offset, size, RL_WRITER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) dmu_free_long_range(os, object, offset, size);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(dmu_object_info(zd->zd_os, object, &doi) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Pick an i/o type at random, biased toward writing block tags.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_bt_generate(&wbt, zd->zd_os, object, offset, 0, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_write(zd, object, offset, sizeof (wbt), &wbt);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) memset(data, 'a' + (object + offset) % 5, blocksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Induce fletcher2 collisions to ensure that
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * zio_ddt_collision() detects and resolves them
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * when using fletcher2-verify for deduplication.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_write(zd, object, offset, blocksize, data);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_write(zd, object, offset, blocksize, data);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_truncate(zd, object, offset, blocksize);
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson (void) ztest_write(zd, object, offset, blocksize, data);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Initialize an object description template.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_od_init(ztest_od_t *od, uint64_t id, char *tag, uint64_t index,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_object_type_t type, uint64_t blocksize, uint64_t gen)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick od->od_crblocksize = blocksize ? blocksize : ztest_random_blocksize();
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) snprintf(od->od_name, sizeof (od->od_name), "%s(%lld)[%llu]",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Lookup or create the objects for a test using the od template.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If the objects do not all exist, or if 'remove' is specified,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * remove any existing objects and create new ones. Otherwise,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * use the existing objects.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_object_init(ztest_ds_t *zd, ztest_od_t *od, size_t size, boolean_t remove)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if ((ztest_lookup(zd, od, count) != 0 || remove) &&
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Remember the committed values in zd, which is in parent/child
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * shared memory. If we die, the next iteration of ztest_run()
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * will verify that the log really does contain this record.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ASSERT3U(zd->zd_shared->zd_seq, <=, zilog->zl_commit_lr_seq);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zd->zd_shared->zd_seq = zilog->zl_commit_lr_seq;
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock * This function is designed to simulate the operations that occur during a
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock * mount/unmount operation. We hold the dataset across these operations in an
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock * attempt to expose any implicit assumptions about ZIL management.
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock/* ARGSUSED */
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson * We grab the zd_dirobj_lock to ensure that no other thread is
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson * updating the zil (i.e. adding in-memory log records) and the
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson * zd_zilog_lock to block any I/O.
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock /* zfsvfs_teardown() */
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock /* zfsvfs_setup() */
c9ba2a43cb76c223d115e021fdabd2c066e020edEric Schrock VERIFY(zil_open(os, ztest_get_data) == zd->zd_zilog);
ce636f8b38e8c9ff484e880d9abb27251a882860Matthew Ahrens VERIFY(mutex_unlock(&zd->zd_dirobj_lock) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that we can't destroy an active pool, create an existing pool,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * or create a pool with a bad vdev spec.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Attempt to create using a bad file.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens spa_create("ztest_bad_file", nvroot, NULL, NULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Attempt to create using a bad mirror.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 2, 1);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens spa_create("ztest_bad_mirror", nvroot, NULL, NULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Attempt to create an existing pool. It shouldn't matter
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * what's in the nvroot; we should fail with EEXIST.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson/* ARGSUSED */
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson uint64_t initial_version = SPA_VERSION_INITIAL;
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson name = kmem_asprintf("%s_upgrade", ztest_opts.zo_pool);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * Clean up from previous runs.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvroot = make_vdev_root(NULL, NULL, name, ztest_opts.zo_vdev_size, 0,
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson 0, ztest_opts.zo_raidz, ztest_opts.zo_mirrors, 1);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * If we're configuring a RAIDZ device then make sure that the
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * the initial version is capable of supporting that feature.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * Create a pool with a spa version that can be upgraded. Pick
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson * a value between initial_version and SPA_VERSION_BEFORE_FEATURES.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson version = ztest_random_spa_version(initial_version);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson } while (version > SPA_VERSION_BEFORE_FEATURES);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson zpool_prop_to_name(ZPOOL_PROP_VERSION), version);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson VERIFY0(spa_create(name, nvroot, props, NULL));
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson newversion = ztest_random_spa_version(version + 1);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson (void) printf("upgrading spa version from %llu to %llu\n",
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson (u_longlong_t)version, (u_longlong_t)newversion);
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson VERIFY3U(spa_version(spa), ==, fnvlist_lookup_uint64(spa->spa_config,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickvdev_lookup_by_path(vdev_t *vd, const char *path)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (vd->vdev_path != NULL && strcmp(path, vd->vdev_path) == 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if ((mvd = vdev_lookup_by_path(vd->vdev_child[c], path)) !=
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Find the first available hole which can be used as a top-level.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(spa_config_held(spa, SCL_VDEV, RW_READER) == SCL_VDEV);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that vdev_add() works as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_shared->zs_vdev_next_leaf = find_vdev_hole(spa) * leaves;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If we have slogs then remove them 1/4 of the time.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson if (spa_has_slogs(spa) && ztest_random(4) == 0) {
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Grab the guid from the head of the log class rotor.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick guid = spa_log_class(spa)->mc_rotor->mg_vd->vdev_guid;
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * We have to grab the zs_name_lock as writer to
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * prevent a race between removing a slog (dmu_objset_find)
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * and destroying a dataset. Removing the slog will
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * grab a reference on the dataset which may cause
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * dmu_objset_destroy() to fail with EBUSY thus
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * leaving the dataset in an inconsistent state.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson * Make 1/4 of the devices be log devices.
88ecc943b4eb72f7c4fbbd8435997b85ef171fc3George Wilson else if (error != 0)
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Verify that adding/removing aux devices (l2arc, hot spare) works as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick if (sav->sav_count != 0 && ztest_random(4) == 0) {
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Pick a random device to remove.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick guid = sav->sav_vdevs[ztest_random(sav->sav_count)]->vdev_guid;
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Find an unused device we can add.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) snprintf(path, sizeof (path), ztest_aux_template,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Add a new device.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvlist_t *nvroot = make_vdev_root(NULL, aux, NULL,
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Remove an existing device. Sometimes, dirty its
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * vdev state first to make sure we handle removal
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * of devices that have pending state changes.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick fatal(0, "spa_vdev_remove(%llu) = %d", guid, error);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante * split a pool if it has mirror tlvdevs
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante/* ARGSUSED */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante nvlist_t *tree, **child, *config, *split, **schild;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante uint_t c, children, schildren = 0, lastlogid = 0;
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* ensure we have a useable config; mirrors of raidz aren't supported */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden if (zs->zs_mirrors < 3 || ztest_opts.zo_raidz > 1) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* clean up the old pool, if any */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* generate a config from the existing config */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_lookup_nvlist(spa->spa_config, ZPOOL_CONFIG_VDEV_TREE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN, &child,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante schild = malloc(rvd->vdev_children * sizeof (nvlist_t *));
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (c = 0; c < children; c++) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante if (tvd->vdev_islog || tvd->vdev_ops == &vdev_hole_ops) {
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_alloc(&schild[schildren], NV_UNIQUE_NAME,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_dup(mchild[0], &schild[schildren++], 0) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante /* OK, create a config that can be used to split */
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_alloc(&split, NV_UNIQUE_NAME, 0) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_add_string(split, ZPOOL_CONFIG_TYPE,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_add_nvlist_array(split, ZPOOL_CONFIG_CHILDREN, schild,
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante lastlogid != 0 ? lastlogid : schildren) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, 0) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, split) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante for (c = 0; c < schildren; c++)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante error = spa_vdev_split_mirror(spa, "splitp", config, NULL, B_FALSE);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante (void) printf("successful split - results:\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that we can attach and detach devices.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Decide whether to do an attach or a replace.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Pick a random top-level vdev.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Pick a random leaf within it.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * Locate this vdev.
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante ASSERT(oldvd->vdev_children >= zs->zs_mirrors);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden oldvd = oldvd->vdev_child[leaf / ztest_opts.zo_raidz];
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ASSERT(oldvd->vdev_children == ztest_opts.zo_raidz);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden oldvd = oldvd->vdev_child[leaf % ztest_opts.zo_raidz];
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * If we're already doing an attach or replace, oldvd may be a
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * mirror vdev -- in which case, pick a random child.
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick oldvd = oldvd->vdev_child[ztest_random(oldvd->vdev_children)];
9af0a4dffb12fece9e4ca0a97721e6e05ca2bca9Jeff Bonwick * If oldvd has siblings, then half of the time, detach it.
9af0a4dffb12fece9e4ca0a97721e6e05ca2bca9Jeff Bonwick if (oldvd_has_siblings && ztest_random(2) == 0) {
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick error = spa_vdev_detach(spa, oldguid, pguid, B_FALSE);
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick if (error != 0 && error != ENODEV && error != EBUSY &&
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick fatal(0, "detach (%s) returned %d", oldpath, error);
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * For the new vdev, choose with equal probability between the two
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * standard paths (ending in either 'a' or 'b') or a random hot spare.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick if (sav->sav_count != 0 && ztest_random(3) == 0) {
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick newvd = sav->sav_vdevs[ztest_random(sav->sav_count)];
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick (void) snprintf(newpath, sizeof (newpath), ztest_dev_template,
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * Make newsize a little bigger or smaller than oldsize.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * If it's smaller, the attach should fail.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * If it's larger, and we're doing a replace,
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick * we should get dynamic LUN growth when we're done.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick newsize = 10 * oldsize / (9 + ztest_random(3));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If pvd is not a mirror or root, the attach should fail with ENOTSUP,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * unless it's a replace; in that case any non-replacing parent is OK.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * If newvd is already part of the pool, it should fail with EBUSY.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * If newvd is too small, it should fail with EOVERFLOW.
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick pvd->vdev_ops != &vdev_root_ops && (!replacing ||
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick else if (newvd_is_spare && (!replacing || oldvd_is_log))
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick else if (vdev_lookup_by_path(rvd, newpath) != NULL)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Build the nvlist describing newpath.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson root = make_vdev_root(newpath, NULL, NULL, newvd == NULL ? newsize : 0,
31157203d871bc0b4bc67d925b0a8424570774a1Jeff Bonwick error = spa_vdev_attach(spa, oldguid, root, replacing);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If our parent was the replacing vdev, but the replace completed,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * then instead of failing with ENOTSUP we may either succeed,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fail with ENODEV, or fail with EOVERFLOW.
fa9e4066f08beec538e775443c5be79dd423fcabahrens (error == 0 || error == ENODEV || error == EOVERFLOW))
f0aa80d4da975c8ef3e34c15c60ea31e9b75f7a9bonwick * If someone grew the LUN, the replacement may be too small.
088f389458728c464569a5506b58070254fa4f7dahrens /* XXX workaround 6690467 */
088f389458728c464569a5506b58070254fa4f7dahrens if (error != expected_error && expected_error != EBUSY) {
088f389458728c464569a5506b58070254fa4f7dahrens "returned %d, expected %d",
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Callback function which expands the physical size of the vdev.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson (void) printf("%s grew from %lu to %lu bytes\n",
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson vd->vdev_path, (ulong_t)fsize, (ulong_t)*newsize);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Callback function which expands a given vdev by calling vdev_online().
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson/* ARGSUSED */
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson uint64_t generation = spa->spa_config_generation + 1;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson ASSERT(spa_config_held(spa, SCL_STATE, RW_READER) == SCL_STATE);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson /* Calling vdev_online will initialize the new metaslabs */
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson error = vdev_online(spa, guid, ZFS_ONLINE_EXPAND, &newstate);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson spa_config_enter(spa, SCL_STATE, spa, RW_READER);
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson * If vdev_online returned an error or the underlying vdev_open
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson * failed then we abort the expand. The only way to know that
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson * vdev_open fails is by checking the returned newstate.
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson if (error || newstate != VDEV_STATE_HEALTHY) {
095bcd6622e3b3520eb3b71039a3be5cfab25b74George Wilson (void) printf("Unable to expand vdev, state %llu, "
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Since we dropped the lock we need to ensure that we're
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * still talking to the original vdev. It's possible this
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * vdev may have been detached/replaced while we were
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * trying to online it.
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson if (generation != spa->spa_config_generation) {
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson (void) printf("vdev configuration has changed, "
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson "guid %llu, state %llu, expected gen %llu, "
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick "got gen %llu\n",
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Traverse the vdev tree calling the supplied function.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * We continue to walk the tree until we either have walked all
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * children or we receive a non-NULL return from the callback.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * If a NULL callback is passed, then we just return back the first
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * leaf vdev we encounter.
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilsonvdev_walk_tree(vdev_t *vd, vdev_t *(*func)(vdev_t *, void *), void *arg)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson for (uint_t c = 0; c < vd->vdev_children; c++) {
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if ((cvd = vdev_walk_tree(cvd, func, arg)) != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that dynamic LUN growth works as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t old_class_space, new_class_space, old_ms_count, new_ms_count;
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson spa_config_enter(spa, SCL_STATE, spa, RW_READER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick old_class_space = metaslab_class_get_space(mc);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Determine the size of the first leaf vdev associated with
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * our top-level device.
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * We only try to expand the vdev if it's healthy, less than 4x its
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * original size, and it has a valid psize.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden psize == 0 || psize >= 4 * ztest_opts.zo_vdev_size) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("Expanding LUN %s from %lu to %lu\n",
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson vd->vdev_path, (ulong_t)psize, (ulong_t)newsize);
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Growing the vdev is a two step process:
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * 1). expand the physical size (i.e. relabel)
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * 2). online the vdev to create the new metaslabs
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson if (vdev_walk_tree(tvd, grow_vdev, &newsize) != NULL ||
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson vdev_walk_tree(tvd, online_vdev, NULL) != NULL ||
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick "the vdev configuration changed.\n");
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Expanding the LUN will update the config asynchronously,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * thus we must wait for the async thread to complete any
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * pending tasks before proceeding.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick done = (spa->spa_async_thread == NULL && !spa->spa_async_tasks);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick spa_config_enter(spa, SCL_STATE, spa, RW_READER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick new_class_space = metaslab_class_get_space(mc);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (tvd->vdev_mg != mg || mg->mg_class != mc) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("Could not verify LUN expansion due to "
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick "intervening vdev offline or remove.\n");
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Make sure we were able to grow the vdev.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick fatal(0, "LUN expansion failed: ms_count %llu <= %llu\n",
573ca77e53dd31dcaebef023e7eb41969e6896c1George Wilson * Make sure we were able to grow the pool.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick fatal(0, "LUN expansion failed: class_space %llu <= %llu\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that dmu_objset_{create,destroy,open,close} work as expected.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_objset_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Create the objects common to all ztest datasets.
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante int err = dmu_objset_create(dsname, DMU_OST_OTHER, 0,
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) printf("Setting dataset %s to sync always\n", dsname);
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante return (ztest_dsl_prop_set_uint64(dsname, ZFS_PROP_SYNC,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
fd1368791be99c4a6354fa81f08408c2dbf4b444Matthew Ahrensztest_objset_destroy_cb(const char *name, void *arg)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that the dataset contains a directory object.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, FTAG, &os));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = dmu_object_info(os, ZTEST_DIROBJ, &doi);
e19302335c33c8c6e0b0b5e426fc1f6352c84b5dbonwick /* We could have crashed in the middle of destroying it */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Destroy the dataset.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dsl_destroy_snapshot(name, B_FALSE));
1d452cf5123cb6ac0a013a4dbd4dcceeb0da314dahrens return (0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_snapshot_create(char *osname, uint64_t id)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_snapshot_one(osname, snapname);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "ztest_snapshot_create(%s@%s) = %d", osname,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_snapshot_destroy(char *osname, uint64_t id)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snapname, sizeof (snapname), "%s@%llu", osname,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(snapname, B_FALSE);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick fatal(0, "ztest_snapshot_destroy(%s) = %d", snapname, error);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(name, sizeof (name), "%s/temp_%llu",
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If this dataset exists from a previous run, process its replay log
fa9e4066f08beec538e775443c5be79dd423fcabahrens * half of the time. If we don't replay it, then dmu_objset_destroy()
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * (invoked from ztest_objset_destroy_cb()) should just throw it away.
503ad85c168c7992ccc310af845a581cff3c72b5Matthew Ahrens dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * There may be an old instance of the dataset we're about to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * create lying around from a previous run. If so, destroy it
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and all of its snapshots.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) dmu_objset_find(name, ztest_objset_destroy_cb, NULL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that the destroyed dataset is no longer in the namespace.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that we can create a new dataset.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Open the intent log for it.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Put some objects in there, do a little I/O to them,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * and randomly take a couple of snapshots along the way.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int i = 0; i < iters; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that we cannot create an existing dataset.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_objset_create(name, DMU_OST_OTHER, 0, NULL, NULL));
503ad85c168c7992ccc310af845a581cff3c72b5Matthew Ahrens * Verify that we can hold an objset that is also owned.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_objset_hold(name, FTAG, &os2));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that we cannot own an objset that is already owned.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os2));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that dmu_snapshot_{create,destroy,open,close} work as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_snapshot_create_destroy(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_snapshot_destroy(zd->zd_name, id);
718d718a734e79bad0b9f8a264219b238fabaf44George Wilson * Cleanup non-standard snapshots and clones.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dsl_dataset_cleanup(char *osname, uint64_t id)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap1name, sizeof (snap1name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(clone1name, sizeof (clone1name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap2name, sizeof (snap2name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(clone2name, sizeof (clone2name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap3name, sizeof (snap3name),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_head(%s) = %d", clone2name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(snap3name, B_FALSE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s) = %d", snap3name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(snap2name, B_FALSE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s) = %d", snap2name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_head(%s) = %d", clone1name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(snap1name, B_FALSE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error);
4f5064b73b1cc9de1d0f1a2ae700d519d4d565dfMark J Musante * Verify dsl_dataset_promote handles EBUSY
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap1name, sizeof (snap1name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(clone1name, sizeof (clone1name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap2name, sizeof (snap2name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(clone2name, sizeof (clone2name),
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(snap3name, sizeof (snap3name),
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens error = dmu_objset_snapshot_one(osname, strchr(snap1name, '@') + 1);
b2d22b66bc47a107891381986ae05e32ff517d10George Wilson fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_clone(clone1name, snap1name);
b2d22b66bc47a107891381986ae05e32ff517d10George Wilson fatal(0, "dmu_objset_create(%s) = %d", clone1name, error);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens error = dmu_objset_snapshot_one(clone1name, strchr(snap2name, '@') + 1);
b2d22b66bc47a107891381986ae05e32ff517d10George Wilson fatal(0, "dmu_open_snapshot(%s) = %d", snap2name, error);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens error = dmu_objset_snapshot_one(clone1name, strchr(snap3name, '@') + 1);
b2d22b66bc47a107891381986ae05e32ff517d10George Wilson fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_clone(clone2name, snap3name);
b2d22b66bc47a107891381986ae05e32ff517d10George Wilson fatal(0, "dmu_objset_create(%s) = %d", clone2name, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, FTAG, &os);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dmu_objset_own(%s) = %d", snap2name, error);
4f5064b73b1cc9de1d0f1a2ae700d519d4d565dfMark J Musante fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that dmu_object_{alloc,free} work as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_object_alloc_free(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int b = 0; b < batchsize; b++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[b], id, FTAG, b, DMU_OT_UINT64_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Destroy the previous batch of objects, create a new batch,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * and do some I/O on the new objects.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_TRUE) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_io(zd, od[ztest_random(batchsize)].od_object,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that dmu_{read,write} work as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t packobj, packoff, packsize, bigobj, bigoff, bigsize;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t chunksize = (1000 + ztest_random(1000)) * sizeof (uint64_t);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This test uses two objects, packobj and bigobj, that are always
fa9e4066f08beec538e775443c5be79dd423fcabahrens * updated together (i.e. in the same tx) so that their contents are
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in sync and can be compared. Their contents relate to each other
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in a simple way: packobj is a dense array of 'bufwad' structures,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * while bigobj is a sparse array of the same bufwads. Specifically,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for any index n, there are three bufwads that should be identical:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * packobj, at offset n * sizeof (bufwad_t)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * bigobj, at the head of the nth chunk
fa9e4066f08beec538e775443c5be79dd423fcabahrens * bigobj, at the tail of the nth chunk
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The chunk size is arbitrary. It doesn't have to be a power of two,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and it doesn't have any relation to the object blocksize.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The only requirement is that it can hold at least two bufwads.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Normally, we write the bufwad to each of these locations.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * However, free_percent of the time we instead write zeroes to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * packobj and perform a dmu_free_range() on bigobj. By comparing
fa9e4066f08beec538e775443c5be79dd423fcabahrens * bigobj to packobj, we can verify that the DMU is correctly
fa9e4066f08beec538e775443c5be79dd423fcabahrens * tracking which parts of an object are allocated and free,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and that the contents of the allocated blocks are correct.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Read the directory info. If it's the first time, set things up.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, chunksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Prefetch a random chunk of the big object.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Our aim here is to get some async reads in flight
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for blocks that we may free below; the DMU should
fa9e4066f08beec538e775443c5be79dd423fcabahrens * handle this race correctly.
fa9e4066f08beec538e775443c5be79dd423fcabahrens n = ztest_random(regions) * stride + ztest_random(width);
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie dmu_prefetch(os, bigobj, 0, n * chunksize, s * chunksize,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Pick a random index and compute the offsets into packobj and bigobj.
fa9e4066f08beec538e775443c5be79dd423fcabahrens n = ztest_random(regions) * stride + ztest_random(width);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * free_percent of the time, free a range of bigobj rather than
fa9e4066f08beec538e775443c5be79dd423fcabahrens * overwriting it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Read the current contents of our objects.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = dmu_read(os, packobj, packoff, packsize, packbuf,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = dmu_read(os, bigobj, bigoff, bigsize, bigbuf,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Get a tx for the mods to both packobj and bigobj.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, packobj, packoff, packsize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, bigobj, bigoff, bigsize);
be9000cc677e0a8d04e5be45c61d7370fc8c7b54Matthew Ahrens /* This accounts for setting the checksum/compression. */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens } while (cksum >= ZIO_CHECKSUM_LEGACY_FUNCTIONS);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens dmu_object_set_checksum(os, bigobj, cksum, tx);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens } while (comp >= ZIO_COMPRESS_LEGACY_FUNCTIONS);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens dmu_object_set_compress(os, bigobj, comp, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For each index from n to n + s, verify that the existing bufwad
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in packobj matches the bufwads at the head and tail of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * corresponding chunk in bigobj. Then update all three bufwads
fa9e4066f08beec538e775443c5be79dd423fcabahrens * with the new values we want to write out.
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < s; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* LINTED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens pack = (bufwad_t *)((char *)packbuf + i * sizeof (bufwad_t));
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* LINTED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bigH = (bufwad_t *)((char *)bigbuf + i * chunksize);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* LINTED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bigT = (bufwad_t *)((char *)bigH + chunksize) - 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT((uintptr_t)bigH - (uintptr_t)bigbuf < bigsize);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT((uintptr_t)bigT - (uintptr_t)bigbuf < bigsize);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We've verified all the old bufwads, and made new ones.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Now write them out.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_write(os, packobj, packoff, packsize, packbuf, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens " txg %llx\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(0 == dmu_free_range(os, bigobj, bigoff, bigsize, tx));
fa9e4066f08beec538e775443c5be79dd423fcabahrens " txg %llx\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_write(os, bigobj, bigoff, bigsize, bigbuf, tx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Sanity check the stuff we just wrote.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiycompare_and_update_pbbufs(uint64_t s, bufwad_t *packbuf, bufwad_t *bigbuf,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t bigsize, uint64_t n, uint64_t chunksize, uint64_t txg)
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * For each index from n to n + s, verify that the existing bufwad
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * in packobj matches the bufwads at the head and tail of the
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * corresponding chunk in bigobj. Then update all three bufwads
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * with the new values we want to write out.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy for (i = 0; i < s; i++) {
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy pack = (bufwad_t *)((char *)packbuf + i * sizeof (bufwad_t));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bigH = (bufwad_t *)((char *)bigbuf + i * chunksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bigT = (bufwad_t *)((char *)bigH + chunksize) - 1;
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy ASSERT((uintptr_t)bigH - (uintptr_t)bigbuf < bigsize);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy ASSERT((uintptr_t)bigT - (uintptr_t)bigbuf < bigsize);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy fatal(0, "future leak: got %llx, open txg is %llx",
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy if (pack->bw_data != 0 && pack->bw_index != n + i)
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy fatal(0, "wrong index: got %llx, wanted %llx+%llx",
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy if (bcmp(pack, bigH, sizeof (bufwad_t)) != 0)
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy fatal(0, "pack/bigH mismatch in %p/%p", pack, bigH);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy if (bcmp(pack, bigT, sizeof (bufwad_t)) != 0)
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy fatal(0, "pack/bigT mismatch in %p/%p", pack, bigT);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy pack->bw_data = 1 + ztest_random(-2ULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_read_write_zcopy(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t packobj, packoff, packsize, bigobj, bigoff, bigsize;
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * This test uses two objects, packobj and bigobj, that are always
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * updated together (i.e. in the same tx) so that their contents are
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * in sync and can be compared. Their contents relate to each other
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * in a simple way: packobj is a dense array of 'bufwad' structures,
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * while bigobj is a sparse array of the same bufwads. Specifically,
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * for any index n, there are three bufwads that should be identical:
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * packobj, at offset n * sizeof (bufwad_t)
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * bigobj, at the head of the nth chunk
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * bigobj, at the tail of the nth chunk
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * The chunk size is set equal to bigobj block size so that
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * dmu_assign_arcbuf() can be tested for object updates.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Read the directory info. If it's the first time, set things up.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[1], id, FTAG, 1, DMU_OT_UINT64_OTHER, 0, chunksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(dmu_object_info(os, bigobj, &doi) == 0);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Pick a random index and compute the offsets into packobj and bigobj.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy n = ztest_random(regions) * stride + ztest_random(width);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy packbuf = umem_zalloc(packsize, UMEM_NOFAIL);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy bigbuf = umem_zalloc(bigsize, UMEM_NOFAIL);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, dmu_bonus_hold(os, bigobj, FTAG, &bonus_db));
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy bigbuf_arcbufs = umem_zalloc(2 * s * sizeof (arc_buf_t *), UMEM_NOFAIL);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 0 test zcopy for DB_UNCACHED dbufs.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 1 test zcopy to already referenced dbufs.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 2 test zcopy to dirty dbuf in the same txg.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 3 test zcopy to dbuf dirty in previous txg.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 4 test zcopy when dbuf is no longer dirty.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 5 test zcopy when it can't be done.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Iteration 6 one more zcopy write.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy for (i = 0; i < 7; i++) {
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * In iteration 5 (i == 5) use arcbufs
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * that don't match bigobj blksz to test
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * dmu_assign_arcbuf() when it can't directly
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * assign an arcbuf to a dbuf.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy for (j = 0; j < s; j++) {
89c86e32293a30cdd7af530c38b2073fee01411cChris Williamson if (i != 5 || chunksize < (SPA_MINBLOCKSIZE * 2)) {
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Get a tx for the mods to both packobj and bigobj.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, packobj, packoff, packsize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, bigobj, bigoff, bigsize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy for (j = 0; j < s; j++) {
89c86e32293a30cdd7af530c38b2073fee01411cChris Williamson if (i != 5 ||
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy umem_free(bigbuf_arcbufs, 2 * s * sizeof (arc_buf_t *));
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * 50% of the time don't read objects in the 1st iteration to
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * test dmu_assign_arcbuf() for the case when there're no
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * existing dbufs for the specified offsets.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy compare_and_update_pbbufs(s, packbuf, bigbuf, bigsize,
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * We've verified all the old bufwads, and made new ones.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Now write them out.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_write(os, packobj, packoff, packsize, packbuf, tx);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy (void) printf("writing offset %llx size %llx"
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy " txg %llx\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (off = bigoff, j = 0; j < s; j++, off += chunksize) {
89c86e32293a30cdd7af530c38b2073fee01411cChris Williamson if (i != 5 || chunksize < (SPA_MINBLOCKSIZE * 2)) {
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy bcopy((caddr_t)bigbuf + (off - bigoff) +
89c86e32293a30cdd7af530c38b2073fee01411cChris Williamson if (i != 5 || chunksize < (SPA_MINBLOCKSIZE * 2)) {
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy * Sanity check the stuff we just wrote.
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy void *packcheck = umem_alloc(packsize, UMEM_NOFAIL);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy void *bigcheck = umem_alloc(bigsize, UMEM_NOFAIL);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy ASSERT(bcmp(packbuf, packcheck, packsize) == 0);
2fdbea25c2ba89186b8a6b7c6840ebc9f4dff245Aleksandr Guzovskiy ASSERT(bcmp(bigbuf, bigcheck, bigsize) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick } else if (i == 3) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick umem_free(bigbuf_arcbufs, 2 * s * sizeof (arc_buf_t *));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_write_parallel(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t offset = (1ULL << (ztest_random(20) + 43)) +
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Have multiple threads write to large offsets in an object
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * to verify that parallel writes to an object -- even to the
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * same blocks within the object -- doesn't cause any trouble.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], ID_PARALLEL, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t offset = (1ULL << (ztest_random(4) + SPA_MAXBLOCKSHIFT)) +
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_truncate(zd, od[0].od_object, offset, count * blocksize) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_prealloc(zd, od[0].od_object, offset, count * blocksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t randoff = offset + (ztest_random(count) * blocksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_write(zd, od[0].od_object, randoff, blocksize,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that zap_{create,destroy,add,remove,update} work as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Generate a known hash collision, and verify that
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * we can lookup and remove both entries.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (i = 0; i < 2; i++) {
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_add(os, object, hc[i], sizeof (uint64_t),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (i = 0; i < 2; i++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY3U(EEXIST, ==, zap_add(os, object, hc[i],
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe zap_length(os, object, hc[i], &zl_intsize, &zl_ints));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (i = 0; i < 2; i++) {
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_remove(os, object, hc[i], tx));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Generate a buch of random entries.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ints = MAX(ZTEST_ZAP_MIN_INTS, object % ZTEST_ZAP_MAX_INTS);
e05725b117836db173257fae43fb0746eb857fb5bonwick (void) sprintf(propname, "prop_%llu", (u_longlong_t)prop);
e05725b117836db173257fae43fb0746eb857fb5bonwick (void) sprintf(txgname, "txg_%llu", (u_longlong_t)prop);
e05725b117836db173257fae43fb0746eb857fb5bonwick * If these zap entries already exist, validate their contents.
e05725b117836db173257fae43fb0746eb857fb5bonwick error = zap_length(os, object, txgname, &zl_intsize, &zl_ints);
e05725b117836db173257fae43fb0746eb857fb5bonwick if (error == 0) {
e05725b117836db173257fae43fb0746eb857fb5bonwick VERIFY(zap_length(os, object, propname, &zl_intsize,
e05725b117836db173257fae43fb0746eb857fb5bonwick for (i = 0; i < ints; i++) {
e05725b117836db173257fae43fb0746eb857fb5bonwick * Atomically update two entries in our zap object.
e05725b117836db173257fae43fb0746eb857fb5bonwick * The first is named txg_%llu, and contains the txg
e05725b117836db173257fae43fb0746eb857fb5bonwick * in which the property was last updated. The second
e05725b117836db173257fae43fb0746eb857fb5bonwick * is named prop_%llu, and the nth element of its value
e05725b117836db173257fae43fb0746eb857fb5bonwick * should be txg + object + n.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
e05725b117836db173257fae43fb0746eb857fb5bonwick fatal(0, "zap future leak: old %llu new %llu", last_txg, txg);
e05725b117836db173257fae43fb0746eb857fb5bonwick for (i = 0; i < ints; i++)
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_update(os, object, txgname, sizeof (uint64_t),
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_update(os, object, propname, sizeof (uint64_t),
e05725b117836db173257fae43fb0746eb857fb5bonwick * Remove a random pair of entries.
e05725b117836db173257fae43fb0746eb857fb5bonwick (void) sprintf(propname, "prop_%llu", (u_longlong_t)prop);
e05725b117836db173257fae43fb0746eb857fb5bonwick (void) sprintf(txgname, "txg_%llu", (u_longlong_t)prop);
e05725b117836db173257fae43fb0746eb857fb5bonwick error = zap_length(os, object, txgname, &zl_intsize, &zl_ints);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_remove(os, object, txgname, tx));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_remove(os, object, propname, tx));
12a2833a0260ba374a4e6d8225376193e908784aSanjeev Bagewadi * Testcase to test the upgrading of a microzap to fatzap.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), !ztest_random(2)) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Add entries to this ZAP and make sure it spills over
12a2833a0260ba374a4e6d8225376193e908784aSanjeev Bagewadi * and gets upgraded to a fatzap. Also, since we are adding
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * 2050 entries we should see ptrtbl growth and leaf-block split.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int i = 0; i < 2050; i++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) snprintf(name, sizeof (name), "fzap-%llu-%llu",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = zap_add(os, object, name, sizeof (uint64_t), 1,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t txg, object, count, wsize, wc, zl_wsize, zl_wc;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], ID_PARALLEL, FTAG, micro, DMU_OT_ZAP_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
e05725b117836db173257fae43fb0746eb857fb5bonwick * Generate a random name of the form 'xxx.....' where each
e05725b117836db173257fae43fb0746eb857fb5bonwick * x is a random printable character and the dots are dots.
e05725b117836db173257fae43fb0746eb857fb5bonwick * There are 94 such characters, and the name length goes from
e05725b117836db173257fae43fb0746eb857fb5bonwick * 6 to 20, so there are 94^3 * 15 = 12,458,760 possible names.
e05725b117836db173257fae43fb0746eb857fb5bonwick for (i = 0; i < 3; i++)
e05725b117836db173257fae43fb0746eb857fb5bonwick * Select an operation: length, lookup, add, update, remove.
e05725b117836db173257fae43fb0746eb857fb5bonwick if (i >= 2) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
e05725b117836db173257fae43fb0746eb857fb5bonwick switch (i) {
e05725b117836db173257fae43fb0746eb857fb5bonwick error = zap_length(os, object, name, &zl_wsize, &zl_wc);
e05725b117836db173257fae43fb0746eb857fb5bonwick if (error == 0) {
e05725b117836db173257fae43fb0746eb857fb5bonwick error = zap_lookup(os, object, name, wsize, wc, data);
e05725b117836db173257fae43fb0746eb857fb5bonwick if (error == 0) {
e05725b117836db173257fae43fb0746eb857fb5bonwick error = zap_add(os, object, name, wsize, wc, data, tx);
e05725b117836db173257fae43fb0746eb857fb5bonwick VERIFY(zap_update(os, object, name, wsize, wc, data, tx) == 0);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Commit callback data.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia/* This is the actual commit callback function */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correiaztest_commit_callback(void *arg, int error)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia VERIFY3S(data->zcd_expected_err, ==, error);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia synced_txg = spa_last_synced_txg(data->zcd_spa);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia fatal(0, "commit callback of txg %" PRIu64 " called prematurely"
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia ", last synced txg = %" PRIu64 "\n", data->zcd_txg,
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * The private callback data should be destroyed here, but
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * since we are going to check the zcd_called field after
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * dmu_tx_abort(), we will destroy it there.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia /* Was this callback added to the global callback list? */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia /* Remove our callback from the list */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia (void) mutex_lock(&zcl.zcl_callbacks_lock);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia (void) mutex_unlock(&zcl.zcl_callbacks_lock);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia umem_free(data, sizeof (ztest_cb_data_t));
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia/* Allocate and initialize callback data structure */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correiaztest_create_cb_data(objset_t *os, uint64_t txg)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia cb_data = umem_zalloc(sizeof (ztest_cb_data_t), UMEM_NOFAIL);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * If a number of txgs equal to this threshold have been created after a commit
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * callback has been registered but not called, then we assume there is an
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * implementation bug.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia#define ZTEST_COMMIT_CALLBACK_THRESH (TXG_CONCURRENT_STATES + 2)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Commit callback test.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_commit_callbacks(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia cb_data[0] = ztest_create_cb_data(os, 0);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[0]);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, od[0].od_object, 0, sizeof (uint64_t));
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia /* Every once in a while, abort the transaction on purpose */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia cb_data[1] = ztest_create_cb_data(os, txg);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[1]);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * It's not a strict requirement to call the registered
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * callbacks from inside dmu_tx_abort(), but that's what
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * it's supposed to happen in the current implementation
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * so we will check for that.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia for (i = 0; i < 2; i++) {
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia cb_data[i]->zcd_expected_err = ECANCELED;
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia for (i = 0; i < 2; i++) {
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia umem_free(cb_data[i], sizeof (ztest_cb_data_t));
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia cb_data[2] = ztest_create_cb_data(os, txg);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[2]);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Read existing data to make sure there isn't a future leak.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(0 == dmu_read(os, od[0].od_object, 0, sizeof (uint64_t),
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia fatal(0, "future leak: got %" PRIu64 ", open txg is %" PRIu64,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_write(os, od[0].od_object, 0, sizeof (uint64_t), &txg, tx);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia (void) mutex_lock(&zcl.zcl_callbacks_lock);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Since commit callbacks don't have any ordering requirement and since
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * it is theoretically possible for a commit callback to be called
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * after an arbitrary amount of time has elapsed since its txg has been
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * synced, it is difficult to reliably determine whether a commit
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * callback hasn't been called due to high load or due to a flawed
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * implementation.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * In practice, we will assume that if after a certain number of txgs a
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * commit callback hasn't been called, then most likely there's an
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * implementation bug..
b3d9f2e26021d3f55a281af30720589d303b9806Will Andrews (txg - ZTEST_COMMIT_CALLBACK_THRESH) > tmp_cb->zcd_txg) {
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia fatal(0, "Commit callback threshold exceeded, oldest txg: %"
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia PRIu64 ", open txg: %" PRIu64 "\n", tmp_cb->zcd_txg, txg);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Let's find the place to insert our callbacks.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * Even though the list is ordered by txg, it is possible for the
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * insertion point to not be the end because our txg may already be
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * quiescing at this point and other callbacks in the open txg
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia * (from other objsets) may have sneaked in.
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia while (tmp_cb != NULL && tmp_cb->zcd_txg > txg)
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia tmp_cb = list_prev(&zcl.zcl_callbacks, tmp_cb);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia /* Add the 3 callbacks to the list */
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia for (i = 0; i < 3; i++) {
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia list_insert_head(&zcl.zcl_callbacks, cb_data[i]);
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia list_insert_after(&zcl.zcl_callbacks, tmp_cb,
d20e665c84abf083a9e8b62cca93383ecb55afdfRicardo M. Correia (void) mutex_unlock(&zcl.zcl_callbacks_lock);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dsl_prop_get_set(ztest_ds_t *zd, uint64_t id)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < sizeof (proplist) / sizeof (proplist[0]); p++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ztest_dsl_prop_set_uint64(zd->zd_name, proplist[p],
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_random_dsl_prop(proplist[p]), (int)ztest_random(2));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id)
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) ztest_spa_prop_set_uint64(ZPOOL_PROP_DEDUPDITTO,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ZIO_DEDUPDITTO_MIN + ztest_random(ZIO_DEDUPDITTO_MIN));
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrensuser_release_one(const char *snapname, const char *holdname)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_user_release(snaps, NULL);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * Test snapshot hold/release and deferred destroy.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) snprintf(snapname, sizeof (snapname), "sh1_%llu", id);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) snprintf(fullname, sizeof (fullname), "%s@%s", osname, snapname);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) snprintf(clonename, sizeof (clonename),
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens (void) snprintf(tag, sizeof (tag), "tag_%llu", id);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * Clean up from any previous run.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(fullname, B_FALSE);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * Create snapshot, clone it, mark snap for deferred destroy,
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * destroy clone, verify snap was also destroyed.
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens error = dmu_objset_snapshot_one(osname, snapname);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dmu_objset_clone(clonename, fullname);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby fatal(0, "dmu_objset_clone(%s) = %d", clonename, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(fullname, B_TRUE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_head(%s) = %d", clonename, error);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby error = dmu_objset_hold(fullname, FTAG, &origin);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby fatal(0, "dmu_objset_hold(%s) = %d", fullname, error);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * Create snapshot, add temporary hold, verify that we can't
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * destroy a held snapshot, mark for deferred destroy,
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby * release hold, verify snapshot was destroyed.
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens error = dmu_objset_snapshot_one(osname, snapname);
5c987a37e6561d090231fb3c10ba9f6ea995f34dChris Kirby fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_dataset_user_hold(holds, 0, NULL);
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens ztest_record_enospc("dsl_dataset_user_hold");
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens } else if (error) {
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens fatal(0, "dsl_dataset_user_hold(%s, %s) = %u",
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(fullname, B_FALSE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s, B_FALSE) = %d",
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = dsl_destroy_snapshot(fullname, B_TRUE);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d",
a7a845e4bf22fd1b2a284729ccd95c7370a0438cSteven Hartland fatal(0, "user_release_one(%s, %s) = %d", fullname, tag, error);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Inject random faults into the on-disk data.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * Grab the name lock as reader. There are some operations
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * which don't like to have their vdevs changed while
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * they are in progress (i.e. spa_change_guid). Those
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * operations will have grabbed the name lock as writer.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * We need SCL_STATE here because we're going to look at vd0->vdev_tsd.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick spa_config_enter(spa, SCL_STATE, FTAG, RW_READER);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Inject errors on a normal data device or slog device.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Generate paths to the first leaf in this top-level vdev,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * and to the random leaf we selected. We'll induce transient
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * write failures and random online/offline activity on leaf 0,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * and we'll write random garbage to the randomly chosen leaf.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick (void) snprintf(path0, sizeof (path0), ztest_dev_template,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick (void) snprintf(pathrand, sizeof (pathrand), ztest_dev_template,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick vd0 = vdev_lookup_by_path(spa->spa_root_vdev, path0);
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * If the top-level vdev needs to be resilvered
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * then we only allow faults on the device that is
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * resilvering.
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson (!vdev_resilver_needed(vd0->vdev_top, NULL, NULL) ||
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Make vd0 explicitly claim to be unreadable,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * or unwriteable, or reach behind its back
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * and close the underlying fd. We can do this if
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * maxfaults == 0 because we'll fail and reexecute,
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * and we can do it if maxfaults >= 2 because we'll
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * have enough redundancy. If maxfaults == 1, the
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * combination of this with injection of random data
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * corruption below exceeds the pool's fault tolerance.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Inject errors on an l2cache device.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick vd0 = sav->sav_vdevs[ztest_random(sav->sav_count)];
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick maxfaults = INT_MAX; /* no limit on cache devices */
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * If we can tolerate two or more faults, or we're dealing
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * with a slog, randomly online/offline vd0.
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson if ((maxfaults >= 2 || islog) && guid0 != 0) {
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * We have to grab the zs_name_lock as writer to
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * prevent a race between offlining a slog and
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * destroying a dataset. Offlining the slog will
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * grab a reference on the dataset which may cause
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * dmu_objset_destroy() to fail with EBUSY thus
8f18d1fadf6a0c20fac9ff7259a5368faa3c3bfbGeorge Wilson * leaving the dataset in an inconsistent state.
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick VERIFY(vdev_offline(spa, guid0, flags) != EBUSY);
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * Ideally we would like to be able to randomly
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * call vdev_[on|off]line without holding locks
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * to force unpredictable failures but the side
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * effects of vdev_[on|off]line prevent us from
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * doing so. We grab the ztest_vdev_lock here to
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * prevent a race between injection testing and
9253d63df408bb48584e0b1abfcc24ef2472382eGeorge Wilson * aux_vdev removal.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * We have at least single-fault tolerance, so inject data corruption.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fd == -1) /* we hit a gap in the device namespace */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (--iters != 0) {
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * The offset must be chosen carefully to ensure that
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * we do not inject a given logical block with errors
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * on two different leaf devices, because ZFS can not
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * tolerate that (if maxfaults==1).
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * We divide each leaf into chunks of size
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * (# leaves * SPA_MAXBLOCKSIZE * 4). Within each chunk
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * there is a series of ranges to which we can inject errors.
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * Each range can accept errors on only a single leaf vdev.
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * The error injection ranges are separated by ranges
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * which we will not inject errors on any device (DMZs).
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * Each DMZ must be large enough such that a single block
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * can not straddle it, so that a single block can not be
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * a target in two different injection ranges (on different
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * leaf vdevs).
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * For example, with 3 leaves, each chunk looks like:
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 0 to 32M: injection range for leaf 0
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 32M to 64M: DMZ - no injection allowed
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 64M to 96M: injection range for leaf 1
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 96M to 128M: DMZ - no injection allowed
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 128M to 160M: injection range for leaf 2
f9eb9fdf196b6ed476e4ffc69cecd8b0da3cb7e7Matthew Ahrens * 160M to 192M: DMZ - no injection allowed
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (pwrite(fd, &bad, sizeof (bad), offset) != sizeof (bad))
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante " offset 0x%llx\n", pathrand, (u_longlong_t)offset);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that DDT repair works as expected.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t object, blocksize, txg, pattern, psize;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick enum zio_checksum checksum = spa_dedup_checksum(spa);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick blocksize = MIN(blocksize, 2048); /* because we write so many */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_od_init(&od[0], id, FTAG, 0, DMU_OT_UINT64_OTHER, blocksize, 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_object_init(zd, od, sizeof (od), B_FALSE) != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Take the name lock as writer to prevent anyone else from changing
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * the pool and dataset properies we need to maintain during this test.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_DEDUP, checksum,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_COPIES, 1,
aab80726335c76a7cae32c7300890248d73a51e3George Wilson dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
aab80726335c76a7cae32c7300890248d73a51e3George Wilson dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_tx_hold_write(tx, object, 0, copies * blocksize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Write all the copies of our block.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int i = 0; i < copies; i++) {
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens int error = dmu_buf_hold(os, object, offset, FTAG, &db,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(B_FALSE, "dmu_buf_hold(%p, %llu, %llu) = %u",
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens os, (long long)object, (long long) offset, error);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) ||
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_pattern_match(db->db_data, db->db_size, 0ULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ztest_pattern_set(db->db_data, db->db_size, pattern);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Find out what block we got.
80901aea8e78a2c20751f61f01bebd1d5b5c2ba5George Wilson VERIFY0(dmu_buf_hold(os, object, 0, FTAG, &db,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Damage the block. Dedup-ditto will save us when we read it later.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) zio_wait(zio_rewrite(NULL, spa, 0, &blk,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick buf, psize, NULL, NULL, ZIO_PRIORITY_SYNC_WRITE,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ZIO_FLAG_CANFAIL | ZIO_FLAG_INDUCE_DAMAGE, NULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Scrub the pool.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) poll(NULL, 0, 100); /* wait a moment, then force a restart */
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore * Change the guid for the pool.
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore/* ARGSUSED */
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore (void) printf("Changed guid old %llu -> %llu\n",
e9103aaee0c546d4644791198c54abb03c89969eGarrett D'Amore (u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Rename the pool to a different name and then rename it back.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick/* ARGSUSED */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick newname = umem_alloc(strlen(oldname) + 5, UMEM_NOFAIL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Do the rename
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Try to open it under the old name, which shouldn't exist
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY3U(ENOENT, ==, spa_open(oldname, &spa, FTAG));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Open it under the new name and make sure it's still the same spa_t.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(newname, &spa, FTAG));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Rename it back to the original
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Make sure it can still be opened
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(oldname, &spa, FTAG));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify pool integrity by running zdb.
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* zdb lives in /usr/sbin, while ztest lives in /usr/bin */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* LINTED */
5d7b4d438c4a51eccc95e77a83a437b4d48380ebMatthew Ahrens "/usr/sbin%.*s/zdb -bcc%s%s -d -U %s %s",
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("Executing %s\n", strstr(zdb, "zdb "));
fa9e4066f08beec538e775443c5be79dd423fcabahrens fatal(0, "'%s' exit code %d", zdb, WEXITSTATUS(status));
fa9e4066f08beec538e775443c5be79dd423fcabahrens fatal(0, "'%s' died with signal %d", zdb, WTERMSIG(status));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Clean up from previous runs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Get the pool's configuration and guid.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(oldname, &spa, FTAG));
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * Kick off a scrub to tickle scrub/export races.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Export it.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_export(oldname, &config, B_FALSE, B_FALSE));
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * Try to import it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Import it under the new name.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens error = spa_import(newname, config, NULL, 0);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens fatal(B_FALSE, "couldn't import pool %s as %s: error %u",
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Try to import it again -- should fail with EEXIST.
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson VERIFY3U(EEXIST, ==, spa_import(newname, config, NULL, 0));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Try to import it under a different name -- should fail with EEXIST.
4b964ada391d44b89d97e7e930e6a9a136e0a2f4George Wilson VERIFY3U(EEXIST, ==, spa_import(oldname, config, NULL, 0));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that the pool is no longer visible under the old name.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY3U(ENOENT, ==, spa_open(oldname, &spa, FTAG));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that we can open and close the pool using the new name.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(newname, &spa, FTAG));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden if (spa_suspended(spa) && ztest_opts.zo_verbose >= 6)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("resuming from suspended state\n");
0a4e9518a44f226be6d39383330b5b1792d2f184gwstatic void *
dcbf3bd6a1f1360fc1afcee9e22c6dcff7844bf2George Wilson * Periodically change the zfs_compressed_arc_enabled setting.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickstatic void *
69962b5647e4a8b9b14998733b765925381b727eMatthew Ahrens delta = zs->zs_thread_stop - zs->zs_thread_start +
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * If the pool is suspended then fail immediately. Otherwise,
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * check to see if the pool is making any progress. If
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * vdev_deadman() discovers that there hasn't been any recent
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson * I/Os then it will end up aborting the tests.
0713e232b7712cd27d99e1e935ebb8d5de61c57dGeorge Wilson if (spa_suspended(spa) || spa->spa_root_vdev == NULL) {
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson fatal(0, "aborting test after %llu seconds because "
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson "pool has transitioned to a suspended state.",
2c1e2b44148432fb7a509dd216a99299b6740250George Wilson (void) printf("ztest has been running for %lld seconds\n",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenztest_execute(int test, ztest_info_t *zi, uint64_t id)
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_ds_t *zd = &ztest_ds[id % ztest_opts.zo_datasets];
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_shared_callstate_t *zc = ZTEST_GET_SHARED_CALLSTATE(test);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic void *
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick while ((now = gethrtime()) < zs->zs_thread_stop) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See if it's time to force a crash.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If we're getting ENOSPC with some regularity, stop.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Pick a random function to execute.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden atomic_cas_64(&zc->zc_next, call_next, call_next +
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_random(2 * zi->zi_interval[0] + 1)) == call_next) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickztest_dataset_name(char *dsname, char *pool, int d)
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(dsname, ZFS_MAX_DATASET_NAME_LEN, "%s/ds_%d", pool, d);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_dataset_name(name, ztest_opts.zo_pool, d);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("Destroying %s to free up space\n", name);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Cleanup any non-standard clones and snapshots. In general,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * ztest thread t operates on dataset (t % zopt_datasets),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * so there may be more than one thing to clean up.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) dmu_objset_find(name, ztest_objset_destroy_cb, NULL,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * ZTEST_DIROBJ is the object directory for the entire dataset.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Therefore, the number of objects in use should equal the
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * number of ZTEST_DIROBJ entries, +1 for ZTEST_DIROBJ itself.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If not, we have an object leak.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Note that we can only check this in ztest_dataset_open(),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * when the open-context and syncing-context values agree.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * That's because zap_count() returns the open-context value,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * while dmu_objset_space() returns the rootbp fill count.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, zap_count(zd->zd_os, ZTEST_DIROBJ, &dirobjs));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dmu_objset_space(zd->zd_os, &scratch, &scratch, &usedobjs, &scratch);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden uint64_t committed_seq = ZTEST_GET_SHARED_DS(d)->zd_seq;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_dataset_name(name, ztest_opts.zo_pool, d);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zilog->zl_header->zh_claim_lr_seq < committed_seq)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick fatal(0, "missing log records: claimed %llu < committed %llu",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zilog->zl_header->zh_claim_lr_seq, committed_seq);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("%s replay %llu blocks, %llu records, seq %llu\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick fatal(0, "missing log records: replayed %llu < committed %llu",
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Kick off threads to run tests on all datasets in parallel.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Initialize parent/child shared state.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zs->zs_thread_start + ztest_opts.zo_passtime * NANOSEC;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zs->zs_thread_stop = MIN(zs->zs_thread_stop, zs->zs_proc_stop);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden if (ztest_random(100) < ztest_opts.zo_killrate) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) _mutex_init(&zcl.zcl_callbacks_lock, USYNC_THREAD, NULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick list_create(&zcl.zcl_callbacks, sizeof (ztest_cb_data_t),
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Open our pool.
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG));
30beaff42d8240ebf5386e8b7a14e3d137a1631fGeorge Wilson metaslab_preload_limit = ztest_random(20) + 1;
aab80726335c76a7cae32c7300890248d73a51e3George Wilson dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
aab80726335c76a7cae32c7300890248d73a51e3George Wilson dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * We don't expect the pool to suspend unless maxfaults == 0,
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * in which case ztest_fault_inject() temporarily takes away
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick * the only valid replica.
e14bb3258d05c1b1077e2db7cf77088924e56919Jeff Bonwick * Create a thread to periodically resume suspended I/O.
8ad4d6dd86f5bc65fb3afa566c8133f3bac21648Jeff Bonwick VERIFY(thr_create(0, 0, ztest_resume_thread, spa, THR_BOUND,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Create a deadman thread to abort() if we hang.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(thr_create(0, 0, ztest_deadman_thread, zs, THR_BOUND,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Verify that we can safely inquire about about any object,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * whether it's allocated or not. To make it interesting,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we probe a 5-wide window around each power of two.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This hits all edge cases, including zero and the max.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int t = 0; t < 64; t++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If we got any ENOSPC errors on the previous run, destroy something.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden tid = umem_zalloc(ztest_opts.zo_threads * sizeof (thread_t),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Kick off all the tests that run in parallel.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden for (int t = 0; t < ztest_opts.zo_threads; t++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(thr_create(0, 0, ztest_thread, (void *)(uintptr_t)t,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Wait for all of the tests to complete. We go in reverse order
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * so we don't close datasets while threads are still using them.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden for (int t = ztest_opts.zo_threads - 1; t >= 0; t--) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(spa));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zs->zs_space = metaslab_class_get_space(spa_normal_class(spa));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden umem_free(tid, ztest_opts.zo_threads * sizeof (thread_t));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick /* Kill the resume thread */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Right before closing the pool, kick off a bunch of async I/O;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * spa_close() should wait for it to complete.
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie for (uint64_t object = 1; object < 50; object++) {
a2cdcdd260232b58202b11a9bfc0103c9449ed52Paul Dagnelie dmu_prefetch(spa->spa_meta_objset, object, 0, 0, 1ULL << 20,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that we can loop over all pools.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (spa = spa_next(NULL); spa != NULL; spa = spa_next(spa))
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) printf("spa_next: found %s\n", spa_name(spa));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Verify that we can export the pool and reimport it under a
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * different name.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens (void) snprintf(name, sizeof (name), "%s_import",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_spa_import_export(ztest_opts.zo_pool, name);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_spa_import_export(name, ztest_opts.zo_pool);
26cb54a92aed3443f699b590c5c1601ba9a22963George Wilson (void) _mutex_destroy(&zcl.zcl_callbacks_lock);
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Force the first log block to be transactionally allocated.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * We have to do this before we freeze the pool -- otherwise
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * the log chain won't be anchored.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick while (BP_IS_HOLE(&zd->zd_zilog->zl_header->zh_log)) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Freeze the pool. This stops spa_sync() from doing anything,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * so that the only way to record changes from now on is the ZIL.
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece * Because it is hard to predict how much space a write will actually
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece * require beforehand, we leave ourselves some fudge space to write over
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece uint64_t capacity = metaslab_class_get_space(spa_normal_class(spa)) / 2;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Run tests that generate log records but don't alter the pool config
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * or depend on DSL sync tasks (snapshots, objset create/destroy, etc).
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * We do a txg_wait_synced() after each iteration to force the txg
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * to increase well beyond the last synced value in the uberblock.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * The ZIL should be OK with that.
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece * Run a random number of times less than zo_maxloops and ensure we do
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece * not run out of space on the pool.
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece metaslab_class_get_alloc(spa_normal_class(spa)) < capacity) {
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece ztest_od_init(&od, 0, FTAG, 0, DMU_OT_UINT64_OTHER, 0, 0);
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece VERIFY0(ztest_object_init(zd, &od, sizeof (od), B_FALSE));
2a104a5236475eb73aa41eaaf3ed9f3ccbe0ca55Alex Reece ztest_random(ZTEST_RANGE_LOCKS) << SPA_MAXBLOCKSHIFT);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Commit all of the changes we just generated.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Close our dataset and close the pool.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Open and close the pool and dataset to induce log replay.
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
fa9e4066f08beec538e775443c5be79dd423fcabahrens s -= m * 60;
fa9e4066f08beec538e775443c5be79dd423fcabahrens m -= h * 60;
fa9e4066f08beec538e775443c5be79dd423fcabahrens h -= d * 24;
fa9e4066f08beec538e775443c5be79dd423fcabahrens "%llud%02lluh%02llum%02llus", d, h, m, s);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (h)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) sprintf(timebuf, "%lluh%02llum%02llus", h, m, s);
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (m)
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0);
1195e687f1c03c8d57417b5999578922e20a3554Mark J Musante VERIFY(nvlist_add_uint64(props, "autoreplace", 1) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create a storage pool with the given name and initial vdev size.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Then test spa_freeze() functionality.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden VERIFY(_mutex_init(&ztest_vdev_lock, USYNC_THREAD, NULL) == 0);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden VERIFY(rwlock_init(&ztest_name_lock, USYNC_THREAD, NULL) == 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create the storage pool.
25345e466695fbe736faa53b8f3413d8e8f81981George Wilson nvroot = make_vdev_root(NULL, NULL, NULL, ztest_opts.zo_vdev_size, 0,
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden for (int i = 0; i < SPA_FEATURES; i++) {
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden (void) snprintf(buf, sizeof (buf), "feature@%s",
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, nvlist_add_uint64(props, buf, 0));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props, NULL));
b420f3adeb349714478d1a7813d2c0e069d41555Richard Lowe VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden 1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift;
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps static char ztest_name_data[] = "/tmp/ztest.data.XXXXXX";
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden size += hdr->zh_stats_size * hdr->zh_stats_count;
ad135b5d644628e791c3188a6ecbd9c257961ef8Christopher Siden size += hdr->zh_ds_size * hdr->zh_ds_count;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps VERIFY3U(0, ==, ftruncate(ztest_fd_data, sizeof (ztest_shared_hdr_t)));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hdr->zh_stats_size = sizeof (ztest_shared_callstate_t);
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps VERIFY3U(0, ==, ftruncate(ztest_fd_data, size));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden offset += hdr->zh_stats_size * hdr->zh_stats_count;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Sidenexec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps cmdbuf = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps (void) strlcpy(cmdbuf, getexecname(), MAXPATHLEN);
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps snprintf(fd_data_str, 12, "%d", ztest_fd_data));
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps VERIFY0(setenv("ZTEST_FD_DATA", fd_data_str, 1));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) fprintf(stderr, "child exited with code %d\n",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden if (!ignorekill || WTERMSIG(status) != SIGKILL) {
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) fprintf(stderr, "child died with signal %d\n",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) fprintf(stderr, "something strange happened to child\n");
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden /* NOTREACHED */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * Blow away any existing copy of zpool.cache
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden * Create and initialize our storage pool.
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps char *fd_data_str = getenv("ZTEST_FD_DATA");
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps ztest_fd_rand = open("/dev/urandom", O_RDONLY);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ASSERT3U(ztest_opts.zo_datasets, ==, ztest_shared_hdr->zh_ds_count);
f0ba89be159095fb15265a5e1cd79e09e5e44ef9Jeff Bonwick /* Override location of zpool.cache */
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps VERIFY3U(asprintf((char **)&spa_config_path, "%s/zpool.cache",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden ztest_ds = umem_alloc(ztest_opts.zo_datasets * sizeof (ztest_ds_t),
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden hasalt = (strlen(ztest_opts.zo_alt_ztest) != 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens " %llu seconds...\n",
741652b0d7a641dcc9c966750c26e41bcc641863Etienne Dechamps (void) strlcpy(cmd, getexecname(), MAXNAMELEN);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden "initialization: %s\n", ztest_opts.zo_alt_ztest);
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden zs->zs_proc_stop = zs->zs_proc_start + ztest_opts.zo_time * NANOSEC;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int f = 0; f < ZTEST_FUNCS; f++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (zs->zs_proc_start + zi->zi_interval[0] > zs->zs_proc_stop)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Run the tests in a loop. These tests include fault injection
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to verify that self-healing data works, and forced crashes
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to verify that we never lose on-disk consistency.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize the workload counters for each function.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int f = 0; f < ZTEST_FUNCS; f++) {
d6e555bdd793b8bc8fe57d5f12c3d69c813d0661George Wilson /* Set the allocation switch size */
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden killed = exec_child(cmd, NULL, B_TRUE, &status);
fa9e4066f08beec538e775443c5be79dd423fcabahrens "%4.1f%% of %5s used, %3.0f%% done, %8s to go\n",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int f = 0; f < ZTEST_FUNCS; f++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * It's possible that we killed a child during a rename test,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * in which case we'll have a 'ztest_tmp' pool lying around
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * instead of 'ztest'. Do a blind rename in case this happened.
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden if (spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) snprintf(tmpname, sizeof (tmpname), "%s_tmp",
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) printf("%d runs of older ztest: %s\n", older,
420dfc9585ff67e83ee7800a7ad2ebe1a9145983Chris Siden (void) printf("%d runs of newer ztest: %s\n", newer,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) printf("%d killed, %d completed, %.0f%% kill rate\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens kills, iters - kills, (100.0 * kills) / MAX(1, iters));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);