spa.c revision 2f8aaab38e6371ad39ed90a1211ba8921acbb4d5
1fa9e406ahrens/*
2fa9e406ahrens * CDDL HEADER START
3fa9e406ahrens *
4fa9e406ahrens * The contents of this file are subject to the terms of the
5ea8dc4beschrock * Common Development and Distribution License (the "License").
6ea8dc4beschrock * You may not use this file except in compliance with the License.
7fa9e406ahrens *
8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e406ahrens * or http://www.opensolaris.org/os/licensing.
10fa9e406ahrens * See the License for the specific language governing permissions
11fa9e406ahrens * and limitations under the License.
12fa9e406ahrens *
13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each
14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the
16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e406ahrens *
19fa9e406ahrens * CDDL HEADER END
20fa9e406ahrens */
2199653d4eschrock
22fa9e406ahrens/*
2339c2341eschrock * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24fa9e406ahrens * Use is subject to license terms.
25fa9e406ahrens */
26fa9e406ahrens
27fa9e406ahrens#pragma ident	"%Z%%M%	%I%	%E% SMI"
28fa9e406ahrens
29fa9e406ahrens/*
30fa9e406ahrens * This file contains all the routines used when modifying on-disk SPA state.
31fa9e406ahrens * This includes opening, importing, destroying, exporting a pool, and syncing a
32fa9e406ahrens * pool.
33fa9e406ahrens */
34fa9e406ahrens
35fa9e406ahrens#include <sys/zfs_context.h>
36ea8dc4beschrock#include <sys/fm/fs/zfs.h>
37fa9e406ahrens#include <sys/spa_impl.h>
38fa9e406ahrens#include <sys/zio.h>
39fa9e406ahrens#include <sys/zio_checksum.h>
40fa9e406ahrens#include <sys/zio_compress.h>
41fa9e406ahrens#include <sys/dmu.h>
42fa9e406ahrens#include <sys/dmu_tx.h>
43fa9e406ahrens#include <sys/zap.h>
44fa9e406ahrens#include <sys/zil.h>
45fa9e406ahrens#include <sys/vdev_impl.h>
46fa9e406ahrens#include <sys/metaslab.h>
47fa9e406ahrens#include <sys/uberblock_impl.h>
48fa9e406ahrens#include <sys/txg.h>
49fa9e406ahrens#include <sys/avl.h>
50fa9e406ahrens#include <sys/dmu_traverse.h>
51b1b8ab3lling#include <sys/dmu_objset.h>
52fa9e406ahrens#include <sys/unique.h>
53fa9e406ahrens#include <sys/dsl_pool.h>
54b1b8ab3lling#include <sys/dsl_dataset.h>
55fa9e406ahrens#include <sys/dsl_dir.h>
56fa9e406ahrens#include <sys/dsl_prop.h>
57b1b8ab3lling#include <sys/dsl_synctask.h>
58fa9e406ahrens#include <sys/fs/zfs.h>
59fa9e406ahrens#include <sys/callb.h>
609517395ek#include <sys/systeminfo.h>
619517395ek#include <sys/sunddi.h>
62fa9e406ahrens
63990b485lling#include "zfs_prop.h"
64990b485lling
65416e0cdekint zio_taskq_threads = 8;
66416e0cdek
67990b485llingstatic void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx);
68990b485lling
69990b485lling/*
70990b485lling * ==========================================================================
71990b485lling * SPA properties routines
72990b485lling * ==========================================================================
73990b485lling */
74990b485lling
75990b485lling/*
76990b485lling * Add a (source=src, propname=propval) list to an nvlist.
77990b485lling */
78990b485llingstatic int
79990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
80990b485lling    uint64_t intval, zprop_source_t src)
81990b485lling{
82990b485lling	const char *propname = zpool_prop_to_name(prop);
83990b485lling	nvlist_t *propval;
84990b485lling	int err = 0;
85990b485lling
86990b485lling	if (err = nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP))
87990b485lling		return (err);
88990b485lling
89990b485lling	if (err = nvlist_add_uint64(propval, ZPROP_SOURCE, src))
90990b485lling		goto out;
91990b485lling
92990b485lling	if (strval != NULL) {
93990b485lling		if (err = nvlist_add_string(propval, ZPROP_VALUE, strval))
94990b485lling			goto out;
95990b485lling	} else {
96990b485lling		if (err = nvlist_add_uint64(propval, ZPROP_VALUE, intval))
97990b485lling			goto out;
98990b485lling	}
99990b485lling
100990b485lling	err = nvlist_add_nvlist(nvl, propname, propval);
101990b485llingout:
102990b485lling	nvlist_free(propval);
103990b485lling	return (err);
104990b485lling}
105990b485lling
106990b485lling/*
107990b485lling * Get property values from the spa configuration.
108990b485lling */
109990b485llingstatic int
110990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp)
111990b485lling{
112990b485lling	uint64_t size = spa_get_space(spa);
113990b485lling	uint64_t used = spa_get_alloc(spa);
114990b485lling	uint64_t cap, version;
115990b485lling	zprop_source_t src = ZPROP_SRC_NONE;
116990b485lling	int err;
1172f8aaabeschrock	char *cachefile;
1182f8aaabeschrock	size_t len;
119990b485lling
120990b485lling	/*
121990b485lling	 * readonly properties
122990b485lling	 */
123990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name,
124990b485lling	    0, src))
125990b485lling		return (err);
126990b485lling
127990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src))
128990b485lling		return (err);
129990b485lling
130990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src))
131990b485lling		return (err);
132990b485lling
133990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL,
134990b485lling	    size - used, src))
135990b485lling		return (err);
136990b485lling
137990b485lling	cap = (size == 0) ? 0 : (used * 100 / size);
138990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src))
139990b485lling		return (err);
140990b485lling
141990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL,
142990b485lling	    spa_guid(spa), src))
143990b485lling		return (err);
144990b485lling
145990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
146990b485lling	    spa->spa_root_vdev->vdev_state, src))
147990b485lling		return (err);
148990b485lling
149990b485lling	/*
150990b485lling	 * settable properties that are not stored in the pool property object.
151990b485lling	 */
152990b485lling	version = spa_version(spa);
153990b485lling	if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
154990b485lling		src = ZPROP_SRC_DEFAULT;
155990b485lling	else
156990b485lling		src = ZPROP_SRC_LOCAL;
157990b485lling	if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL,
158990b485lling	    version, src))
159990b485lling		return (err);
160990b485lling
161990b485lling	if (spa->spa_root != NULL) {
162990b485lling		src = ZPROP_SRC_LOCAL;
163990b485lling		if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT,
164990b485lling		    spa->spa_root, 0, src))
165990b485lling			return (err);
166990b485lling	}
167990b485lling
1682f8aaabeschrock	if (spa->spa_config_dir != NULL) {
1692f8aaabeschrock		if (strcmp(spa->spa_config_dir, "none") == 0) {
1702f8aaabeschrock			err = spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
1712f8aaabeschrock			    spa->spa_config_dir, 0, ZPROP_SRC_LOCAL);
1722f8aaabeschrock		} else {
1732f8aaabeschrock			len = strlen(spa->spa_config_dir) +
1742f8aaabeschrock			    strlen(spa->spa_config_file) + 2;
1752f8aaabeschrock			cachefile = kmem_alloc(len, KM_SLEEP);
1762f8aaabeschrock			(void) snprintf(cachefile, len, "%s/%s",
1772f8aaabeschrock			    spa->spa_config_dir, spa->spa_config_file);
1782f8aaabeschrock			err = spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
1792f8aaabeschrock			    cachefile, 0, ZPROP_SRC_LOCAL);
1802f8aaabeschrock			kmem_free(cachefile, len);
1812f8aaabeschrock		}
1822f8aaabeschrock
1832f8aaabeschrock		if (err)
1842f8aaabeschrock			return (err);
1852f8aaabeschrock	}
186990b485lling
187990b485lling	return (0);
188990b485lling}
189990b485lling
190990b485lling/*
191990b485lling * Get zpool property values.
192990b485lling */
193990b485llingint
194990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp)
195990b485lling{
196990b485lling	zap_cursor_t zc;
197990b485lling	zap_attribute_t za;
198990b485lling	objset_t *mos = spa->spa_meta_objset;
199990b485lling	int err;
200990b485lling
201990b485lling	if (err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP))
202990b485lling		return (err);
203990b485lling
204990b485lling	/*
205990b485lling	 * Get properties from the spa config.
206990b485lling	 */
207990b485lling	if (err = spa_prop_get_config(spa, nvp))
208990b485lling		goto out;
209990b485lling
210990b485lling	mutex_enter(&spa->spa_props_lock);
211990b485lling	/* If no pool property object, no more prop to get. */
212990b485lling	if (spa->spa_pool_props_object == 0) {
213990b485lling		mutex_exit(&spa->spa_props_lock);
214990b485lling		return (0);
215990b485lling	}
216990b485lling
217990b485lling	/*
218990b485lling	 * Get properties from the MOS pool property object.
219990b485lling	 */
220990b485lling	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
221990b485lling	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
222990b485lling	    zap_cursor_advance(&zc)) {
223990b485lling		uint64_t intval = 0;
224990b485lling		char *strval = NULL;
225990b485lling		zprop_source_t src = ZPROP_SRC_DEFAULT;
226990b485lling		zpool_prop_t prop;
227990b485lling
228990b485lling		if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL)
229990b485lling			continue;
230990b485lling
231990b485lling		switch (za.za_integer_length) {
232990b485lling		case 8:
233990b485lling			/* integer property */
234990b485lling			if (za.za_first_integer !=
235990b485lling			    zpool_prop_default_numeric(prop))
236990b485lling				src = ZPROP_SRC_LOCAL;
237990b485lling
238990b485lling			if (prop == ZPOOL_PROP_BOOTFS) {
239990b485lling				dsl_pool_t *dp;
240990b485lling				dsl_dataset_t *ds = NULL;
241990b485lling
242990b485lling				dp = spa_get_dsl(spa);
243990b485lling				rw_enter(&dp->dp_config_rwlock, RW_READER);
244990b485lling				if (err = dsl_dataset_open_obj(dp,
245990b485lling				    za.za_first_integer, NULL, DS_MODE_NONE,
246990b485lling				    FTAG, &ds)) {
247990b485lling					rw_exit(&dp->dp_config_rwlock);
248990b485lling					break;
249990b485lling				}
250990b485lling
251990b485lling				strval = kmem_alloc(
252990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
253990b485lling				    KM_SLEEP);
254990b485lling				dsl_dataset_name(ds, strval);
255990b485lling				dsl_dataset_close(ds, DS_MODE_NONE, FTAG);
256990b485lling				rw_exit(&dp->dp_config_rwlock);
257990b485lling			} else {
258990b485lling				strval = NULL;
259990b485lling				intval = za.za_first_integer;
260990b485lling			}
261990b485lling
262990b485lling			err = spa_prop_add_list(*nvp, prop, strval,
263990b485lling			    intval, src);
264990b485lling
265990b485lling			if (strval != NULL)
266990b485lling				kmem_free(strval,
267990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
268990b485lling
269990b485lling			break;
270990b485lling
271990b485lling		case 1:
272990b485lling			/* string property */
273990b485lling			strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
274990b485lling			err = zap_lookup(mos, spa->spa_pool_props_object,
275990b485lling			    za.za_name, 1, za.za_num_integers, strval);
276990b485lling			if (err) {
277990b485lling				kmem_free(strval, za.za_num_integers);
278990b485lling				break;
279990b485lling			}
280990b485lling			err = spa_prop_add_list(*nvp, prop, strval, 0, src);
281990b485lling			kmem_free(strval, za.za_num_integers);
282990b485lling			break;
283990b485lling
284990b485lling		default:
285990b485lling			break;
286990b485lling		}
287990b485lling	}
288990b485lling	zap_cursor_fini(&zc);
289990b485lling	mutex_exit(&spa->spa_props_lock);
290990b485llingout:
291990b485lling	if (err && err != ENOENT) {
292990b485lling		nvlist_free(*nvp);
293990b485lling		return (err);
294990b485lling	}
295990b485lling
296990b485lling	return (0);
297990b485lling}
298990b485lling
299990b485lling/*
300990b485lling * Validate the given pool properties nvlist and modify the list
301990b485lling * for the property values to be set.
302990b485lling */
303990b485llingstatic int
304990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props)
305990b485lling{
306990b485lling	nvpair_t *elem;
307990b485lling	int error = 0, reset_bootfs = 0;
308990b485lling	uint64_t objnum;
309990b485lling
310990b485lling	elem = NULL;
311990b485lling	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
312990b485lling		zpool_prop_t prop;
313990b485lling		char *propname, *strval;
314990b485lling		uint64_t intval;
315990b485lling		vdev_t *rvdev;
316990b485lling		char *vdev_type;
317990b485lling		objset_t *os;
3182f8aaabeschrock		char *slash;
319990b485lling
320990b485lling		propname = nvpair_name(elem);
321990b485lling
322990b485lling		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
323990b485lling			return (EINVAL);
324990b485lling
325990b485lling		switch (prop) {
326990b485lling		case ZPOOL_PROP_VERSION:
327990b485lling			error = nvpair_value_uint64(elem, &intval);
328990b485lling			if (!error &&
329990b485lling			    (intval < spa_version(spa) || intval > SPA_VERSION))
330990b485lling				error = EINVAL;
331990b485lling			break;
332990b485lling
333990b485lling		case ZPOOL_PROP_DELEGATION:
334990b485lling		case ZPOOL_PROP_AUTOREPLACE:
335990b485lling			error = nvpair_value_uint64(elem, &intval);
336990b485lling			if (!error && intval > 1)
337990b485lling				error = EINVAL;
338990b485lling			break;
339990b485lling
340990b485lling		case ZPOOL_PROP_BOOTFS:
341990b485lling			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
342990b485lling				error = ENOTSUP;
343990b485lling				break;
344990b485lling			}
345990b485lling
346990b485lling			/*
347990b485lling			 * A bootable filesystem can not be on a RAIDZ pool
348990b485lling			 * nor a striped pool with more than 1 device.
349990b485lling			 */
350990b485lling			rvdev = spa->spa_root_vdev;
351990b485lling			vdev_type =
352990b485lling			    rvdev->vdev_child[0]->vdev_ops->vdev_op_type;
353990b485lling			if (rvdev->vdev_children > 1 ||
354990b485lling			    strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 ||
355990b485lling			    strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) {
356990b485lling				error = ENOTSUP;
357990b485lling				break;
358990b485lling			}
359990b485lling
360990b485lling			reset_bootfs = 1;
361990b485lling
362990b485lling			error = nvpair_value_string(elem, &strval);
363990b485lling
364990b485lling			if (!error) {
365990b485lling				if (strval == NULL || strval[0] == '\0') {
366990b485lling					objnum = zpool_prop_default_numeric(
367990b485lling					    ZPOOL_PROP_BOOTFS);
368990b485lling					break;
369990b485lling				}
370990b485lling
371990b485lling				if (error = dmu_objset_open(strval, DMU_OST_ZFS,
372990b485lling				    DS_MODE_STANDARD | DS_MODE_READONLY, &os))
373990b485lling					break;
374990b485lling				objnum = dmu_objset_id(os);
375990b485lling				dmu_objset_close(os);
376990b485lling			}
377990b485lling			break;
3780a4e951gw		case ZPOOL_PROP_FAILUREMODE:
3790a4e951gw			error = nvpair_value_uint64(elem, &intval);
3800a4e951gw			if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
3810a4e951gw			    intval > ZIO_FAILURE_MODE_PANIC))
3820a4e951gw				error = EINVAL;
3830a4e951gw
3840a4e951gw			/*
3850a4e951gw			 * This is a special case which only occurs when
3860a4e951gw			 * the pool has completely failed. This allows
3870a4e951gw			 * the user to change the in-core failmode property
3880a4e951gw			 * without syncing it out to disk (I/Os might
3890a4e951gw			 * currently be blocked). We do this by returning
3900a4e951gw			 * EIO to the caller (spa_prop_set) to trick it
3910a4e951gw			 * into thinking we encountered a property validation
3920a4e951gw			 * error.
3930a4e951gw			 */
3940a4e951gw			if (!error && spa_state(spa) == POOL_STATE_IO_FAILURE) {
3950a4e951gw				spa->spa_failmode = intval;
3960a4e951gw				error = EIO;
3970a4e951gw			}
3980a4e951gw			break;
3992f8aaabeschrock
4002f8aaabeschrock		case ZPOOL_PROP_CACHEFILE:
4012f8aaabeschrock			if ((error = nvpair_value_string(elem, &strval)) != 0)
4022f8aaabeschrock				break;
4032f8aaabeschrock
4042f8aaabeschrock			if (strval[0] == '\0')
4052f8aaabeschrock				break;
4062f8aaabeschrock
4072f8aaabeschrock			if (strcmp(strval, "none") == 0)
4082f8aaabeschrock				break;
4092f8aaabeschrock
4102f8aaabeschrock			if (strval[0] != '/') {
4112f8aaabeschrock				error = EINVAL;
4122f8aaabeschrock				break;
4132f8aaabeschrock			}
4142f8aaabeschrock
4152f8aaabeschrock			slash = strrchr(strval, '/');
4162f8aaabeschrock			ASSERT(slash != NULL);
4172f8aaabeschrock
4182f8aaabeschrock			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
4192f8aaabeschrock			    strcmp(slash, "/..") == 0)
4202f8aaabeschrock				error = EINVAL;
4212f8aaabeschrock			break;
422990b485lling		}
423990b485lling
424990b485lling		if (error)
425990b485lling			break;
426990b485lling	}
427990b485lling
428990b485lling	if (!error && reset_bootfs) {
429990b485lling		error = nvlist_remove(props,
430990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING);
431990b485lling
432990b485lling		if (!error) {
433990b485lling			error = nvlist_add_uint64(props,
434990b485lling			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum);
435990b485lling		}
436990b485lling	}
437990b485lling
438990b485lling	return (error);
439990b485lling}
440990b485lling
441990b485llingint
442990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp)
443990b485lling{
444990b485lling	int error;
445990b485lling
446990b485lling	if ((error = spa_prop_validate(spa, nvp)) != 0)
447990b485lling		return (error);
448990b485lling
449990b485lling	return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props,
450990b485lling	    spa, nvp, 3));
451990b485lling}
452990b485lling
453990b485lling/*
454990b485lling * If the bootfs property value is dsobj, clear it.
455990b485lling */
456990b485llingvoid
457990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
458990b485lling{
459990b485lling	if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) {
460990b485lling		VERIFY(zap_remove(spa->spa_meta_objset,
461990b485lling		    spa->spa_pool_props_object,
462990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0);
463990b485lling		spa->spa_bootfs = 0;
464990b485lling	}
465990b485lling}
466990b485lling
467fa9e406ahrens/*
468fa9e406ahrens * ==========================================================================
469fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export)
470fa9e406ahrens * ==========================================================================
471fa9e406ahrens */
472fa9e406ahrens
473ea8dc4beschrockstatic int
474ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b)
475ea8dc4beschrock{
476ea8dc4beschrock	spa_error_entry_t *sa = (spa_error_entry_t *)a;
477ea8dc4beschrock	spa_error_entry_t *sb = (spa_error_entry_t *)b;
478ea8dc4beschrock	int ret;
479ea8dc4beschrock
480ea8dc4beschrock	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
481ea8dc4beschrock	    sizeof (zbookmark_t));
482ea8dc4beschrock
483ea8dc4beschrock	if (ret < 0)
484ea8dc4beschrock		return (-1);
485ea8dc4beschrock	else if (ret > 0)
486ea8dc4beschrock		return (1);
487ea8dc4beschrock	else
488ea8dc4beschrock		return (0);
489ea8dc4beschrock}
490ea8dc4beschrock
491ea8dc4beschrock/*
492ea8dc4beschrock * Utility function which retrieves copies of the current logs and
493ea8dc4beschrock * re-initializes them in the process.
494ea8dc4beschrock */
495ea8dc4beschrockvoid
496ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
497ea8dc4beschrock{
498ea8dc4beschrock	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
499ea8dc4beschrock
500ea8dc4beschrock	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
501ea8dc4beschrock	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
502ea8dc4beschrock
503ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
504ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
505ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
506ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
507ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
508ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
509ea8dc4beschrock}
510ea8dc4beschrock
511fa9e406ahrens/*
512fa9e406ahrens * Activate an uninitialized pool.
513fa9e406ahrens */
514fa9e406ahrensstatic void
515fa9e406ahrensspa_activate(spa_t *spa)
516fa9e406ahrens{
517fa9e406ahrens	int t;
518fa9e406ahrens
519fa9e406ahrens	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
520fa9e406ahrens
521fa9e406ahrens	spa->spa_state = POOL_STATE_ACTIVE;
522fa9e406ahrens
523fa9e406ahrens	spa->spa_normal_class = metaslab_class_create();
5248654d02perrin	spa->spa_log_class = metaslab_class_create();
525fa9e406ahrens
526fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
527fa9e406ahrens		spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue",
528416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
529fa9e406ahrens		    TASKQ_PREPOPULATE);
530fa9e406ahrens		spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr",
531416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
532fa9e406ahrens		    TASKQ_PREPOPULATE);
533fa9e406ahrens	}
534fa9e406ahrens
535fa9e406ahrens	list_create(&spa->spa_dirty_list, sizeof (vdev_t),
536fa9e406ahrens	    offsetof(vdev_t, vdev_dirty_node));
5370a4e951gw	list_create(&spa->spa_zio_list, sizeof (zio_t),
5380a4e951gw	    offsetof(zio_t, zio_link_node));
539fa9e406ahrens
540fa9e406ahrens	txg_list_create(&spa->spa_vdev_txg_list,
541fa9e406ahrens	    offsetof(struct vdev, vdev_txg_node));
542ea8dc4beschrock
543ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
544ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
545ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
546ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
547ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
548ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
549fa9e406ahrens}
550fa9e406ahrens
551fa9e406ahrens/*
552fa9e406ahrens * Opposite of spa_activate().
553fa9e406ahrens */
554fa9e406ahrensstatic void
555fa9e406ahrensspa_deactivate(spa_t *spa)
556fa9e406ahrens{
557fa9e406ahrens	int t;
558fa9e406ahrens
559fa9e406ahrens	ASSERT(spa->spa_sync_on == B_FALSE);
560fa9e406ahrens	ASSERT(spa->spa_dsl_pool == NULL);
561fa9e406ahrens	ASSERT(spa->spa_root_vdev == NULL);
562fa9e406ahrens
563fa9e406ahrens	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
564fa9e406ahrens
565fa9e406ahrens	txg_list_destroy(&spa->spa_vdev_txg_list);
566fa9e406ahrens
567fa9e406ahrens	list_destroy(&spa->spa_dirty_list);
5680a4e951gw	list_destroy(&spa->spa_zio_list);
569fa9e406ahrens
570fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
571fa9e406ahrens		taskq_destroy(spa->spa_zio_issue_taskq[t]);
572fa9e406ahrens		taskq_destroy(spa->spa_zio_intr_taskq[t]);
573fa9e406ahrens		spa->spa_zio_issue_taskq[t] = NULL;
574fa9e406ahrens		spa->spa_zio_intr_taskq[t] = NULL;
575fa9e406ahrens	}
576fa9e406ahrens
577fa9e406ahrens	metaslab_class_destroy(spa->spa_normal_class);
578fa9e406ahrens	spa->spa_normal_class = NULL;
579fa9e406ahrens
5808654d02perrin	metaslab_class_destroy(spa->spa_log_class);
5818654d02perrin	spa->spa_log_class = NULL;
5828654d02perrin
583ea8dc4beschrock	/*
584ea8dc4beschrock	 * If this was part of an import or the open otherwise failed, we may
585ea8dc4beschrock	 * still have errors left in the queues.  Empty them just in case.
586ea8dc4beschrock	 */
587ea8dc4beschrock	spa_errlog_drain(spa);
588ea8dc4beschrock
589ea8dc4beschrock	avl_destroy(&spa->spa_errlist_scrub);
590ea8dc4beschrock	avl_destroy(&spa->spa_errlist_last);
591ea8dc4beschrock
592fa9e406ahrens	spa->spa_state = POOL_STATE_UNINITIALIZED;
593fa9e406ahrens}
594fa9e406ahrens
595fa9e406ahrens/*
596fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately.  This
597fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev
598