]> git.proxmox.com Git - mirror_zfs.git/blobdiff - cmd/ztest/ztest.c
OpenZFS 7280 - Allow changing global libzpool variables in zdb and ztest through...
[mirror_zfs.git] / cmd / ztest / ztest.c
index ad15dea1d543ac60452a9b4f38c7549411e44c30..d1c6a783aebde05e7a86a72bc67725a868fcb00b 100644 (file)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  */
 #include <sys/refcount.h>
 #include <sys/zfeature.h>
 #include <sys/dsl_userhold.h>
+#include <sys/abd.h>
 #include <stdio.h>
 #include <stdio_ext.h>
 #include <stdlib.h>
@@ -145,8 +146,8 @@ typedef struct ztest_shared_hdr {
 static ztest_shared_hdr_t *ztest_shared_hdr;
 
 typedef struct ztest_shared_opts {
-       char zo_pool[MAXNAMELEN];
-       char zo_dir[MAXNAMELEN];
+       char zo_pool[ZFS_MAX_DATASET_NAME_LEN];
+       char zo_dir[ZFS_MAX_DATASET_NAME_LEN];
        char zo_alt_ztest[MAXNAMELEN];
        char zo_alt_libpath[MAXNAMELEN];
        uint64_t zo_vdevs;
@@ -177,7 +178,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = {
        .zo_mirrors = 2,
        .zo_raidz = 4,
        .zo_raidz_parity = 1,
-       .zo_vdev_size = SPA_MINDEVSIZE * 2,
+       .zo_vdev_size = SPA_MINDEVSIZE * 4,     /* 256m default size */
        .zo_datasets = 7,
        .zo_threads = 23,
        .zo_passtime = 60,              /* 60 seconds */
@@ -192,6 +193,8 @@ static const ztest_shared_opts_t ztest_opts_defaults = {
 extern uint64_t metaslab_gang_bang;
 extern uint64_t metaslab_df_alloc_threshold;
 extern int metaslab_preload_limit;
+extern boolean_t zfs_compressed_arc_enabled;
+extern int  zfs_abd_scatter_enabled;
 
 static ztest_shared_opts_t *ztest_shared_opts;
 static ztest_shared_opts_t ztest_opts;
@@ -262,7 +265,7 @@ typedef struct ztest_od {
        uint64_t        od_crdnodesize;
        uint64_t        od_gen;
        uint64_t        od_crgen;
-       char            od_name[MAXNAMELEN];
+       char            od_name[ZFS_MAX_DATASET_NAME_LEN];
 } ztest_od_t;
 
 /*
@@ -274,7 +277,7 @@ typedef struct ztest_ds {
        rwlock_t        zd_zilog_lock;
        zilog_t         *zd_zilog;
        ztest_od_t      *zd_od;         /* debugging aid */
-       char            zd_name[MAXNAMELEN];
+       char            zd_name[ZFS_MAX_DATASET_NAME_LEN];
        kmutex_t        zd_dirobj_lock;
        rll_t           zd_object_lock[ZTEST_OBJECT_LOCKS];
        zll_t           zd_range_lock[ZTEST_RANGE_LOCKS];
@@ -331,6 +334,7 @@ ztest_func_t ztest_split_pool;
 ztest_func_t ztest_reguid;
 ztest_func_t ztest_spa_upgrade;
 ztest_func_t ztest_fletcher;
+ztest_func_t ztest_fletcher_incr;
 ztest_func_t ztest_verify_dnode_bt;
 
 uint64_t zopt_always = 0ULL * NANOSEC;         /* all the time */
@@ -378,6 +382,7 @@ ztest_info_t ztest_info[] = {
        ZTI_INIT(ztest_vdev_add_remove, 1, &ztest_opts.zo_vdevtime),
        ZTI_INIT(ztest_vdev_aux_add_remove, 1, &ztest_opts.zo_vdevtime),
        ZTI_INIT(ztest_fletcher, 1, &zopt_rarely),
+       ZTI_INIT(ztest_fletcher_incr, 1, &zopt_rarely),
        ZTI_INIT(ztest_verify_dnode_bt, 1, &zopt_sometimes),
 };
 
@@ -624,6 +629,8 @@ usage(boolean_t requested)
            "\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
            "\t[-P passtime (default: %llu sec)] time per pass\n"
            "\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
+           "\t[-o variable=value] ... set global variable to an unsigned\n"
+           "\t    32-bit integer value\n"
            "\t[-h] (print help)\n"
            "",
            zo->zo_pool,
@@ -659,7 +666,7 @@ process_options(int argc, char **argv)
        bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
 
        while ((opt = getopt(argc, argv,
-           "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
+           "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:o:")) != EOF) {
                value = 0;
                switch (opt) {
                case 'v':
@@ -726,6 +733,7 @@ process_options(int argc, char **argv)
                        } else {
                                (void) strlcpy(zo->zo_dir, path,
                                    sizeof (zo->zo_dir));
+                               free(path);
                        }
                        break;
                case 'V':
@@ -746,6 +754,10 @@ process_options(int argc, char **argv)
                case 'B':
                        (void) strlcpy(altdir, optarg, sizeof (altdir));
                        break;
+               case 'o':
+                       if (set_global_var(optarg) != 0)
+                               usage(B_FALSE);
+                       break;
                case 'h':
                        usage(B_TRUE);
                        break;
@@ -1125,9 +1137,8 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value,
 
                err = zfs_prop_index_to_string(prop, curval, &valname);
                if (err)
-                       (void) printf("%s %s = %llu at '%s'\n",
-                           osname, propname, (unsigned long long)curval,
-                               setpoint);
+                       (void) printf("%s %s = %llu at '%s'\n", osname,
+                           propname, (unsigned long long)curval, setpoint);
                else
                        (void) printf("%s %s = %s at '%s'\n",
                            osname, propname, valname, setpoint);
@@ -3494,9 +3505,12 @@ ztest_objset_destroy_cb(const char *name, void *arg)
         * Destroy the dataset.
         */
        if (strchr(name, '@') != NULL) {
-               VERIFY0(dsl_destroy_snapshot(name, B_FALSE));
+               VERIFY0(dsl_destroy_snapshot(name, B_TRUE));
        } else {
-               VERIFY0(dsl_destroy_head(name));
+               error = dsl_destroy_head(name);
+               /* There could be a hold on this dataset */
+               if (error != EBUSY)
+                       ASSERT0(error);
        }
        return (0);
 }
@@ -3504,7 +3518,7 @@ ztest_objset_destroy_cb(const char *name, void *arg)
 static boolean_t
 ztest_snapshot_create(char *osname, uint64_t id)
 {
-       char snapname[MAXNAMELEN];
+       char snapname[ZFS_MAX_DATASET_NAME_LEN];
        int error;
 
        (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id);
@@ -3524,10 +3538,10 @@ ztest_snapshot_create(char *osname, uint64_t id)
 static boolean_t
 ztest_snapshot_destroy(char *osname, uint64_t id)
 {
-       char snapname[MAXNAMELEN];
+       char snapname[ZFS_MAX_DATASET_NAME_LEN];
        int error;
 
-       (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname,
+       (void) snprintf(snapname, sizeof (snapname), "%s@%llu", osname,
            (u_longlong_t)id);
 
        error = dsl_destroy_snapshot(snapname, B_FALSE);
@@ -3544,16 +3558,15 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
        int iters;
        int error;
        objset_t *os, *os2;
-       char *name;
+       char name[ZFS_MAX_DATASET_NAME_LEN];
        zilog_t *zilog;
        int i;
 
        zdtmp = umem_alloc(sizeof (ztest_ds_t), UMEM_NOFAIL);
-       name = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
 
        (void) rw_rdlock(&ztest_name_lock);
 
-       (void) snprintf(name, MAXNAMELEN, "%s/temp_%llu",
+       (void) snprintf(name, sizeof (name), "%s/temp_%llu",
            ztest_opts.zo_pool, (u_longlong_t)id);
 
        /*
@@ -3639,7 +3652,6 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
 out:
        (void) rw_unlock(&ztest_name_lock);
 
-       umem_free(name, MAXNAMELEN);
        umem_free(zdtmp, sizeof (ztest_ds_t));
 }
 
@@ -3668,22 +3680,22 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id)
        char *snap3name;
        int error;
 
-       snap1name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       clone1name = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       snap2name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       clone2name = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       snap3name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-
-       (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu",
-           clone1name, (u_longlong_t)id);
-       (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu",
-           clone1name, (u_longlong_t)id);
+       snap1name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       clone1name = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       snap2name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       clone2name = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       snap3name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+
+       (void) snprintf(snap1name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s1_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(clone1name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s/c1_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(snap2name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s2_%llu", clone1name, (u_longlong_t)id);
+       (void) snprintf(clone2name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s/c2_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(snap3name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s3_%llu", clone1name, (u_longlong_t)id);
 
        error = dsl_destroy_head(clone2name);
        if (error && error != ENOENT)
@@ -3701,11 +3713,11 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id)
        if (error && error != ENOENT)
                fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error);
 
-       umem_free(snap1name, MAXNAMELEN);
-       umem_free(clone1name, MAXNAMELEN);
-       umem_free(snap2name, MAXNAMELEN);
-       umem_free(clone2name, MAXNAMELEN);
-       umem_free(snap3name, MAXNAMELEN);
+       umem_free(snap1name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(clone1name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(snap2name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(clone2name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(snap3name, ZFS_MAX_DATASET_NAME_LEN);
 }
 
 /*
@@ -3723,26 +3735,26 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
        char *osname = zd->zd_name;
        int error;
 
-       snap1name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       clone1name = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       snap2name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       clone2name = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
-       snap3name  = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
+       snap1name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       clone1name = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       snap2name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       clone2name = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
+       snap3name  = umem_alloc(ZFS_MAX_DATASET_NAME_LEN, UMEM_NOFAIL);
 
        (void) rw_rdlock(&ztest_name_lock);
 
        ztest_dsl_dataset_cleanup(osname, id);
 
-       (void) snprintf(snap1name, MAXNAMELEN, "%s@s1_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(clone1name, MAXNAMELEN, "%s/c1_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(snap2name, MAXNAMELEN, "%s@s2_%llu",
-           clone1name, (u_longlong_t)id);
-       (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu",
-           osname, (u_longlong_t)id);
-       (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu",
-           clone1name, (u_longlong_t)id);
+       (void) snprintf(snap1name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s1_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(clone1name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s/c1_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(snap2name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s2_%llu", clone1name, (u_longlong_t)id);
+       (void) snprintf(clone2name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s/c2_%llu", osname, (u_longlong_t)id);
+       (void) snprintf(snap3name, ZFS_MAX_DATASET_NAME_LEN,
+           "%s@s3_%llu", clone1name, (u_longlong_t)id);
 
        error = dmu_objset_snapshot_one(osname, strchr(snap1name, '@') + 1);
        if (error && error != EEXIST) {
@@ -3808,11 +3820,11 @@ out:
 
        (void) rw_unlock(&ztest_name_lock);
 
-       umem_free(snap1name, MAXNAMELEN);
-       umem_free(clone1name, MAXNAMELEN);
-       umem_free(snap2name, MAXNAMELEN);
-       umem_free(clone2name, MAXNAMELEN);
-       umem_free(snap3name, MAXNAMELEN);
+       umem_free(snap1name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(clone1name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(snap2name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(clone2name, ZFS_MAX_DATASET_NAME_LEN);
+       umem_free(snap3name, ZFS_MAX_DATASET_NAME_LEN);
 }
 
 #undef OD_ARRAY_SIZE
@@ -4475,7 +4487,7 @@ ztest_zap(ztest_ds_t *zd, uint64_t id)
        ztest_od_init(od, id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0, 0);
 
        if (ztest_object_init(zd, od, sizeof (ztest_od_t),
-                       !ztest_random(2)) != 0)
+           !ztest_random(2)) != 0)
                goto out;
 
        object = od->od_object;
@@ -4612,7 +4624,7 @@ ztest_fzap(ztest_ds_t *zd, uint64_t id)
        ztest_od_init(od, id, FTAG, 0, DMU_OT_ZAP_OTHER, 0, 0, 0);
 
        if (ztest_object_init(zd, od, sizeof (ztest_od_t),
-                               !ztest_random(2)) != 0)
+           !ztest_random(2)) != 0)
                goto out;
        object = od->od_object;
 
@@ -4622,7 +4634,7 @@ ztest_fzap(ztest_ds_t *zd, uint64_t id)
         * 2050 entries we should see ptrtbl growth and leaf-block split.
         */
        for (i = 0; i < 2050; i++) {
-               char name[MAXNAMELEN];
+               char name[ZFS_MAX_DATASET_NAME_LEN];
                uint64_t value = i;
                dmu_tx_t *tx;
                int error;
@@ -4704,8 +4716,10 @@ ztest_zap_parallel(ztest_ds_t *zd, uint64_t id)
                tx = dmu_tx_create(os);
                dmu_tx_hold_zap(tx, object, B_TRUE, NULL);
                txg = ztest_tx_assign(tx, TXG_MIGHTWAIT, FTAG);
-               if (txg == 0)
+               if (txg == 0) {
+                       umem_free(od, sizeof (ztest_od_t));
                        return;
+               }
                bcopy(name, string_value, namelen);
        } else {
                tx = NULL;
@@ -5077,7 +5091,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
        char fullname[100];
        char clonename[100];
        char tag[100];
-       char osname[MAXNAMELEN];
+       char osname[ZFS_MAX_DATASET_NAME_LEN];
        nvlist_t *holds;
 
        (void) rw_rdlock(&ztest_name_lock);
@@ -5206,7 +5220,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
        char *path0;
        char *pathrand;
        size_t fsize;
-       int bshift = SPA_MAXBLOCKSHIFT + 2;     /* don't scrog all labels */
+       int bshift = SPA_MAXBLOCKSHIFT + 2;
        int iters = 1000;
        int maxfaults;
        int mirror_save;
@@ -5399,7 +5413,29 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
                    (leaves << bshift) + (leaf << bshift) +
                    (ztest_random(1ULL << (bshift - 1)) & -8ULL);
 
-               if (offset >= fsize)
+               /*
+                * Only allow damage to the labels at one end of the vdev.
+                *
+                * If all labels are damaged, the device will be totally
+                * inaccessible, which will result in loss of data,
+                * because we also damage (parts of) the other side of
+                * the mirror/raidz.
+                *
+                * Additionally, we will always have both an even and an
+                * odd label, so that we can handle crashes in the
+                * middle of vdev_config_sync().
+                */
+               if ((leaf & 1) == 0 && offset < VDEV_LABEL_START_SIZE)
+                       continue;
+
+               /*
+                * The two end labels are stored at the "end" of the disk, but
+                * the end of the disk (vdev_psize) is aligned to
+                * sizeof (vdev_label_t).
+                */
+               uint64_t psize = P2ALIGN(fsize, sizeof (vdev_label_t));
+               if ((leaf & 1) == 1 &&
+                   offset + sizeof (bad) > psize - VDEV_LABEL_END_SIZE)
                        continue;
 
                mutex_enter(&ztest_vdev_lock);
@@ -5440,7 +5476,7 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
        enum zio_checksum checksum = spa_dedup_checksum(spa);
        dmu_buf_t *db;
        dmu_tx_t *tx;
-       void *buf;
+       abd_t *abd;
        blkptr_t blk;
        int copies = 2 * ZIO_DEDUPDITTO_MIN;
        int i;
@@ -5471,9 +5507,14 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
                return;
        }
 
+       dmu_objset_stats_t dds;
+       dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
+       dmu_objset_fast_stat(os, &dds);
+       dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
+
        object = od[0].od_object;
        blocksize = od[0].od_blocksize;
-       pattern = zs->zs_guid ^ dmu_objset_fsid_guid(os);
+       pattern = zs->zs_guid ^ dds.dds_guid;
 
        ASSERT(object != 0);
 
@@ -5521,14 +5562,14 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id)
         * Damage the block.  Dedup-ditto will save us when we read it later.
         */
        psize = BP_GET_PSIZE(&blk);
-       buf = zio_buf_alloc(psize);
-       ztest_pattern_set(buf, psize, ~pattern);
+       abd = abd_alloc_linear(psize, B_TRUE);
+       ztest_pattern_set(abd_to_buf(abd), psize, ~pattern);
 
        (void) zio_wait(zio_rewrite(NULL, spa, 0, &blk,
-           buf, psize, NULL, NULL, ZIO_PRIORITY_SYNC_WRITE,
+           abd, psize, NULL, NULL, ZIO_PRIORITY_SYNC_WRITE,
            ZIO_FLAG_CANFAIL | ZIO_FLAG_INDUCE_DAMAGE, NULL));
 
-       zio_buf_free(buf, psize);
+       abd_free(abd);
 
        (void) rw_unlock(&ztest_name_lock);
        umem_free(od, sizeof (ztest_od_t));
@@ -5652,16 +5693,16 @@ ztest_fletcher(ztest_ds_t *zd, uint64_t id)
                        *ptr = ztest_random(UINT_MAX);
 
                VERIFY0(fletcher_4_impl_set("scalar"));
-               fletcher_4_native(buf, size, &zc_ref);
-               fletcher_4_byteswap(buf, size, &zc_ref_byteswap);
+               fletcher_4_native(buf, size, NULL, &zc_ref);
+               fletcher_4_byteswap(buf, size, NULL, &zc_ref_byteswap);
 
                VERIFY0(fletcher_4_impl_set("cycle"));
                while (run_count-- > 0) {
                        zio_cksum_t zc;
                        zio_cksum_t zc_byteswap;
 
-                       fletcher_4_byteswap(buf, size, &zc_byteswap);
-                       fletcher_4_native(buf, size, &zc);
+                       fletcher_4_byteswap(buf, size, NULL, &zc_byteswap);
+                       fletcher_4_native(buf, size, NULL, &zc);
 
                        VERIFY0(bcmp(&zc, &zc_ref, sizeof (zc)));
                        VERIFY0(bcmp(&zc_byteswap, &zc_ref_byteswap,
@@ -5672,6 +5713,82 @@ ztest_fletcher(ztest_ds_t *zd, uint64_t id)
        }
 }
 
+void
+ztest_fletcher_incr(ztest_ds_t *zd, uint64_t id)
+{
+       void *buf;
+       size_t size;
+       int *ptr;
+       int i;
+       zio_cksum_t zc_ref;
+       zio_cksum_t zc_ref_bswap;
+
+       hrtime_t end = gethrtime() + NANOSEC;
+
+       while (gethrtime() <= end) {
+               int run_count = 100;
+
+               size = ztest_random_blocksize();
+               buf = umem_alloc(size, UMEM_NOFAIL);
+
+               for (i = 0, ptr = buf; i < size / sizeof (*ptr); i++, ptr++)
+                       *ptr = ztest_random(UINT_MAX);
+
+               VERIFY0(fletcher_4_impl_set("scalar"));
+               fletcher_4_native(buf, size, NULL, &zc_ref);
+               fletcher_4_byteswap(buf, size, NULL, &zc_ref_bswap);
+
+               VERIFY0(fletcher_4_impl_set("cycle"));
+
+               while (run_count-- > 0) {
+                       zio_cksum_t zc;
+                       zio_cksum_t zc_bswap;
+                       size_t pos = 0;
+
+                       ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
+                       ZIO_SET_CHECKSUM(&zc_bswap, 0, 0, 0, 0);
+
+                       while (pos < size) {
+                               size_t inc = 64 * ztest_random(size / 67);
+                               /* sometimes add few bytes to test non-simd */
+                               if (ztest_random(100) < 10)
+                                       inc += P2ALIGN(ztest_random(64),
+                                           sizeof (uint32_t));
+
+                               if (inc > (size - pos))
+                                       inc = size - pos;
+
+                               fletcher_4_incremental_native(buf + pos, inc,
+                                   &zc);
+                               fletcher_4_incremental_byteswap(buf + pos, inc,
+                                   &zc_bswap);
+
+                               pos += inc;
+                       }
+
+                       VERIFY3U(pos, ==, size);
+
+                       VERIFY(ZIO_CHECKSUM_EQUAL(zc, zc_ref));
+                       VERIFY(ZIO_CHECKSUM_EQUAL(zc_bswap, zc_ref_bswap));
+
+                       /*
+                        * verify if incremental on the whole buffer is
+                        * equivalent to non-incremental version
+                        */
+                       ZIO_SET_CHECKSUM(&zc, 0, 0, 0, 0);
+                       ZIO_SET_CHECKSUM(&zc_bswap, 0, 0, 0, 0);
+
+                       fletcher_4_incremental_native(buf, size, &zc);
+                       fletcher_4_incremental_byteswap(buf, size, &zc_bswap);
+
+                       VERIFY(ZIO_CHECKSUM_EQUAL(zc, zc_ref));
+                       VERIFY(ZIO_CHECKSUM_EQUAL(zc_bswap, zc_ref_bswap));
+               }
+
+               umem_free(buf, size);
+       }
+}
+
 static int
 ztest_check_path(char *path)
 {
@@ -5727,7 +5844,7 @@ ztest_run_zdb(char *pool)
        ztest_get_zdb_bin(bin, len);
 
        (void) sprintf(zdb,
-           "%s -bcc%s%s -d -U %s %s",
+           "%s -bcc%s%s -G -d -U %s %s",
            bin,
            ztest_opts.zo_verbose >= 3 ? "s" : "",
            ztest_opts.zo_verbose >= 4 ? "v" : "",
@@ -5879,6 +5996,18 @@ ztest_resume_thread(void *arg)
                if (spa_suspended(spa))
                        ztest_resume(spa);
                (void) poll(NULL, 0, 100);
+
+               /*
+                * Periodically change the zfs_compressed_arc_enabled setting.
+                */
+               if (ztest_random(10) == 0)
+                       zfs_compressed_arc_enabled = ztest_random(2);
+
+               /*
+                * Periodically change the zfs_abd_scatter_enabled setting.
+                */
+               if (ztest_random(10) == 0)
+                       zfs_abd_scatter_enabled = ztest_random(2);
        }
 
        thread_exit();
@@ -5964,13 +6093,13 @@ ztest_thread(void *arg)
 static void
 ztest_dataset_name(char *dsname, char *pool, int d)
 {
-       (void) snprintf(dsname, MAXNAMELEN, "%s/ds_%d", pool, d);
+       (void) snprintf(dsname, ZFS_MAX_DATASET_NAME_LEN, "%s/ds_%d", pool, d);
 }
 
 static void
 ztest_dataset_destroy(int d)
 {
-       char name[MAXNAMELEN];
+       char name[ZFS_MAX_DATASET_NAME_LEN];
        int t;
 
        ztest_dataset_name(name, ztest_opts.zo_pool, d);
@@ -6019,7 +6148,7 @@ ztest_dataset_open(int d)
        uint64_t committed_seq = ZTEST_GET_SHARED_DS(d)->zd_seq;
        objset_t *os;
        zilog_t *zilog;
-       char name[MAXNAMELEN];
+       char name[ZFS_MAX_DATASET_NAME_LEN];
        int error;
 
        ztest_dataset_name(name, ztest_opts.zo_pool, d);
@@ -6126,9 +6255,13 @@ ztest_run(ztest_shared_t *zs)
        metaslab_preload_limit = ztest_random(20) + 1;
        ztest_spa = spa;
 
+       dmu_objset_stats_t dds;
        VERIFY0(dmu_objset_own(ztest_opts.zo_pool,
            DMU_OST_ANY, B_TRUE, FTAG, &os));
-       zs->zs_guid = dmu_objset_fsid_guid(os);
+       dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
+       dmu_objset_fast_stat(os, &dds);
+       dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
+       zs->zs_guid = dds.dds_guid;
        dmu_objset_disown(os, FTAG);
 
        spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN;
@@ -6147,7 +6280,7 @@ ztest_run(ztest_shared_t *zs)
         * Create a thread to periodically resume suspended I/O.
         */
        VERIFY3P((resume_thread = zk_thread_create(NULL, 0,
-           (thread_func_t)ztest_resume_thread, spa, TS_RUN, NULL, 0, 0,
+           (thread_func_t)ztest_resume_thread, spa, 0, NULL, TS_RUN, 0,
            PTHREAD_CREATE_JOINABLE)), !=, NULL);
 
 #if 0
@@ -6195,12 +6328,15 @@ ztest_run(ztest_shared_t *zs)
                kthread_t *thread;
 
                if (t < ztest_opts.zo_datasets &&
-                   ztest_dataset_open(t) != 0)
+                   ztest_dataset_open(t) != 0) {
+                       umem_free(tid,
+                           ztest_opts.zo_threads * sizeof (kt_did_t));
                        return;
+               }
 
                VERIFY3P(thread = zk_thread_create(NULL, 0,
                    (thread_func_t)ztest_thread,
-                   (void *)(uintptr_t)t, TS_RUN, NULL, 0, 0,
+                   (void *)(uintptr_t)t, 0, NULL, TS_RUN, 0,
                    PTHREAD_CREATE_JOINABLE), !=, NULL);
                tid[t] = thread->t_tid;
        }
@@ -6256,8 +6392,8 @@ ztest_run(ztest_shared_t *zs)
         * different name.
         */
        if (ztest_random(2) == 0) {
-               char name[MAXNAMELEN];
-               (void) snprintf(name, MAXNAMELEN, "%s_import",
+               char name[ZFS_MAX_DATASET_NAME_LEN];
+               (void) snprintf(name, sizeof (name), "%s_import",
                    ztest_opts.zo_pool);
                ztest_spa_import_export(ztest_opts.zo_pool, name);
                ztest_spa_import_export(name, ztest_opts.zo_pool);
@@ -6834,7 +6970,7 @@ main(int argc, char **argv)
                if (spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0) {
                        spa_close(spa, FTAG);
                } else {
-                       char tmpname[MAXNAMELEN];
+                       char tmpname[ZFS_MAX_DATASET_NAME_LEN];
                        kernel_fini();
                        kernel_init(FREAD | FWRITE);
                        (void) snprintf(tmpname, sizeof (tmpname), "%s_tmp",