spa.c revision 89a89ebfd7c3b4056afe2c03e959e22824df777d
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/*
23b01c3b5eschrock * Copyright 2008 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>
59fa94a07brendan#include <sys/arc.h>
60fa9e406ahrens#include <sys/callb.h>
619517395ek#include <sys/systeminfo.h>
629517395ek#include <sys/sunddi.h>
63e7cbe64gw#include <sys/spa_boot.h>
64fa9e406ahrens
65990b485lling#include "zfs_prop.h"
66b7b9745perrin#include "zfs_comutil.h"
67990b485lling
68416e0cdekint zio_taskq_threads = 8;
69416e0cdek
70990b485llingstatic void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx);
7189a89ebllingstatic boolean_t spa_has_active_shared_spare(spa_t *spa);
72990b485lling
73990b485lling/*
74990b485lling * ==========================================================================
75990b485lling * SPA properties routines
76990b485lling * ==========================================================================
77990b485lling */
78990b485lling
79990b485lling/*
80990b485lling * Add a (source=src, propname=propval) list to an nvlist.
81990b485lling */
829d82f4fllingstatic void
83990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
84990b485lling    uint64_t intval, zprop_source_t src)
85990b485lling{
86990b485lling	const char *propname = zpool_prop_to_name(prop);
87990b485lling	nvlist_t *propval;
88990b485lling
899d82f4flling	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
909d82f4flling	VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
91990b485lling
929d82f4flling	if (strval != NULL)
939d82f4flling		VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0);
949d82f4flling	else
959d82f4flling		VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, intval) == 0);
96990b485lling
979d82f4flling	VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0);
98990b485lling	nvlist_free(propval);
99990b485lling}
100990b485lling
101990b485lling/*
102990b485lling * Get property values from the spa configuration.
103990b485lling */
1049d82f4fllingstatic void
105990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp)
106990b485lling{
107990b485lling	uint64_t size = spa_get_space(spa);
108990b485lling	uint64_t used = spa_get_alloc(spa);
109990b485lling	uint64_t cap, version;
110990b485lling	zprop_source_t src = ZPROP_SRC_NONE;
111c5904d1eschrock	spa_config_dirent_t *dp;
112990b485lling
113990b485lling	/*
114990b485lling	 * readonly properties
115990b485lling	 */
1169d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name, 0, src);
1179d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src);
1189d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src);
1199d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL, size - used, src);
120990b485lling
121990b485lling	cap = (size == 0) ? 0 : (used * 100 / size);
1229d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src);
123990b485lling
1249d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
1259d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
1269d82f4flling	    spa->spa_root_vdev->vdev_state, src);
127990b485lling
128990b485lling	/*
129990b485lling	 * settable properties that are not stored in the pool property object.
130990b485lling	 */
131990b485lling	version = spa_version(spa);
132990b485lling	if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
133990b485lling		src = ZPROP_SRC_DEFAULT;
134990b485lling	else
135990b485lling		src = ZPROP_SRC_LOCAL;
1369d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
137990b485lling
1389d82f4flling	if (spa->spa_root != NULL)
1399d82f4flling		spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
1409d82f4flling		    0, ZPROP_SRC_LOCAL);
141990b485lling
142c5904d1eschrock	if ((dp = list_head(&spa->spa_config_list)) != NULL) {
143c5904d1eschrock		if (dp->scd_path == NULL) {
1449d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
145c5904d1eschrock			    "none", 0, ZPROP_SRC_LOCAL);
146c5904d1eschrock		} else if (strcmp(dp->scd_path, spa_config_path) != 0) {
1479d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
148c5904d1eschrock			    dp->scd_path, 0, ZPROP_SRC_LOCAL);
1492f8aaabeschrock		}
1502f8aaabeschrock	}
151990b485lling}
152990b485lling
153990b485lling/*
154990b485lling * Get zpool property values.
155990b485lling */
156990b485llingint
157990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp)
158990b485lling{
159990b485lling	zap_cursor_t zc;
160990b485lling	zap_attribute_t za;
161990b485lling	objset_t *mos = spa->spa_meta_objset;
162990b485lling	int err;
163990b485lling
1649d82f4flling	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
165990b485lling
166990b485lling	/*
167990b485lling	 * Get properties from the spa config.
168990b485lling	 */
1699d82f4flling	spa_prop_get_config(spa, nvp);
170990b485lling
171990b485lling	mutex_enter(&spa->spa_props_lock);
172990b485lling	/* If no pool property object, no more prop to get. */
173990b485lling	if (spa->spa_pool_props_object == 0) {
174990b485lling		mutex_exit(&spa->spa_props_lock);
175990b485lling		return (0);
176990b485lling	}
177990b485lling
178990b485lling	/*
179990b485lling	 * Get properties from the MOS pool property object.
180990b485lling	 */
181990b485lling	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
182990b485lling	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
183990b485lling	    zap_cursor_advance(&zc)) {
184990b485lling		uint64_t intval = 0;
185990b485lling		char *strval = NULL;
186990b485lling		zprop_source_t src = ZPROP_SRC_DEFAULT;
187990b485lling		zpool_prop_t prop;
188990b485lling
189990b485lling		if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL)
190990b485lling			continue;
191990b485lling
192990b485lling		switch (za.za_integer_length) {
193990b485lling		case 8:
194990b485lling			/* integer property */
195990b485lling			if (za.za_first_integer !=
196990b485lling			    zpool_prop_default_numeric(prop))
197990b485lling				src = ZPROP_SRC_LOCAL;
198990b485lling
199990b485lling			if (prop == ZPOOL_PROP_BOOTFS) {
200990b485lling				dsl_pool_t *dp;
201990b485lling				dsl_dataset_t *ds = NULL;
202990b485lling
203990b485lling				dp = spa_get_dsl(spa);
204990b485lling				rw_enter(&dp->dp_config_rwlock, RW_READER);
205745cd3cmaybee				if (err = dsl_dataset_hold_obj(dp,
206745cd3cmaybee				    za.za_first_integer, FTAG, &ds)) {
207990b485lling					rw_exit(&dp->dp_config_rwlock);
208990b485lling					break;
209990b485lling				}
210990b485lling
211990b485lling				strval = kmem_alloc(
212990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
213990b485lling				    KM_SLEEP);
214990b485lling				dsl_dataset_name(ds, strval);
215745cd3cmaybee				dsl_dataset_rele(ds, FTAG);
216990b485lling				rw_exit(&dp->dp_config_rwlock);
217990b485lling			} else {
218990b485lling				strval = NULL;
219990b485lling				intval = za.za_first_integer;
220990b485lling			}
221990b485lling
2229d82f4flling			spa_prop_add_list(*nvp, prop, strval, intval, src);
223990b485lling
224990b485lling			if (strval != NULL)
225990b485lling				kmem_free(strval,
226990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
227990b485lling
228990b485lling			break;
229990b485lling
230990b485lling		case 1:
231990b485lling			/* string property */
232990b485lling			strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
233990b485lling			err = zap_lookup(mos, spa->spa_pool_props_object,
234990b485lling			    za.za_name, 1, za.za_num_integers, strval);
235990b485lling			if (err) {
236990b485lling				kmem_free(strval, za.za_num_integers);
237990b485lling				break;
238990b485lling			}
2399d82f4flling			spa_prop_add_list(*nvp, prop, strval, 0, src);
240990b485lling			kmem_free(strval, za.za_num_integers);
241990b485lling			break;
242990b485lling
243990b485lling		default:
244990b485lling			break;
245990b485lling		}
246990b485lling	}
247990b485lling	zap_cursor_fini(&zc);
248990b485lling	mutex_exit(&spa->spa_props_lock);
249990b485llingout:
250990b485lling	if (err && err != ENOENT) {
251990b485lling		nvlist_free(*nvp);
2529d82f4flling		*nvp = NULL;
253990b485lling		return (err);
254990b485lling	}
255990b485lling
256990b485lling	return (0);
257990b485lling}
258990b485lling
259990b485lling/*
260990b485lling * Validate the given pool properties nvlist and modify the list
261990b485lling * for the property values to be set.
262990b485lling */
263990b485llingstatic int
264990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props)
265990b485lling{
266990b485lling	nvpair_t *elem;
267990b485lling	int error = 0, reset_bootfs = 0;
268990b485lling	uint64_t objnum;
269990b485lling
270990b485lling	elem = NULL;
271990b485lling	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
272990b485lling		zpool_prop_t prop;
273990b485lling		char *propname, *strval;
274990b485lling		uint64_t intval;
275990b485lling		objset_t *os;
2762f8aaabeschrock		char *slash;
277990b485lling
278990b485lling		propname = nvpair_name(elem);
279990b485lling
280990b485lling		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
281990b485lling			return (EINVAL);
282990b485lling
283990b485lling		switch (prop) {
284990b485lling		case ZPOOL_PROP_VERSION:
285990b485lling			error = nvpair_value_uint64(elem, &intval);
286990b485lling			if (!error &&
287990b485lling			    (intval < spa_version(spa) || intval > SPA_VERSION))
288990b485lling				error = EINVAL;
289990b485lling			break;
290990b485lling
291990b485lling		case ZPOOL_PROP_DELEGATION:
292990b485lling		case ZPOOL_PROP_AUTOREPLACE:
293990b485lling			error = nvpair_value_uint64(elem, &intval);
294990b485lling			if (!error && intval > 1)
295990b485lling				error = EINVAL;
296990b485lling			break;
297990b485lling
298990b485lling		case ZPOOL_PROP_BOOTFS:
299990b485lling			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
300990b485lling				error = ENOTSUP;
301990b485lling				break;
302990b485lling			}
303990b485lling
304990b485lling			/*
30515e6edfgw			 * Make sure the vdev config is bootable
306990b485lling			 */
30715e6edfgw			if (!vdev_is_bootable(spa->spa_root_vdev)) {
308990b485lling				error = ENOTSUP;
309990b485lling				break;
310990b485lling			}
311990b485lling
312990b485lling			reset_bootfs = 1;
313990b485lling
314990b485lling			error = nvpair_value_string(elem, &strval);
315990b485lling
316990b485lling			if (!error) {
31715e6edfgw				uint64_t compress;
31815e6edfgw
319990b485lling				if (strval == NULL || strval[0] == '\0') {
320990b485lling					objnum = zpool_prop_default_numeric(
321990b485lling					    ZPOOL_PROP_BOOTFS);
322990b485lling					break;
323990b485lling				}
324990b485lling
325990b485lling				if (error = dmu_objset_open(strval, DMU_OST_ZFS,
326745cd3cmaybee				    DS_MODE_USER | DS_MODE_READONLY, &os))
327990b485lling					break;
32815e6edfgw
32915e6edfgw				/* We don't support gzip bootable datasets */
33015e6edfgw				if ((error = dsl_prop_get_integer(strval,
33115e6edfgw				    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
33215e6edfgw				    &compress, NULL)) == 0 &&
33315e6edfgw				    !BOOTFS_COMPRESS_VALID(compress)) {
33415e6edfgw					error = ENOTSUP;
33515e6edfgw				} else {
33615e6edfgw					objnum = dmu_objset_id(os);
33715e6edfgw				}
338990b485lling				dmu_objset_close(os);
339990b485lling			}
340990b485lling			break;
3410a4e951gw		case ZPOOL_PROP_FAILUREMODE:
3420a4e951gw			error = nvpair_value_uint64(elem, &intval);
3430a4e951gw			if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
3440a4e951gw			    intval > ZIO_FAILURE_MODE_PANIC))
3450a4e951gw				error = EINVAL;
3460a4e951gw
3470a4e951gw			/*
3480a4e951gw			 * This is a special case which only occurs when
3490a4e951gw			 * the pool has completely failed. This allows
3500a4e951gw			 * the user to change the in-core failmode property
3510a4e951gw			 * without syncing it out to disk (I/Os might
3520a4e951gw			 * currently be blocked). We do this by returning
3530a4e951gw			 * EIO to the caller (spa_prop_set) to trick it
3540a4e951gw			 * into thinking we encountered a property validation
3550a4e951gw			 * error.
3560a4e951gw			 */
3570a4e951gw			if (!error && spa_state(spa) == POOL_STATE_IO_FAILURE) {
3580a4e951gw				spa->spa_failmode = intval;
3590a4e951gw				error = EIO;
3600a4e951gw			}
3610a4e951gw			break;
3622f8aaabeschrock
3632f8aaabeschrock		case ZPOOL_PROP_CACHEFILE:
3642f8aaabeschrock			if ((error = nvpair_value_string(elem, &strval)) != 0)
3652f8aaabeschrock				break;
3662f8aaabeschrock
3672f8aaabeschrock			if (strval[0] == '\0')
3682f8aaabeschrock				break;
3692f8aaabeschrock
3702f8aaabeschrock			if (strcmp(strval, "none") == 0)
3712f8aaabeschrock				break;
3722f8aaabeschrock
3732f8aaabeschrock			if (strval[0] != '/') {
3742f8aaabeschrock				error = EINVAL;
3752f8aaabeschrock				break;
3762f8aaabeschrock			}
3772f8aaabeschrock
3782f8aaabeschrock			slash = strrchr(strval, '/');
3792f8aaabeschrock			ASSERT(slash != NULL);
3802f8aaabeschrock
3812f8aaabeschrock			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
3822f8aaabeschrock			    strcmp(slash, "/..") == 0)
3832f8aaabeschrock				error = EINVAL;
3842f8aaabeschrock			break;
385990b485lling		}
386990b485lling
387990b485lling		if (error)
388990b485lling			break;
389990b485lling	}
390990b485lling
391990b485lling	if (!error && reset_bootfs) {
392990b485lling		error = nvlist_remove(props,
393990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING);
394990b485lling
395990b485lling		if (!error) {
396990b485lling			error = nvlist_add_uint64(props,
397990b485lling			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum);
398990b485lling		}
399990b485lling	}
400990b485lling
401990b485lling	return (error);
402990b485lling}
403990b485lling
404990b485llingint
405990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp)
406990b485lling{
407990b485lling	int error;
408990b485lling
409990b485lling	if ((error = spa_prop_validate(spa, nvp)) != 0)
410990b485lling		return (error);
411990b485lling
412990b485lling	return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props,
413990b485lling	    spa, nvp, 3));
414990b485lling}
415990b485lling
416990b485lling/*
417990b485lling * If the bootfs property value is dsobj, clear it.
418990b485lling */
419990b485llingvoid
420990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
421990b485lling{
422990b485lling	if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) {
423990b485lling		VERIFY(zap_remove(spa->spa_meta_objset,
424990b485lling		    spa->spa_pool_props_object,
425990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0);
426990b485lling		spa->spa_bootfs = 0;
427990b485lling	}
428990b485lling}
429990b485lling
430fa9e406ahrens/*
431fa9e406ahrens * ==========================================================================
432fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export)
433fa9e406ahrens * ==========================================================================
434fa9e406ahrens */
435fa9e406ahrens
436ea8dc4beschrockstatic int
437ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b)
438ea8dc4beschrock{
439ea8dc4beschrock	spa_error_entry_t *sa = (spa_error_entry_t *)a;
440ea8dc4beschrock	spa_error_entry_t *sb = (spa_error_entry_t *)b;
441ea8dc4beschrock	int ret;
442ea8dc4beschrock
443ea8dc4beschrock	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
444ea8dc4beschrock	    sizeof (zbookmark_t));
445ea8dc4beschrock
446ea8dc4beschrock	if (ret < 0)
447ea8dc4beschrock		return (-1);
448ea8dc4beschrock	else if (ret > 0)
449ea8dc4beschrock		return (1);
450ea8dc4beschrock	else
451ea8dc4beschrock		return (0);
452ea8dc4beschrock}
453ea8dc4beschrock
454ea8dc4beschrock/*
455ea8dc4beschrock * Utility function which retrieves copies of the current logs and
456ea8dc4beschrock * re-initializes them in the process.
457ea8dc4beschrock */
458ea8dc4beschrockvoid
459ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
460ea8dc4beschrock{
461ea8dc4beschrock	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
462ea8dc4beschrock
463ea8dc4beschrock	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
464ea8dc4beschrock	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
465ea8dc4beschrock
466ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
467ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
468ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
469ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
470ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
471ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
472ea8dc4beschrock}
473ea8dc4beschrock
474fa9e406ahrens/*
475fa9e406ahrens * Activate an uninitialized pool.
476fa9e406ahrens */
477fa9e406ahrensstatic void
478fa9e406ahrensspa_activate(spa_t *spa)
479fa9e406ahrens{
480fa9e406ahrens	int t;
481fa9e406ahrens
482fa9e406ahrens	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
483fa9e406ahrens
484fa9e406ahrens	spa->spa_state = POOL_STATE_ACTIVE;
485fa9e406ahrens
486fa9e406ahrens	spa->spa_normal_class = metaslab_class_create();
4878654d02perrin	spa->spa_log_class = metaslab_class_create();
488fa9e406ahrens
489fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
490fa9e406ahrens		spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue",
491416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
492fa9e406ahrens		    TASKQ_PREPOPULATE);
493fa9e406ahrens		spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr",
494416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
495fa9e406ahrens		    TASKQ_PREPOPULATE);
496fa9e406ahrens	}
497fa9e406ahrens
498fa9e406ahrens	list_create(&spa->spa_dirty_list, sizeof (vdev_t),
499fa9e406ahrens	    offsetof(vdev_t, vdev_dirty_node));
5000a4e951gw	list_create(&spa->spa_zio_list, sizeof (zio_t),
5010a4e951gw	    offsetof(zio_t, zio_link_node));
502fa9e406ahrens
503fa9e406ahrens	txg_list_create(&spa->spa_vdev_txg_list,
504fa9e406ahrens	    offsetof(struct vdev, vdev_txg_node));
505ea8dc4beschrock
506ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
507ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
508ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
509ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
510ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
511ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
512fa9e406ahrens}
513fa9e406ahrens
514fa9e406ahrens/*
515fa9e406ahrens * Opposite of spa_activate().
516fa9e406ahrens */
517fa9e406ahrensstatic void
518fa9e406ahrensspa_deactivate(spa_t *spa)
519fa9e406ahrens{
520fa9e406ahrens	int t;
521fa9e406ahrens
522fa9e406ahrens	ASSERT(spa->spa_sync_on == B_FALSE);
523fa9e406ahrens	ASSERT(spa->spa_dsl_pool == NULL);
524fa9e406ahrens	ASSERT(spa->spa_root_vdev == NULL);
525fa9e406ahrens
526fa9e406ahrens	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
527fa9e406ahrens
528fa9e406ahrens	txg_list_destroy(&spa->spa_vdev_txg_list);
529fa9e406ahrens
530fa9e406ahrens	list_destroy(&spa->spa_dirty_list);
5310a4e951gw	list_destroy(&spa->spa_zio_list);
532fa9e406ahrens
533fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
534fa9e406ahrens		taskq_destroy(spa->spa_zio_issue_taskq[t]);
535fa9e406ahrens		taskq_destroy(spa->spa_zio_intr_taskq[t]);
536fa9e406ahrens		spa->spa_zio_issue_taskq[t] = NULL;
537fa9e406ahrens		spa->spa_zio_intr_taskq[t] = NULL;
538fa9e406ahrens	}
539fa9e406ahrens
540fa9e406ahrens	metaslab_class_destroy(spa->spa_normal_class);
541fa9e406ahrens	spa->spa_normal_class = NULL;
542fa9e406ahrens
5438654d02perrin	metaslab_class_destroy(spa->spa_log_class);
5448654d02perrin	spa->spa_log_class = NULL;
5458654d02perrin
546ea8dc4beschrock	/*
547ea8dc4beschrock	 * If this was part of an import or the open otherwise failed, we may
548ea8dc4beschrock	 * still have errors left in the queues.  Empty them just in case.
549ea8dc4beschrock	 */
550ea8dc4beschrock	spa_errlog_drain(spa);
551ea8dc4beschrock
552ea8dc4beschrock	avl_destroy(&spa->spa_errlist_scrub);
553ea8dc4beschrock	avl_destroy(&spa->spa_errlist_last);
554ea8dc4beschrock
555fa9e406ahrens	spa->spa_state = POOL_STATE_UNINITIALIZED;
556fa9e406ahrens}
557fa9e406ahrens
558fa9e406ahrens/*
559fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately.  This
560fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev
561fa9e406ahrens * in the CLOSED state.  This will prep the pool before open/creation/import.
562fa9e406ahrens * All vdev validation is done by the vdev_alloc() routine.
563fa9e406ahrens */
56499653d4eschrockstatic int
56599653d4eschrockspa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
56699653d4eschrock    uint_t id, int atype)
567fa9e406ahrens{
568fa9e406ahrens	nvlist_t **child;
569fa9e406ahrens	uint_t c, children;
57099653d4eschrock	int error;
571fa9e406ahrens
57299653d4eschrock	if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0)
57399653d4eschrock		return (error);
574fa9e406ahrens
57599653d4eschrock	if ((*vdp)->vdev_ops->vdev_op_leaf)
57699653d4eschrock		return (0);
577fa9e406ahrens
578fa9e406ahrens	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
579fa9e406ahrens	    &child, &children) != 0) {
58099653d4eschrock		vdev_free(*vdp);
58199653d4eschrock		*vdp = NULL;
58299653d4eschrock		return (EINVAL);
583fa9e406ahrens	}
584fa9e406ahrens
585fa9e406ahrens	for (c = 0; c < children; c++) {
58699653d4eschrock		vdev_t *vd;
58799653d4eschrock		if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c,
58899653d4eschrock		    atype)) != 0) {
58999653d4eschrock			vdev_free(*vdp);
59099653d4eschrock			*vdp = NULL;
59199653d4eschrock			return (error);
592fa9e406ahrens		}
593fa9e406ahrens	}
594fa9e406ahrens
59599653d4eschrock	ASSERT(*vdp != NULL);
59699653d4eschrock
59799653d4eschrock	return (0);
598fa9e406ahrens}
599fa9e406ahrens
600fa9e406ahrens/*
601fa9e406ahrens * Opposite of spa_load().
602fa9e406ahrens */
603fa9e406ahrensstatic void
604fa9e406ahrensspa_unload(spa_t *spa)
605fa9e406ahrens{
60699653d4eschrock	int i;
60799653d4eschrock
608fa9e406ahrens	/*
609ea8dc4beschrock	 * Stop async tasks.
610