Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 May 2012 11:37:24 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r236143 - head/cddl/contrib/opensolaris/cmd/ztest
Message-ID:  <201205271137.q4RBbODF046203@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Sun May 27 11:37:24 2012
New Revision: 236143
URL: http://svn.freebsd.org/changeset/base/236143

Log:
  Import illumos changeset 13571:a5771a96228c
  1950 ztest backwards compatibility testing option
  
  References:
  https://www.illumos.org/issues/1950
  
  Obtained from:	illumos (issue #1950)
  MFC after:	2 weeks

Modified:
  head/cddl/contrib/opensolaris/cmd/ztest/ztest.c

Modified: head/cddl/contrib/opensolaris/cmd/ztest/ztest.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Sun May 27 10:32:10 2012	(r236142)
+++ head/cddl/contrib/opensolaris/cmd/ztest/ztest.c	Sun May 27 11:37:24 2012	(r236143)
@@ -20,8 +20,9 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>.  All rights reserved.
  */
 
 /*
@@ -51,7 +52,9 @@
  *     At random times, the child self-immolates with a SIGKILL.
  *     This is the software equivalent of pulling the power cord.
  *     The parent then runs the test again, using the existing
- *     storage pool, as many times as desired.
+ *     storage pool, as many times as desired. If backwards compatability
+ *     testing is enabled ztest will sometimes run the "older" version
+ *     of ztest after a SIGKILL.
  *
  * (6) To verify that we don't have future leaks or temporal incursions,
  *     many of the functional tests record the transaction group number
@@ -68,9 +71,15 @@
  * You can ask more more vdevs [-v], datasets [-d], or threads [-t]
  * to increase the pool capacity, fanout, and overall stress level.
  *
- * The -N(okill) option will suppress kills, so each child runs to completion.
- * This can be useful when you're trying to distinguish temporal incursions
- * from plain old race conditions.
+ * Use the -k option to set the desired frequency of kills.
+ *
+ * When ztest invokes itself it passes all relevant information through a
+ * temporary file which is mmap-ed in the child process. This allows shared
+ * memory to survive the exec syscall. The ztest_shared_hdr_t struct is always
+ * stored at offset 0 of this file and contains information on the size and
+ * number of shared structures in the file. The information stored in this file
+ * must remain backwards compatible with older versions of ztest so that
+ * ztest can invoke them during backwards compatibility testing (-B).
  */
 
 #include <sys/zfs_context.h>
@@ -111,29 +120,82 @@
 #include <sys/fs/zfs.h>
 #include <libnvpair.h>
 
-static char cmdname[] = "ztest";
-static char *zopt_pool = cmdname;
-static char *progname;
-
-static uint64_t zopt_vdevs = 5;
-static uint64_t zopt_vdevtime;
-static int zopt_ashift = SPA_MINBLOCKSHIFT;
-static int zopt_mirrors = 2;
-static int zopt_raidz = 4;
-static int zopt_raidz_parity = 1;
-static size_t zopt_vdev_size = SPA_MINDEVSIZE;
-static int zopt_datasets = 7;
-static int zopt_threads = 23;
-static uint64_t zopt_passtime = 60;	/* 60 seconds */
-static uint64_t zopt_killrate = 70;	/* 70% kill rate */
-static int zopt_verbose = 0;
-static int zopt_init = 1;
-static char *zopt_dir = "/tmp";
-static uint64_t zopt_time = 300;	/* 5 minutes */
-static uint64_t zopt_maxloops = 50;	/* max loops during spa_freeze() */
+#define	ZTEST_FD_DATA 3
+#define	ZTEST_FD_RAND 4
+
+typedef struct ztest_shared_hdr {
+	uint64_t	zh_hdr_size;
+	uint64_t	zh_opts_size;
+	uint64_t	zh_size;
+	uint64_t	zh_stats_size;
+	uint64_t	zh_stats_count;
+	uint64_t	zh_ds_size;
+	uint64_t	zh_ds_count;
+} ztest_shared_hdr_t;
+
+static ztest_shared_hdr_t *ztest_shared_hdr;
+
+typedef struct ztest_shared_opts {
+	char zo_pool[MAXNAMELEN];
+	char zo_dir[MAXNAMELEN];
+	char zo_alt_ztest[MAXNAMELEN];
+	char zo_alt_libpath[MAXNAMELEN];
+	uint64_t zo_vdevs;
+	uint64_t zo_vdevtime;
+	size_t zo_vdev_size;
+	int zo_ashift;
+	int zo_mirrors;
+	int zo_raidz;
+	int zo_raidz_parity;
+	int zo_datasets;
+	int zo_threads;
+	uint64_t zo_passtime;
+	uint64_t zo_killrate;
+	int zo_verbose;
+	int zo_init;
+	uint64_t zo_time;
+	uint64_t zo_maxloops;
+	uint64_t zo_metaslab_gang_bang;
+} ztest_shared_opts_t;
+
+static const ztest_shared_opts_t ztest_opts_defaults = {
+	.zo_pool = { 'z', 't', 'e', 's', 't', '\0' },
+	.zo_dir = { '/', 't', 'm', 'p', '\0' },
+	.zo_alt_ztest = { '\0' },
+	.zo_alt_libpath = { '\0' },
+	.zo_vdevs = 5,
+	.zo_ashift = SPA_MINBLOCKSHIFT,
+	.zo_mirrors = 2,
+	.zo_raidz = 4,
+	.zo_raidz_parity = 1,
+	.zo_vdev_size = SPA_MINDEVSIZE,
+	.zo_datasets = 7,
+	.zo_threads = 23,
+	.zo_passtime = 60,		/* 60 seconds */
+	.zo_killrate = 70,		/* 70% kill rate */
+	.zo_verbose = 0,
+	.zo_init = 1,
+	.zo_time = 300,			/* 5 minutes */
+	.zo_maxloops = 50,		/* max loops during spa_freeze() */
+	.zo_metaslab_gang_bang = 32 << 10
+};
+
+extern uint64_t metaslab_gang_bang;
+extern uint64_t metaslab_df_alloc_threshold;
+
+static ztest_shared_opts_t *ztest_shared_opts;
+static ztest_shared_opts_t ztest_opts;
+
+typedef struct ztest_shared_ds {
+	uint64_t	zd_seq;
+} ztest_shared_ds_t;
+
+static ztest_shared_ds_t *ztest_shared_ds;
+#define	ZTEST_GET_SHARED_DS(d) (&ztest_shared_ds[d])
 
 #define	BT_MAGIC	0x123456789abcdefULL
-#define	MAXFAULTS() (MAX(zs->zs_mirrors, 1) * (zopt_raidz_parity + 1) - 1)
+#define	MAXFAULTS() \
+	(MAX(zs->zs_mirrors, 1) * (ztest_opts.zo_raidz_parity + 1) - 1)
 
 enum ztest_io_type {
 	ZTEST_IO_WRITE_TAG,
@@ -205,10 +267,10 @@ typedef struct ztest_od {
  * Per-dataset state.
  */
 typedef struct ztest_ds {
+	ztest_shared_ds_t *zd_shared;
 	objset_t	*zd_os;
 	rwlock_t	zd_zilog_lock;
 	zilog_t		*zd_zilog;
-	uint64_t	zd_seq;
 	ztest_od_t	*zd_od;		/* debugging aid */
 	char		zd_name[MAXNAMELEN];
 	mutex_t		zd_dirobj_lock;
@@ -225,11 +287,17 @@ typedef struct ztest_info {
 	ztest_func_t	*zi_func;	/* test function */
 	uint64_t	zi_iters;	/* iterations per execution */
 	uint64_t	*zi_interval;	/* execute every <interval> seconds */
-	uint64_t	zi_call_count;	/* per-pass count */
-	uint64_t	zi_call_time;	/* per-pass time */
-	uint64_t	zi_call_next;	/* next time to call this function */
 } ztest_info_t;
 
+typedef struct ztest_shared_callstate {
+	uint64_t	zc_count;	/* per-pass count */
+	uint64_t	zc_time;	/* per-pass time */
+	uint64_t	zc_next;	/* next time to call this function */
+} ztest_shared_callstate_t;
+
+static ztest_shared_callstate_t *ztest_shared_callstate;
+#define	ZTEST_GET_SHARED_CALLSTATE(c) (&ztest_shared_callstate[c])
+
 /*
  * Note: these aren't static because we want dladdr() to work.
  */
@@ -297,8 +365,10 @@ ztest_info_t ztest_info[] = {
 	{ ztest_dsl_dataset_promote_busy,	1,	&zopt_rarely	},
 	{ ztest_vdev_attach_detach,		1,	&zopt_rarely },
 	{ ztest_vdev_LUN_growth,		1,	&zopt_rarely	},
-	{ ztest_vdev_add_remove,		1,	&zopt_vdevtime },
-	{ ztest_vdev_aux_add_remove,		1,	&zopt_vdevtime	},
+	{ ztest_vdev_add_remove,		1,
+	    &ztest_opts.zo_vdevtime				},
+	{ ztest_vdev_aux_add_remove,		1,
+	    &ztest_opts.zo_vdevtime				},
 };
 
 #define	ZTEST_FUNCS	(sizeof (ztest_info) / sizeof (ztest_info_t))
@@ -316,8 +386,7 @@ typedef struct ztest_cb_list {
  * Stuff we need to share writably between parent and child.
  */
 typedef struct ztest_shared {
-	char		*zs_pool;
-	spa_t		*zs_spa;
+	boolean_t	zs_do_init;
 	hrtime_t	zs_proc_start;
 	hrtime_t	zs_proc_stop;
 	hrtime_t	zs_thread_start;
@@ -328,13 +397,11 @@ typedef struct ztest_shared {
 	uint64_t	zs_vdev_aux;
 	uint64_t	zs_alloc;
 	uint64_t	zs_space;
-	uint64_t	zs_guid;
-	mutex_t		zs_vdev_lock;
-	rwlock_t	zs_name_lock;
-	ztest_info_t	zs_info[ZTEST_FUNCS];
 	uint64_t	zs_splits;
 	uint64_t	zs_mirrors;
-	ztest_ds_t	zs_zd[];
+	uint64_t	zs_metaslab_sz;
+	uint64_t	zs_metaslab_df_alloc_threshold;
+	uint64_t	zs_guid;
 } ztest_shared_t;
 
 #define	ID_PARALLEL	-1ULL
@@ -342,20 +409,19 @@ typedef struct ztest_shared {
 static char ztest_dev_template[] = "%s/%s.%llua";
 static char ztest_aux_template[] = "%s/%s.%s.%llu";
 ztest_shared_t *ztest_shared;
-uint64_t *ztest_seq;
 
-static int ztest_random_fd;
-static int ztest_dump_core = 1;
+static spa_t *ztest_spa = NULL;
+static ztest_ds_t *ztest_ds;
 
+static mutex_t ztest_vdev_lock;
+static rwlock_t ztest_name_lock;
+
+static boolean_t ztest_dump_core = B_TRUE;
 static boolean_t ztest_exiting;
 
 /* Global commit callback list */
 static ztest_cb_list_t zcl;
 
-extern uint64_t metaslab_gang_bang;
-extern uint64_t metaslab_df_alloc_threshold;
-static uint64_t metaslab_sz;
-
 enum ztest_object {
 	ZTEST_META_DNODE = 0,
 	ZTEST_DIROBJ,
@@ -468,12 +534,14 @@ nicenumtoull(const char *buf)
 static void
 usage(boolean_t requested)
 {
+	const ztest_shared_opts_t *zo = &ztest_opts_defaults;
+
 	char nice_vdev_size[10];
 	char nice_gang_bang[10];
 	FILE *fp = requested ? stdout : stderr;
 
-	nicenum(zopt_vdev_size, nice_vdev_size);
-	nicenum(metaslab_gang_bang, nice_gang_bang);
+	nicenum(zo->zo_vdev_size, nice_vdev_size);
+	nicenum(zo->zo_metaslab_gang_bang, nice_gang_bang);
 
 	(void) fprintf(fp, "Usage: %s\n"
 	    "\t[-v vdevs (default: %llu)]\n"
@@ -494,42 +562,43 @@ usage(boolean_t requested)
 	    "\t[-T time (default: %llu sec)] total run time\n"
 	    "\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[-h] (print help)\n"
 	    "",
-	    cmdname,
-	    (u_longlong_t)zopt_vdevs,			/* -v */
+	    zo->zo_pool,
+	    (u_longlong_t)zo->zo_vdevs,			/* -v */
 	    nice_vdev_size,				/* -s */
-	    zopt_ashift,				/* -a */
-	    zopt_mirrors,				/* -m */
-	    zopt_raidz,					/* -r */
-	    zopt_raidz_parity,				/* -R */
-	    zopt_datasets,				/* -d */
-	    zopt_threads,				/* -t */
+	    zo->zo_ashift,				/* -a */
+	    zo->zo_mirrors,				/* -m */
+	    zo->zo_raidz,				/* -r */
+	    zo->zo_raidz_parity,			/* -R */
+	    zo->zo_datasets,				/* -d */
+	    zo->zo_threads,				/* -t */
 	    nice_gang_bang,				/* -g */
-	    zopt_init,					/* -i */
-	    (u_longlong_t)zopt_killrate,		/* -k */
-	    zopt_pool,					/* -p */
-	    zopt_dir,					/* -f */
-	    (u_longlong_t)zopt_time,			/* -T */
-	    (u_longlong_t)zopt_maxloops,		/* -F */
-	    (u_longlong_t)zopt_passtime);		/* -P */
+	    zo->zo_init,				/* -i */
+	    (u_longlong_t)zo->zo_killrate,		/* -k */
+	    zo->zo_pool,				/* -p */
+	    zo->zo_dir,					/* -f */
+	    (u_longlong_t)zo->zo_time,			/* -T */
+	    (u_longlong_t)zo->zo_maxloops,		/* -F */
+	    (u_longlong_t)zo->zo_passtime);
 	exit(requested ? 0 : 1);
 }
 
 static void
 process_options(int argc, char **argv)
 {
+	char *path;
+	ztest_shared_opts_t *zo = &ztest_opts;
+
 	int opt;
 	uint64_t value;
+	char altdir[MAXNAMELEN] = { 0 };
 
-	/* Remember program name. */
-	progname = argv[0];
-
-	/* By default, test gang blocks for blocks 32K and greater */
-	metaslab_gang_bang = 32 << 10;
+	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:")) != EOF) {
+	    "v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
 		value = 0;
 		switch (opt) {
 		case 'v':
@@ -550,58 +619,71 @@ process_options(int argc, char **argv)
 		}
 		switch (opt) {
 		case 'v':
-			zopt_vdevs = value;
+			zo->zo_vdevs = value;
 			break;
 		case 's':
-			zopt_vdev_size = MAX(SPA_MINDEVSIZE, value);
+			zo->zo_vdev_size = MAX(SPA_MINDEVSIZE, value);
 			break;
 		case 'a':
-			zopt_ashift = value;
+			zo->zo_ashift = value;
 			break;
 		case 'm':
-			zopt_mirrors = value;
+			zo->zo_mirrors = value;
 			break;
 		case 'r':
-			zopt_raidz = MAX(1, value);
+			zo->zo_raidz = MAX(1, value);
 			break;
 		case 'R':
-			zopt_raidz_parity = MIN(MAX(value, 1), 3);
+			zo->zo_raidz_parity = MIN(MAX(value, 1), 3);
 			break;
 		case 'd':
-			zopt_datasets = MAX(1, value);
+			zo->zo_datasets = MAX(1, value);
 			break;
 		case 't':
-			zopt_threads = MAX(1, value);
+			zo->zo_threads = MAX(1, value);
 			break;
 		case 'g':
-			metaslab_gang_bang = MAX(SPA_MINBLOCKSIZE << 1, value);
+			zo->zo_metaslab_gang_bang = MAX(SPA_MINBLOCKSIZE << 1,
+			    value);
 			break;
 		case 'i':
-			zopt_init = value;
+			zo->zo_init = value;
 			break;
 		case 'k':
-			zopt_killrate = value;
+			zo->zo_killrate = value;
 			break;
 		case 'p':
-			zopt_pool = strdup(optarg);
+			(void) strlcpy(zo->zo_pool, optarg,
+			    sizeof (zo->zo_pool));
 			break;
 		case 'f':
-			zopt_dir = strdup(optarg);
+			path = realpath(optarg, NULL);
+			if (path == NULL) {
+				(void) fprintf(stderr, "error: %s: %s\n",
+				    optarg, strerror(errno));
+				usage(B_FALSE);
+			} else {
+				(void) strlcpy(zo->zo_dir, path,
+				    sizeof (zo->zo_dir));
+			}
 			break;
 		case 'V':
-			zopt_verbose++;
+			zo->zo_verbose++;
 			break;
 		case 'E':
-			zopt_init = 0;
+			zo->zo_init = 0;
 			break;
 		case 'T':
-			zopt_time = value;
+			zo->zo_time = value;
 			break;
 		case 'P':
-			zopt_passtime = MAX(1, value);
+			zo->zo_passtime = MAX(1, value);
 			break;
 		case 'F':
-			zopt_maxloops = MAX(1, value);
+			zo->zo_maxloops = MAX(1, value);
+			break;
+		case 'B':
+			(void) strlcpy(altdir, optarg, sizeof (altdir));
 			break;
 		case 'h':
 			usage(B_TRUE);
@@ -613,17 +695,59 @@ process_options(int argc, char **argv)
 		}
 	}
 
-	zopt_raidz_parity = MIN(zopt_raidz_parity, zopt_raidz - 1);
+	zo->zo_raidz_parity = MIN(zo->zo_raidz_parity, zo->zo_raidz - 1);
 
-	zopt_vdevtime = (zopt_vdevs > 0 ? zopt_time * NANOSEC / zopt_vdevs :
+	zo->zo_vdevtime =
+	    (zo->zo_vdevs > 0 ? zo->zo_time * NANOSEC / zo->zo_vdevs :
 	    UINT64_MAX >> 2);
+
+	if (strlen(altdir) > 0) {
+		char cmd[MAXNAMELEN];
+		char realaltdir[MAXNAMELEN];
+		char *bin;
+		char *ztest;
+		char *isa;
+		int isalen;
+
+		(void) realpath(getexecname(), cmd);
+		if (0 != access(altdir, F_OK)) {
+			ztest_dump_core = B_FALSE;
+			fatal(B_TRUE, "invalid alternate ztest path: %s",
+			    altdir);
+		}
+		VERIFY(NULL != realpath(altdir, realaltdir));
+
+		/*
+		 * 'cmd' should be of the form "<anything>/usr/bin/<isa>/ztest".
+		 * We want to extract <isa> to determine if we should use
+		 * 32 or 64 bit binaries.
+		 */
+		bin = strstr(cmd, "/usr/bin/");
+		ztest = strstr(bin, "/ztest");
+		isa = bin + 9;
+		isalen = ztest - isa;
+		(void) snprintf(zo->zo_alt_ztest, sizeof (zo->zo_alt_ztest),
+		    "%s/usr/bin/%.*s/ztest", realaltdir, isalen, isa);
+		(void) snprintf(zo->zo_alt_libpath, sizeof (zo->zo_alt_libpath),
+		    "%s/usr/lib/%.*s", realaltdir, isalen, isa);
+
+		if (0 != access(zo->zo_alt_ztest, X_OK)) {
+			ztest_dump_core = B_FALSE;
+			fatal(B_TRUE, "invalid alternate ztest: %s",
+			    zo->zo_alt_ztest);
+		} else if (0 != access(zo->zo_alt_libpath, X_OK)) {
+			ztest_dump_core = B_FALSE;
+			fatal(B_TRUE, "invalid alternate lib directory %s",
+			    zo->zo_alt_libpath);
+		}
+	}
 }
 
 static void
 ztest_kill(ztest_shared_t *zs)
 {
-	zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(zs->zs_spa));
-	zs->zs_space = metaslab_class_get_space(spa_normal_class(zs->zs_spa));
+	zs->zs_alloc = metaslab_class_get_alloc(spa_normal_class(ztest_spa));
+	zs->zs_space = metaslab_class_get_space(spa_normal_class(ztest_spa));
 	(void) kill(getpid(), SIGKILL);
 }
 
@@ -635,7 +759,7 @@ ztest_random(uint64_t range)
 	if (range == 0)
 		return (0);
 
-	if (read(ztest_random_fd, &r, sizeof (r)) != sizeof (r))
+	if (read(ZTEST_FD_RAND, &r, sizeof (r)) != sizeof (r))
 		fatal(1, "short read from /dev/urandom");
 
 	return (r % range);
@@ -651,9 +775,9 @@ ztest_record_enospc(const char *s)
 static uint64_t
 ztest_get_ashift(void)
 {
-	if (zopt_ashift == 0)
+	if (ztest_opts.zo_ashift == 0)
 		return (SPA_MINBLOCKSHIFT + ztest_random(3));
-	return (zopt_ashift);
+	return (ztest_opts.zo_ashift);
 }
 
 static nvlist_t *
@@ -671,12 +795,14 @@ make_vdev_file(char *path, char *aux, si
 
 		if (aux != NULL) {
 			vdev = ztest_shared->zs_vdev_aux;
-			(void) sprintf(path, ztest_aux_template,
-			    zopt_dir, zopt_pool, aux, vdev);
+			(void) snprintf(path, sizeof (pathbuf),
+			    ztest_aux_template, ztest_opts.zo_dir,
+			    ztest_opts.zo_pool, aux, vdev);
 		} else {
 			vdev = ztest_shared->zs_vdev_next_leaf++;
-			(void) sprintf(path, ztest_dev_template,
-			    zopt_dir, zopt_pool, vdev);
+			(void) snprintf(path, sizeof (pathbuf),
+			    ztest_dev_template, ztest_opts.zo_dir,
+			    ztest_opts.zo_pool, vdev);
 		}
 	}
 
@@ -714,7 +840,7 @@ make_vdev_raidz(char *path, char *aux, s
 	VERIFY(nvlist_add_string(raidz, ZPOOL_CONFIG_TYPE,
 	    VDEV_TYPE_RAIDZ) == 0);
 	VERIFY(nvlist_add_uint64(raidz, ZPOOL_CONFIG_NPARITY,
-	    zopt_raidz_parity) == 0);
+	    ztest_opts.zo_raidz_parity) == 0);
 	VERIFY(nvlist_add_nvlist_array(raidz, ZPOOL_CONFIG_CHILDREN,
 	    child, r) == 0);
 
@@ -852,7 +978,7 @@ ztest_dsl_prop_set_uint64(char *osname, 
 	VERIFY3U(dsl_prop_get(osname, propname, sizeof (curval),
 	    1, &curval, setpoint), ==, 0);
 
-	if (zopt_verbose >= 6) {
+	if (ztest_opts.zo_verbose >= 6) {
 		VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0);
 		(void) printf("%s %s = %s at '%s'\n",
 		    osname, propname, valname, setpoint);
@@ -862,9 +988,9 @@ ztest_dsl_prop_set_uint64(char *osname, 
 }
 
 static int
-ztest_spa_prop_set_uint64(ztest_shared_t *zs, zpool_prop_t prop, uint64_t value)
+ztest_spa_prop_set_uint64(zpool_prop_t prop, uint64_t value)
 {
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	nvlist_t *props = NULL;
 	int error;
 
@@ -986,13 +1112,16 @@ ztest_range_unlock(rl_t *rl)
 }
 
 static void
-ztest_zd_init(ztest_ds_t *zd, objset_t *os)
+ztest_zd_init(ztest_ds_t *zd, ztest_shared_ds_t *szd, objset_t *os)
 {
 	zd->zd_os = os;
 	zd->zd_zilog = dmu_objset_zil(os);
-	zd->zd_seq = 0;
+	zd->zd_shared = szd;
 	dmu_objset_name(os, zd->zd_name);
 
+	if (zd->zd_shared != NULL)
+		zd->zd_shared->zd_seq = 0;
+
 	VERIFY(rwlock_init(&zd->zd_zilog_lock, USYNC_THREAD, NULL) == 0);
 	VERIFY(_mutex_init(&zd->zd_dirobj_lock, USYNC_THREAD, NULL) == 0);
 
@@ -2076,8 +2205,9 @@ ztest_zil_commit(ztest_ds_t *zd, uint64_
 	 * will verify that the log really does contain this record.
 	 */
 	mutex_enter(&zilog->zl_lock);
-	ASSERT(zd->zd_seq <= zilog->zl_commit_lr_seq);
-	zd->zd_seq = zilog->zl_commit_lr_seq;
+	ASSERT(zd->zd_shared != NULL);
+	ASSERT3U(zd->zd_shared->zd_seq, <=, zilog->zl_commit_lr_seq);
+	zd->zd_shared->zd_seq = zilog->zl_commit_lr_seq;
 	mutex_exit(&zilog->zl_lock);
 
 	(void) rw_unlock(&zd->zd_zilog_lock);
@@ -2114,7 +2244,7 @@ ztest_zil_remount(ztest_ds_t *zd, uint64
 void
 ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
 {
-	ztest_shared_t *zs = ztest_shared;
+	ztest_shared_opts_t *zo = &ztest_opts;
 	spa_t *spa;
 	nvlist_t *nvroot;
 
@@ -2138,15 +2268,15 @@ ztest_spa_create_destroy(ztest_ds_t *zd,
 	 * Attempt to create an existing pool.  It shouldn't matter
 	 * what's in the nvroot; we should fail with EEXIST.
 	 */
-	(void) rw_rdlock(&zs->zs_name_lock);
+	(void) rw_rdlock(&ztest_name_lock);
 	nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1);
-	VERIFY3U(EEXIST, ==, spa_create(zs->zs_pool, nvroot, NULL, NULL, NULL));
+	VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
 	nvlist_free(nvroot);
-	VERIFY3U(0, ==, spa_open(zs->zs_pool, &spa, FTAG));
-	VERIFY3U(EBUSY, ==, spa_destroy(zs->zs_pool));
+	VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
+	VERIFY3U(EBUSY, ==, spa_destroy(zo->zo_pool));
 	spa_close(spa, FTAG);
 
-	(void) rw_unlock(&zs->zs_name_lock);
+	(void) rw_unlock(&ztest_name_lock);
 }
 
 static vdev_t *
@@ -2193,14 +2323,15 @@ void
 ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
 {
 	ztest_shared_t *zs = ztest_shared;
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	uint64_t leaves;
 	uint64_t guid;
 	nvlist_t *nvroot;
 	int error;
 
-	VERIFY(mutex_lock(&zs->zs_vdev_lock) == 0);
-	leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * zopt_raidz;
+	VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+	leaves =
+	    MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz;
 
 	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
 
@@ -2225,9 +2356,9 @@ ztest_vdev_add_remove(ztest_ds_t *zd, ui
 		 * dmu_objset_destroy() to fail with EBUSY thus
 		 * leaving the dataset in an inconsistent state.
 		 */
-		VERIFY(rw_wrlock(&ztest_shared->zs_name_lock) == 0);
+		VERIFY(rw_wrlock(&ztest_name_lock) == 0);
 		error = spa_vdev_remove(spa, guid, B_FALSE);
-		VERIFY(rw_unlock(&ztest_shared->zs_name_lock) == 0);
+		VERIFY(rw_unlock(&ztest_name_lock) == 0);
 
 		if (error && error != EEXIST)
 			fatal(0, "spa_vdev_remove() = %d", error);
@@ -2237,8 +2368,10 @@ ztest_vdev_add_remove(ztest_ds_t *zd, ui
 		/*
 		 * Make 1/4 of the devices be log devices.
 		 */
-		nvroot = make_vdev_root(NULL, NULL, zopt_vdev_size, 0,
-		    ztest_random(4) == 0, zopt_raidz, zs->zs_mirrors, 1);
+		nvroot = make_vdev_root(NULL, NULL,
+		    ztest_opts.zo_vdev_size, 0,
+		    ztest_random(4) == 0, ztest_opts.zo_raidz,
+		    zs->zs_mirrors, 1);
 
 		error = spa_vdev_add(spa, nvroot);
 		nvlist_free(nvroot);
@@ -2249,7 +2382,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, ui
 			fatal(0, "spa_vdev_add() = %d", error);
 	}
 
-	VERIFY(mutex_unlock(&ztest_shared->zs_vdev_lock) == 0);
+	VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 }
 
 /*
@@ -2260,7 +2393,7 @@ void
 ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
 {
 	ztest_shared_t *zs = ztest_shared;
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	vdev_t *rvd = spa->spa_root_vdev;
 	spa_aux_vdev_t *sav;
 	char *aux;
@@ -2275,7 +2408,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd
 		aux = ZPOOL_CONFIG_L2CACHE;
 	}
 
-	VERIFY(mutex_lock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
 
 	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
 
@@ -2292,8 +2425,9 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd
 		for (;;) {
 			char path[MAXPATHLEN];
 			int c;
-			(void) sprintf(path, ztest_aux_template, zopt_dir,
-			    zopt_pool, aux, zs->zs_vdev_aux);
+			(void) snprintf(path, sizeof (path), ztest_aux_template,
+			    ztest_opts.zo_dir, ztest_opts.zo_pool, aux,
+			    zs->zs_vdev_aux);
 			for (c = 0; c < sav->sav_count; c++)
 				if (strcmp(sav->sav_vdevs[c]->vdev_path,
 				    path) == 0)
@@ -2312,7 +2446,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd
 		 * Add a new device.
 		 */
 		nvlist_t *nvroot = make_vdev_root(NULL, aux,
-		    (zopt_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
+		    (ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
 		error = spa_vdev_add(spa, nvroot);
 		if (error != 0)
 			fatal(0, "spa_vdev_add(%p) = %d", nvroot, error);
@@ -2331,7 +2465,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd
 			fatal(0, "spa_vdev_remove(%llu) = %d", guid, error);
 	}
 
-	VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 }
 
 /*
@@ -2342,17 +2476,17 @@ void
 ztest_split_pool(ztest_ds_t *zd, uint64_t id)
 {
 	ztest_shared_t *zs = ztest_shared;
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	vdev_t *rvd = spa->spa_root_vdev;
 	nvlist_t *tree, **child, *config, *split, **schild;
 	uint_t c, children, schildren = 0, lastlogid = 0;
 	int error = 0;
 
-	VERIFY(mutex_lock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
 
 	/* ensure we have a useable config; mirrors of raidz aren't supported */
-	if (zs->zs_mirrors < 3 || zopt_raidz > 1) {
-		VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+	if (zs->zs_mirrors < 3 || ztest_opts.zo_raidz > 1) {
+		VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 		return;
 	}
 
@@ -2411,9 +2545,9 @@ ztest_split_pool(ztest_ds_t *zd, uint64_
 
 	spa_config_exit(spa, SCL_VDEV, FTAG);
 
-	(void) rw_wrlock(&zs->zs_name_lock);
+	(void) rw_wrlock(&ztest_name_lock);
 	error = spa_vdev_split_mirror(spa, "splitp", config, NULL, B_FALSE);
-	(void) rw_unlock(&zs->zs_name_lock);
+	(void) rw_unlock(&ztest_name_lock);
 
 	nvlist_free(config);
 
@@ -2426,7 +2560,7 @@ ztest_split_pool(ztest_ds_t *zd, uint64_
 		++zs->zs_splits;
 		--zs->zs_mirrors;
 	}
-	VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 
 }
 
@@ -2438,7 +2572,7 @@ void
 ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
 {
 	ztest_shared_t *zs = ztest_shared;
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	spa_aux_vdev_t *sav = &spa->spa_spares;
 	vdev_t *rvd = spa->spa_root_vdev;
 	vdev_t *oldvd, *newvd, *pvd;
@@ -2455,8 +2589,8 @@ ztest_vdev_attach_detach(ztest_ds_t *zd,
 	int oldvd_is_log;
 	int error, expected_error;
 
-	VERIFY(mutex_lock(&zs->zs_vdev_lock) == 0);
-	leaves = MAX(zs->zs_mirrors, 1) * zopt_raidz;
+	VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
+	leaves = MAX(zs->zs_mirrors, 1) * ztest_opts.zo_raidz;
 
 	spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
 
@@ -2482,12 +2616,12 @@ ztest_vdev_attach_detach(ztest_ds_t *zd,
 	if (zs->zs_mirrors >= 1) {
 		ASSERT(oldvd->vdev_ops == &vdev_mirror_ops);
 		ASSERT(oldvd->vdev_children >= zs->zs_mirrors);
-		oldvd = oldvd->vdev_child[leaf / zopt_raidz];
+		oldvd = oldvd->vdev_child[leaf / ztest_opts.zo_raidz];
 	}
-	if (zopt_raidz > 1) {
+	if (ztest_opts.zo_raidz > 1) {
 		ASSERT(oldvd->vdev_ops == &vdev_raidz_ops);
-		ASSERT(oldvd->vdev_children == zopt_raidz);
-		oldvd = oldvd->vdev_child[leaf % zopt_raidz];
+		ASSERT(oldvd->vdev_children == ztest_opts.zo_raidz);
+		oldvd = oldvd->vdev_child[leaf % ztest_opts.zo_raidz];
 	}
 
 	/*
@@ -2516,7 +2650,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd,
 		if (error != 0 && error != ENODEV && error != EBUSY &&
 		    error != ENOTSUP)
 			fatal(0, "detach (%s) returned %d", oldpath, error);
-		VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+		VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 		return;
 	}
 
@@ -2530,7 +2664,8 @@ ztest_vdev_attach_detach(ztest_ds_t *zd,
 		(void) strcpy(newpath, newvd->vdev_path);
 	} else {
 		(void) snprintf(newpath, sizeof (newpath), ztest_dev_template,
-		    zopt_dir, zopt_pool, top * leaves + leaf);
+		    ztest_opts.zo_dir, ztest_opts.zo_pool,
+		    top * leaves + leaf);
 		if (ztest_random(2) == 0)
 			newpath[strlen(newpath) - 1] = 'b';
 		newvd = vdev_lookup_by_path(rvd, newpath);
@@ -2609,7 +2744,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd,
 		    (longlong_t)newsize, replacing, error, expected_error);
 	}
 
-	VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 }
 
 /*
@@ -2632,7 +2767,7 @@ grow_vdev(vdev_t *vd, void *arg)
 	fsize = lseek(fd, 0, SEEK_END);
 	(void) ftruncate(fd, *newsize);
 
-	if (zopt_verbose >= 6) {
+	if (ztest_opts.zo_verbose >= 6) {
 		(void) printf("%s grew from %lu to %lu bytes\n",
 		    vd->vdev_path, (ulong_t)fsize, (ulong_t)*newsize);
 	}
@@ -2668,7 +2803,7 @@ online_vdev(vdev_t *vd, void *arg)
 	 * vdev_open fails is by checking the returned newstate.
 	 */
 	if (error || newstate != VDEV_STATE_HEALTHY) {
-		if (zopt_verbose >= 5) {
+		if (ztest_opts.zo_verbose >= 5) {
 			(void) printf("Unable to expand vdev, state %llu, "
 			    "error %d\n", (u_longlong_t)newstate, error);
 		}
@@ -2683,7 +2818,7 @@ online_vdev(vdev_t *vd, void *arg)
 	 * trying to online it.
 	 */
 	if (generation != spa->spa_config_generation) {
-		if (zopt_verbose >= 5) {
+		if (ztest_opts.zo_verbose >= 5) {
 			(void) printf("vdev configuration has changed, "
 			    "guid %llu, state %llu, expected gen %llu, "
 			    "got gen %llu\n",
@@ -2729,8 +2864,7 @@ vdev_walk_tree(vdev_t *vd, vdev_t *(*fun
 void
 ztest_vdev_LUN_growth(ztest_ds_t *zd, uint64_t id)
 {
-	ztest_shared_t *zs = ztest_shared;
-	spa_t *spa = zs->zs_spa;
+	spa_t *spa = ztest_spa;
 	vdev_t *vd, *tvd;
 	metaslab_class_t *mc;
 	metaslab_group_t *mg;
@@ -2738,7 +2872,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 	uint64_t top;
 	uint64_t old_class_space, new_class_space, old_ms_count, new_ms_count;
 
-	VERIFY(mutex_lock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
 	spa_config_enter(spa, SCL_STATE, spa, RW_READER);
 
 	top = ztest_random_vdev_top(spa, B_TRUE);
@@ -2764,16 +2898,16 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 	 * original size, and it has a valid psize.
 	 */
 	if (tvd->vdev_state != VDEV_STATE_HEALTHY ||
-	    psize == 0 || psize >= 4 * zopt_vdev_size) {
+	    psize == 0 || psize >= 4 * ztest_opts.zo_vdev_size) {
 		spa_config_exit(spa, SCL_STATE, spa);
-		VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+		VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 		return;
 	}
 	ASSERT(psize > 0);
 	newsize = psize + psize / 8;
 	ASSERT3U(newsize, >, psize);
 
-	if (zopt_verbose >= 6) {
+	if (ztest_opts.zo_verbose >= 6) {
 		(void) printf("Expanding LUN %s from %lu to %lu\n",
 		    vd->vdev_path, (ulong_t)psize, (ulong_t)newsize);
 	}
@@ -2786,12 +2920,12 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 	if (vdev_walk_tree(tvd, grow_vdev, &newsize) != NULL ||
 	    vdev_walk_tree(tvd, online_vdev, NULL) != NULL ||
 	    tvd->vdev_state != VDEV_STATE_HEALTHY) {
-		if (zopt_verbose >= 5) {
+		if (ztest_opts.zo_verbose >= 5) {
 			(void) printf("Could not expand LUN because "
 			    "the vdev configuration changed.\n");
 		}
 		spa_config_exit(spa, SCL_STATE, spa);
-		VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+		VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 		return;
 	}
 
@@ -2820,12 +2954,12 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 	new_class_space = metaslab_class_get_space(mc);
 
 	if (tvd->vdev_mg != mg || mg->mg_class != mc) {
-		if (zopt_verbose >= 5) {
+		if (ztest_opts.zo_verbose >= 5) {
 			(void) printf("Could not verify LUN expansion due to "
 			    "intervening vdev offline or remove.\n");
 		}
 		spa_config_exit(spa, SCL_STATE, spa);
-		VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+		VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 		return;
 	}
 
@@ -2843,7 +2977,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 		fatal(0, "LUN expansion failed: class_space %llu <= %llu\n",
 		    old_class_space, new_class_space);
 
-	if (zopt_verbose >= 5) {
+	if (ztest_opts.zo_verbose >= 5) {
 		char oldnumbuf[6], newnumbuf[6];
 
 		nicenum(old_class_space, oldnumbuf);
@@ -2853,7 +2987,7 @@ ztest_vdev_LUN_growth(ztest_ds_t *zd, ui
 	}
 
 	spa_config_exit(spa, SCL_STATE, spa);
-	VERIFY(mutex_unlock(&zs->zs_vdev_lock) == 0);
+	VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
 }
 
 /*
@@ -2880,7 +3014,8 @@ ztest_dataset_create(char *dsname)
 	if (err || zilset < 80)
 		return (err);
 
-	(void) printf("Setting dataset %s to sync always\n", dsname);
+	if (ztest_opts.zo_verbose >= 6)
+		(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));
 }
@@ -2952,7 +3087,6 @@ ztest_snapshot_destroy(char *osname, uin
 void
 ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
 {
-	ztest_shared_t *zs = ztest_shared;
 	ztest_ds_t zdtmp;
 	int iters;
 	int error;
@@ -2960,10 +3094,10 @@ ztest_dmu_objset_create_destroy(ztest_ds
 	char name[MAXNAMELEN];
 	zilog_t *zilog;
 
-	(void) rw_rdlock(&zs->zs_name_lock);
+	(void) rw_rdlock(&ztest_name_lock);
 
 	(void) snprintf(name, MAXNAMELEN, "%s/temp_%llu",
-	    zs->zs_pool, (u_longlong_t)id);
+	    ztest_opts.zo_pool, (u_longlong_t)id);
 
 	/*
 	 * If this dataset exists from a previous run, process its replay log
@@ -2972,7 +3106,7 @@ ztest_dmu_objset_create_destroy(ztest_ds
 	 */
 	if (ztest_random(2) == 0 &&
 	    dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os) == 0) {
-		ztest_zd_init(&zdtmp, os);
+		ztest_zd_init(&zdtmp, NULL, os);
 		zil_replay(os, &zdtmp, ztest_replay_vector);
 		ztest_zd_fini(&zdtmp);
 		dmu_objset_disown(os, FTAG);
@@ -2998,7 +3132,7 @@ ztest_dmu_objset_create_destroy(ztest_ds
 	if (error) {
 		if (error == ENOSPC) {
 			ztest_record_enospc(FTAG);
-			(void) rw_unlock(&zs->zs_name_lock);
+			(void) rw_unlock(&ztest_name_lock);
 			return;
 		}
 		fatal(0, "dmu_objset_create(%s) = %d", name, error);
@@ -3007,7 +3141,7 @@ ztest_dmu_objset_create_destroy(ztest_ds
 	VERIFY3U(0, ==,
 	    dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os));
 
-	ztest_zd_init(&zdtmp, os);
+	ztest_zd_init(&zdtmp, NULL, os);
 
 	/*
 	 * Open the intent log for it.
@@ -3047,7 +3181,7 @@ ztest_dmu_objset_create_destroy(ztest_ds
 	dmu_objset_disown(os, FTAG);
 	ztest_zd_fini(&zdtmp);
 
-	(void) rw_unlock(&zs->zs_name_lock);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205271137.q4RBbODF046203>