*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
*/
typedef struct ztest_ds {
objset_t *zd_os;
+ krwlock_t zd_zilog_lock;
zilog_t *zd_zilog;
uint64_t zd_seq;
ztest_od_t *zd_od; /* debugging aid */
ztest_func_t ztest_zap;
ztest_func_t ztest_zap_parallel;
ztest_func_t ztest_zil_commit;
+ztest_func_t ztest_zil_remount;
ztest_func_t ztest_dmu_read_write_zcopy;
ztest_func_t ztest_dmu_objset_create_destroy;
ztest_func_t ztest_dmu_prealloc;
ztest_func_t ztest_vdev_add_remove;
ztest_func_t ztest_vdev_aux_add_remove;
ztest_func_t ztest_split_pool;
+ztest_func_t ztest_reguid;
uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
{ ztest_zap_parallel, 100, &zopt_always },
{ ztest_split_pool, 1, &zopt_always },
{ ztest_zil_commit, 1, &zopt_incessant },
+ { ztest_zil_remount, 1, &zopt_sometimes },
{ ztest_dmu_read_write_zcopy, 1, &zopt_often },
{ ztest_dmu_objset_create_destroy, 1, &zopt_often },
{ ztest_dsl_prop_get_set, 1, &zopt_often },
{ ztest_fault_inject, 1, &zopt_sometimes },
{ ztest_ddt_repair, 1, &zopt_sometimes },
{ ztest_dmu_snapshot_hold, 1, &zopt_sometimes },
+ /*
+ * The reguid test is currently broken. Disable it until
+ * we get around to fixing it.
+ */
+#if 0
+ { ztest_reguid, 1, &zopt_sometimes },
+#endif
{ ztest_spa_rename, 1, &zopt_rarely },
{ ztest_scrub, 1, &zopt_rarely },
{ ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
uint64_t zs_vdev_aux;
uint64_t zs_alloc;
uint64_t zs_space;
+ uint64_t zs_guid;
kmutex_t zs_vdev_lock;
krwlock_t zs_name_lock;
ztest_info_t zs_info[ZTEST_FUNCS];
dmu_objset_name(os, zd->zd_name);
int l;
+ rw_init(&zd->zd_zilog_lock, NULL, RW_DEFAULT, NULL);
mutex_init(&zd->zd_dirobj_lock, NULL, MUTEX_DEFAULT, NULL);
for (l = 0; l < ZTEST_OBJECT_LOCKS; l++)
int l;
mutex_destroy(&zd->zd_dirobj_lock);
+ rw_destroy(&zd->zd_zilog_lock);
for (l = 0; l < ZTEST_OBJECT_LOCKS; l++)
ztest_rll_destroy(&zd->zd_object_lock[l]);
if (ztest_random(2) == 0)
io_type = ZTEST_IO_WRITE_TAG;
+ (void) rw_enter(&zd->zd_zilog_lock, RW_READER);
+
switch (io_type) {
case ZTEST_IO_WRITE_TAG:
break;
}
+ (void) rw_exit(&zd->zd_zilog_lock);
+
umem_free(data, blocksize);
}
{
zilog_t *zilog = zd->zd_zilog;
+ (void) rw_enter(&zd->zd_zilog_lock, RW_READER);
+
zil_commit(zilog, ztest_random(ZTEST_OBJECTS));
/*
ASSERT(zd->zd_seq <= zilog->zl_commit_lr_seq);
zd->zd_seq = zilog->zl_commit_lr_seq;
mutex_exit(&zilog->zl_lock);
+
+ (void) rw_exit(&zd->zd_zilog_lock);
+}
+
+/*
+ * This function is designed to simulate the operations that occur during a
+ * mount/unmount operation. We hold the dataset across these operations in an
+ * attempt to expose any implicit assumptions about ZIL management.
+ */
+/* ARGSUSED */
+void
+ztest_zil_remount(ztest_ds_t *zd, uint64_t id)
+{
+ objset_t *os = zd->zd_os;
+
+ (void) rw_enter(&zd->zd_zilog_lock, RW_WRITER);
+
+ /* zfs_sb_teardown() */
+ zil_close(zd->zd_zilog);
+
+ /* zfsvfs_setup() */
+ VERIFY(zil_open(os, ztest_get_data) == zd->zd_zilog);
+ zil_replay(os, zd, ztest_replay_vector);
+
+ (void) rw_exit(&zd->zd_zilog_lock);
}
/*
newvd_is_spare = B_TRUE;
(void) strcpy(newpath, newvd->vdev_path);
} else {
- (void) snprintf(newpath, sizeof (newpath), ztest_dev_template,
+ (void) snprintf(newpath, MAXPATHLEN, ztest_dev_template,
zopt_dir, zopt_pool, top * leaves + leaf);
if (ztest_random(2) == 0)
newpath[strlen(newpath) - 1] = 'b';
if (err || zilset < 80)
return (err);
- (void) printf("Setting dataset %s to sync always\n", dsname);
+ if (zopt_verbose >= 5)
+ (void) printf("Setting dataset %s to sync always\n", dsname);
return (ztest_dsl_prop_set_uint64(dsname, ZFS_PROP_SYNC,
ZFS_SYNC_ALWAYS, B_FALSE));
}
* write failures and random online/offline activity on leaf 0,
* and we'll write random garbage to the randomly chosen leaf.
*/
- (void) snprintf(path0, sizeof (path0), ztest_dev_template,
+ (void) snprintf(path0, MAXPATHLEN, ztest_dev_template,
zopt_dir, zopt_pool, top * leaves + zs->zs_splits);
- (void) snprintf(pathrand, sizeof (pathrand), ztest_dev_template,
+ (void) snprintf(pathrand, MAXPATHLEN, ztest_dev_template,
zopt_dir, zopt_pool, top * leaves + leaf);
vd0 = vdev_lookup_by_path(spa->spa_root_vdev, path0);
object = od[0].od_object;
blocksize = od[0].od_blocksize;
- pattern = spa_guid(spa) ^ dmu_objset_fsid_guid(os);
+ pattern = zs->zs_guid ^ dmu_objset_fsid_guid(os);
ASSERT(object != 0);
}
/*
+ * Change the guid for the pool.
+ */
+/* ARGSUSED */
+void
+ztest_reguid(ztest_ds_t *zd, uint64_t id)
+{
+ ztest_shared_t *zs = ztest_shared;
+ spa_t *spa = zs->zs_spa;
+ uint64_t orig, load;
+
+ orig = spa_guid(spa);
+ load = spa_load_guid(spa);
+ if (spa_change_guid(spa) != 0)
+ return;
+
+ if (zopt_verbose >= 3) {
+ (void) printf("Changed guid old %llu -> %llu\n",
+ (u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
+ }
+
+ VERIFY3U(orig, !=, spa_guid(spa));
+ VERIFY3U(load, ==, spa_load_guid(spa));
+}
+
+/*
* Rename the pool to a different name and then rename it back.
*/
/* ARGSUSED */
ztest_run_zdb(char *pool)
{
int status;
- char zdb[MAXPATHLEN + MAXNAMELEN + 20];
- char zbuf[1024];
char *bin;
- char *ztest;
- char *isa;
- int isalen;
+ char *zdb;
+ char *zbuf;
FILE *fp;
- (void) realpath(getexecname(), zdb);
+ bin = umem_alloc(MAXPATHLEN + MAXNAMELEN + 20, UMEM_NOFAIL);
+ zdb = umem_alloc(MAXPATHLEN + MAXNAMELEN + 20, UMEM_NOFAIL);
+ zbuf = umem_alloc(1024, UMEM_NOFAIL);
- /* zdb lives in /usr/sbin, while ztest lives in /usr/bin */
- bin = strstr(zdb, "/usr/bin/");
- ztest = strstr(bin, "/ztest");
- isa = bin + 8;
- isalen = ztest - isa;
- isa = strdup(isa);
- /* LINTED */
- (void) sprintf(bin,
- "/usr/sbin%.*s/zdb -bcc%s%s -U %s %s",
- isalen,
- isa,
+ VERIFY(realpath(getexecname(), bin) != NULL);
+ if (strncmp(bin, "/usr/sbin/ztest", 15) == 0) {
+ strcpy(bin, "/usr/sbin/zdb"); /* Installed */
+ } else if (strncmp(bin, "/sbin/ztest", 11) == 0) {
+ strcpy(bin, "/sbin/zdb"); /* Installed */
+ } else {
+ strstr(bin, "/ztest/")[0] = '\0'; /* In-tree */
+ strcat(bin, "/zdb/zdb");
+ }
+
+ (void) sprintf(zdb,
+ "%s -bcc%s%s -U %s %s",
+ bin,
zopt_verbose >= 3 ? "s" : "",
zopt_verbose >= 4 ? "v" : "",
spa_config_path,
pool);
- free(isa);
if (zopt_verbose >= 5)
(void) printf("Executing %s\n", strstr(zdb, "zdb "));
fp = popen(zdb, "r");
- while (fgets(zbuf, sizeof (zbuf), fp) != NULL)
+ while (fgets(zbuf, 1024, fp) != NULL)
if (zopt_verbose >= 3)
(void) printf("%s", zbuf);
status = pclose(fp);
if (status == 0)
- return;
+ goto out;
ztest_dump_core = 0;
if (WIFEXITED(status))
fatal(0, "'%s' exit code %d", zdb, WEXITSTATUS(status));
else
fatal(0, "'%s' died with signal %d", zdb, WTERMSIG(status));
+out:
+ umem_free(bin, MAXPATHLEN + MAXNAMELEN + 20);
+ umem_free(zdb, MAXPATHLEN + MAXNAMELEN + 20);
+ umem_free(zbuf, 1024);
}
static void
{
kt_did_t *tid;
spa_t *spa;
+ objset_t *os;
kthread_t *resume_thread;
uint64_t object;
int error;
*/
kernel_init(FREAD | FWRITE);
VERIFY(spa_open(zs->zs_pool, &spa, FTAG) == 0);
+ spa->spa_debug = B_TRUE;
zs->zs_spa = spa;
+ VERIFY3U(0, ==, dmu_objset_hold(zs->zs_pool, FTAG, &os));
+ zs->zs_guid = dmu_objset_fsid_guid(os);
+ dmu_objset_rele(os, FTAG);
+
spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN;
/*
/*
* Create a thread to periodically resume suspended I/O.
*/
- VERIFY3P((resume_thread = thread_create(NULL, 0, ztest_resume_thread,
- spa, TS_RUN, NULL, 0, 0)), !=, NULL);
+ VERIFY3P((resume_thread = zk_thread_create(NULL, 0,
+ (thread_func_t)ztest_resume_thread, spa, TS_RUN, NULL, 0, 0,
+ PTHREAD_CREATE_JOINABLE)), !=, NULL);
/*
* Set a deadman alarm to abort() if we hang.
if (t < zopt_datasets && ztest_dataset_open(zs, t) != 0)
return;
- VERIFY3P(thread = thread_create(NULL, 0, ztest_thread,
- (void *)(uintptr_t)t, TS_RUN, NULL, 0, 0), !=, NULL);
+ VERIFY3P(thread = zk_thread_create(NULL, 0,
+ (thread_func_t)ztest_thread,
+ (void *)(uintptr_t)t, TS_RUN, NULL, 0, 0,
+ PTHREAD_CREATE_JOINABLE), !=, NULL);
tid[t] = thread->t_tid;
}
kernel_fini();
list_destroy(&zcl.zcl_callbacks);
-
- (void) _mutex_destroy(&zcl.zcl_callbacks_lock);
-
- (void) rwlock_destroy(&zs->zs_name_lock);
- (void) _mutex_destroy(&zs->zs_vdev_lock);
+ mutex_destroy(&zcl.zcl_callbacks_lock);
+ rw_destroy(&zs->zs_name_lock);
+ mutex_destroy(&zs->zs_vdev_lock);
}
static void
ztest_random_fd = open("/dev/urandom", O_RDONLY);
+ dprintf_setup(&argc, argv);
process_options(argc, argv);
/* Override location of zpool.cache */