diff options
Diffstat (limited to 'cmd/ztest')
-rw-r--r-- | cmd/ztest/ztest.c | 196 |
1 files changed, 111 insertions, 85 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 28570a090..e192ab17a 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -106,10 +106,12 @@ #include <sys/metaslab_impl.h> #include <sys/dsl_prop.h> #include <sys/dsl_dataset.h> +#include <sys/dsl_destroy.h> #include <sys/dsl_scan.h> #include <sys/zio_checksum.h> #include <sys/refcount.h> #include <sys/zfeature.h> +#include <sys/dsl_userhold.h> #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> @@ -367,7 +369,7 @@ ztest_info_t ztest_info[] = { { ztest_scrub, 1, &zopt_rarely }, { ztest_spa_upgrade, 1, &zopt_rarely }, { ztest_dsl_dataset_promote_busy, 1, &zopt_rarely }, - { ztest_vdev_attach_detach, 1, &zopt_rarely }, + { ztest_vdev_attach_detach, 1, &zopt_sometimes }, { ztest_vdev_LUN_growth, 1, &zopt_rarely }, { ztest_vdev_add_remove, 1, &ztest_opts.zo_vdevtime }, @@ -1031,9 +1033,8 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value, uint64_t curval; int error; - error = dsl_prop_set(osname, propname, - (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), - sizeof (value), 1, &value); + error = dsl_prop_set_int(osname, propname, + (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), value); if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -1042,8 +1043,7 @@ ztest_dsl_prop_set_uint64(char *osname, zfs_prop_t prop, uint64_t value, ASSERT0(error); setpoint = umem_alloc(MAXPATHLEN, UMEM_NOFAIL); - VERIFY3U(dsl_prop_get(osname, propname, sizeof (curval), - 1, &curval, setpoint), ==, 0); + VERIFY0(dsl_prop_get_integer(osname, propname, &curval, setpoint)); if (ztest_opts.zo_verbose >= 6) { VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0); @@ -2484,8 +2484,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id) int error; mutex_enter(&ztest_vdev_lock); - leaves = - MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz; + leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz; spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); @@ -2507,7 +2506,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id) * prevent a race between removing a slog (dmu_objset_find) * and destroying a dataset. Removing the slog will * grab a reference on the dataset which may cause - * dmu_objset_destroy() to fail with EBUSY thus + * dsl_destroy_head() to fail with EBUSY thus * leaving the dataset in an inconsistent state. */ rw_enter(&ztest_name_lock, RW_WRITER); @@ -3196,7 +3195,7 @@ ztest_objset_destroy_cb(const char *name, void *arg) /* * Verify that the dataset contains a directory object. */ - VERIFY3U(0, ==, dmu_objset_hold(name, FTAG, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, FTAG, &os)); error = dmu_object_info(os, ZTEST_DIROBJ, &doi); if (error != ENOENT) { /* We could have crashed in the middle of destroying it */ @@ -3204,12 +3203,16 @@ ztest_objset_destroy_cb(const char *name, void *arg) ASSERT3U(doi.doi_type, ==, DMU_OT_ZAP_OTHER); ASSERT3S(doi.doi_physical_blocks_512, >=, 0); } - dmu_objset_rele(os, FTAG); + dmu_objset_disown(os, FTAG); /* * Destroy the dataset. */ - VERIFY3U(0, ==, dmu_objset_destroy(name, B_FALSE)); + if (strchr(name, '@') != NULL) { + VERIFY0(dsl_destroy_snapshot(name, B_FALSE)); + } else { + VERIFY0(dsl_destroy_head(name)); + } return (0); } @@ -3219,16 +3222,17 @@ ztest_snapshot_create(char *osname, uint64_t id) char snapname[MAXNAMELEN]; int error; - (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname, - (u_longlong_t)id); + (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id); - error = dmu_objset_snapshot_one(osname, strchr(snapname, '@') + 1); + error = dmu_objset_snapshot_one(osname, snapname); if (error == ENOSPC) { ztest_record_enospc(FTAG); return (B_FALSE); } - if (error != 0 && error != EEXIST) - fatal(0, "ztest_snapshot_create(%s) = %d", snapname, error); + if (error != 0 && error != EEXIST) { + fatal(0, "ztest_snapshot_create(%s@%s) = %d", osname, + snapname, error); + } return (B_TRUE); } @@ -3241,7 +3245,7 @@ ztest_snapshot_destroy(char *osname, uint64_t id) (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname, (u_longlong_t)id); - error = dmu_objset_destroy(snapname, B_FALSE); + error = dsl_destroy_snapshot(snapname, B_FALSE); if (error != 0 && error != ENOENT) fatal(0, "ztest_snapshot_destroy(%s) = %d", snapname, error); return (B_TRUE); @@ -3269,7 +3273,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id) /* * If this dataset exists from a previous run, process its replay log - * half of the time. If we don't replay it, then dmu_objset_destroy() + * half of the time. If we don't replay it, then dsl_destroy_head() * (invoked from ztest_objset_destroy_cb()) should just throw it away. */ if (ztest_random(2) == 0 && @@ -3291,7 +3295,8 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id) /* * Verify that the destroyed dataset is no longer in the namespace. */ - VERIFY3U(ENOENT, ==, dmu_objset_hold(name, FTAG, &os)); + VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, + FTAG, &os)); /* * Verify that we can create a new dataset. @@ -3305,8 +3310,7 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_objset_create(%s) = %d", name, error); } - VERIFY3U(0, ==, - dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os)); ztest_zd_init(zdtmp, NULL, os); @@ -3396,21 +3400,21 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id) (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, (u_longlong_t)id); - error = dmu_objset_destroy(clone2name, B_FALSE); + error = dsl_destroy_head(clone2name); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", clone2name, error); - error = dmu_objset_destroy(snap3name, B_FALSE); + fatal(0, "dsl_destroy_head(%s) = %d", clone2name, error); + error = dsl_destroy_snapshot(snap3name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap3name, error); - error = dmu_objset_destroy(snap2name, B_FALSE); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap3name, error); + error = dsl_destroy_snapshot(snap2name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap2name, error); - error = dmu_objset_destroy(clone1name, B_FALSE); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap2name, error); + error = dsl_destroy_head(clone1name); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", clone1name, error); - error = dmu_objset_destroy(snap1name, B_FALSE); + fatal(0, "dsl_destroy_head(%s) = %d", clone1name, error); + error = dsl_destroy_snapshot(snap1name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap1name, error); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error); umem_free(snap1name, MAXNAMELEN); umem_free(clone1name, MAXNAMELEN); @@ -3425,8 +3429,7 @@ ztest_dsl_dataset_cleanup(char *osname, uint64_t id) void ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) { - objset_t *clone; - dsl_dataset_t *ds; + objset_t *os; char *snap1name; char *clone1name; char *snap2name; @@ -3465,12 +3468,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error); } - error = dmu_objset_hold(snap1name, FTAG, &clone); - if (error) - fatal(0, "dmu_open_snapshot(%s) = %d", snap1name, error); - - error = dmu_objset_clone(clone1name, dmu_objset_ds(clone), 0); - dmu_objset_rele(clone, FTAG); + error = dmu_objset_clone(clone1name, snap1name); if (error) { if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -3497,12 +3495,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); } - error = dmu_objset_hold(snap3name, FTAG, &clone); - if (error) - fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); - - error = dmu_objset_clone(clone2name, dmu_objset_ds(clone), 0); - dmu_objset_rele(clone, FTAG); + error = dmu_objset_clone(clone2name, snap3name); if (error) { if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -3511,14 +3504,14 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_objset_create(%s) = %d", clone2name, error); } - error = dsl_dataset_own(snap2name, B_FALSE, FTAG, &ds); + error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, FTAG, &os); if (error) - fatal(0, "dsl_dataset_own(%s) = %d", snap2name, error); + fatal(0, "dmu_objset_own(%s) = %d", snap2name, error); error = dsl_dataset_promote(clone2name, NULL); if (error != EBUSY) fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name, error); - dsl_dataset_disown(ds, FTAG); + dmu_objset_disown(os, FTAG); out: ztest_dsl_dataset_cleanup(osname, id); @@ -4392,7 +4385,7 @@ ztest_zap_parallel(ztest_ds_t *zd, uint64_t id) } count = -1ULL; - VERIFY(zap_count(os, object, &count) == 0); + VERIFY0(zap_count(os, object, &count)); ASSERT(count != -1ULL); /* @@ -4710,6 +4703,22 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, uint64_t id) (void) rw_exit(&ztest_name_lock); } +static int +user_release_one(const char *snapname, const char *holdname) +{ + nvlist_t *snaps, *holds; + int error; + + snaps = fnvlist_alloc(); + holds = fnvlist_alloc(); + fnvlist_add_boolean(holds, holdname); + fnvlist_add_nvlist(snaps, snapname, holds); + fnvlist_free(holds); + error = dsl_dataset_user_release(snaps, NULL); + fnvlist_free(snaps); + return (error); +} + /* * Test snapshot hold/release and deferred destroy. */ @@ -4724,22 +4733,30 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id) char clonename[100]; char tag[100]; char osname[MAXNAMELEN]; + nvlist_t *holds; (void) rw_enter(&ztest_name_lock, RW_READER); dmu_objset_name(os, osname); - (void) snprintf(snapname, 100, "sh1_%llu", (u_longlong_t)id); - (void) snprintf(fullname, 100, "%s@%s", osname, snapname); - (void) snprintf(clonename, 100, "%s/ch1_%llu",osname,(u_longlong_t)id); - (void) snprintf(tag, 100, "tag_%llu", (u_longlong_t)id); + (void) snprintf(snapname, sizeof (snapname), "sh1_%llu", (long long unsigned int)id); + (void) snprintf(fullname, sizeof (fullname), "%s@%s", osname, snapname); + (void) snprintf(clonename, sizeof (clonename), + "%s/ch1_%llu", osname, (long long unsigned int)id); + (void) snprintf(tag, sizeof (tag), "tag_%llu", (long long unsigned int)id); /* * Clean up from any previous run. */ - (void) dmu_objset_destroy(clonename, B_FALSE); - (void) dsl_dataset_user_release(osname, snapname, tag, B_FALSE); - (void) dmu_objset_destroy(fullname, B_FALSE); + error = dsl_destroy_head(clonename); + if (error != ENOENT) + ASSERT0(error); + error = user_release_one(fullname, tag); + if (error != ESRCH && error != ENOENT) + ASSERT0(error); + error = dsl_destroy_snapshot(fullname, B_FALSE); + if (error != ENOENT) + ASSERT0(error); /* * Create snapshot, clone it, mark snap for deferred destroy, @@ -4754,12 +4771,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error); } - error = dmu_objset_hold(fullname, FTAG, &origin); - if (error) - fatal(0, "dmu_objset_hold(%s) = %d", fullname, error); - - error = dmu_objset_clone(clonename, dmu_objset_ds(origin), 0); - dmu_objset_rele(origin, FTAG); + error = dmu_objset_clone(clonename, fullname); if (error) { if (error == ENOSPC) { ztest_record_enospc("dmu_objset_clone"); @@ -4768,15 +4780,15 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_objset_clone(%s) = %d", clonename, error); } - error = dmu_objset_destroy(fullname, B_TRUE); + error = dsl_destroy_snapshot(fullname, B_TRUE); if (error) { - fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d", fullname, error); } - error = dmu_objset_destroy(clonename, B_FALSE); + error = dsl_destroy_head(clonename); if (error) - fatal(0, "dmu_objset_destroy(%s) = %d", clonename, error); + fatal(0, "dsl_destroy_head(%s) = %d", clonename, error); error = dmu_objset_hold(fullname, FTAG, &origin); if (error != ENOENT) @@ -4796,28 +4808,31 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id) fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error); } - error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE, - B_TRUE, -1); + holds = fnvlist_alloc(); + fnvlist_add_string(holds, fullname, tag); + error = dsl_dataset_user_hold(holds, 0, NULL); + fnvlist_free(holds); + if (error) fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag); - error = dmu_objset_destroy(fullname, B_FALSE); + error = dsl_destroy_snapshot(fullname, B_FALSE); if (error != EBUSY) { - fatal(0, "dmu_objset_destroy(%s, B_FALSE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_FALSE) = %d", fullname, error); } - error = dmu_objset_destroy(fullname, B_TRUE); + error = dsl_destroy_snapshot(fullname, B_TRUE); if (error) { - fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d", fullname, error); } - error = dsl_dataset_user_release(osname, snapname, tag, B_FALSE); + error = user_release_one(fullname, tag); if (error) - fatal(0, "dsl_dataset_user_release(%s)", fullname, tag); + fatal(0, "user_release_one(%s)", fullname, tag); - VERIFY(dmu_objset_hold(fullname, FTAG, &origin) == ENOENT); + VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT); out: (void) rw_exit(&ztest_name_lock); @@ -4947,7 +4962,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id) * prevent a race between offlining a slog and * destroying a dataset. Offlining the slog will * grab a reference on the dataset which may cause - * dmu_objset_destroy() to fail with EBUSY thus + * dsl_destroy_head() to fail with EBUSY thus * leaving the dataset in an inconsistent state. */ if (islog) @@ -5084,8 +5099,12 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_t id) */ for (i = 0; i < copies; i++) { uint64_t offset = i * blocksize; - VERIFY(dmu_buf_hold(os, object, offset, FTAG, &db, - DMU_READ_NO_PREFETCH) == 0); + int error = dmu_buf_hold(os, object, offset, FTAG, &db, + DMU_READ_NO_PREFETCH); + if (error != 0) { + fatal(B_FALSE, "dmu_buf_hold(%p, %llu, %llu) = %u", + os, (long long)object, (long long) offset, error); + } ASSERT(db->db_offset == offset); ASSERT(db->db_size == blocksize); ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) || @@ -5300,6 +5319,7 @@ ztest_spa_import_export(char *oldname, char *newname) nvlist_t *config, *newconfig; uint64_t pool_guid; spa_t *spa; + int error; if (ztest_opts.zo_verbose >= 4) { (void) printf("import/export: old = %s, new = %s\n", @@ -5344,7 +5364,12 @@ ztest_spa_import_export(char *oldname, char *newname) /* * Import it under the new name. */ - VERIFY3U(0, ==, spa_import(newname, config, NULL, 0)); + error = spa_import(newname, config, NULL, 0); + if (error != 0) { + dump_nvlist(config, 0); + fatal(B_FALSE, "couldn't import pool %s as %s: error %u", + oldname, newname, error); + } ztest_walk_pool_directory("pools after import"); @@ -5551,7 +5576,7 @@ ztest_dataset_open(int d) } ASSERT(error == 0 || error == EEXIST); - VERIFY0(dmu_objset_hold(name, zd, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os)); (void) rw_exit(&ztest_name_lock); ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os); @@ -5592,7 +5617,7 @@ ztest_dataset_close(int d) ztest_ds_t *zd = &ztest_ds[d]; zil_close(zd->zd_zilog); - dmu_objset_rele(zd->zd_os, zd); + dmu_objset_disown(zd->zd_os, zd); ztest_zd_fini(zd); } @@ -5638,13 +5663,14 @@ ztest_run(ztest_shared_t *zs) * Open our pool. */ kernel_init(FREAD | FWRITE); - VERIFY(spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0); + VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG)); spa->spa_debug = B_TRUE; ztest_spa = spa; - VERIFY3U(0, ==, dmu_objset_hold(ztest_opts.zo_pool, FTAG, &os)); + VERIFY0(dmu_objset_own(ztest_opts.zo_pool, + DMU_OST_ANY, B_TRUE, FTAG, &os)); zs->zs_guid = dmu_objset_fsid_guid(os); - dmu_objset_rele(os, FTAG); + dmu_objset_disown(os, FTAG); spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN; |