spa.c revision 8654d0253136055bd4cc2423d87378e8a37f2eb5
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
63416e0cdekint zio_taskq_threads = 8;
64416e0cdek
65fa9e406ahrens/*
66fa9e406ahrens * ==========================================================================
67fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export)
68fa9e406ahrens * ==========================================================================
69fa9e406ahrens */
70fa9e406ahrens
71ea8dc4beschrockstatic int
72ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b)
73ea8dc4beschrock{
74ea8dc4beschrock	spa_error_entry_t *sa = (spa_error_entry_t *)a;
75ea8dc4beschrock	spa_error_entry_t *sb = (spa_error_entry_t *)b;
76ea8dc4beschrock	int ret;
77ea8dc4beschrock
78ea8dc4beschrock	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
79ea8dc4beschrock	    sizeof (zbookmark_t));
80ea8dc4beschrock
81ea8dc4beschrock	if (ret < 0)
82ea8dc4beschrock		return (-1);
83ea8dc4beschrock	else if (ret > 0)
84ea8dc4beschrock		return (1);
85ea8dc4beschrock	else
86ea8dc4beschrock		return (0);
87ea8dc4beschrock}
88ea8dc4beschrock
89ea8dc4beschrock/*
90ea8dc4beschrock * Utility function which retrieves copies of the current logs and
91ea8dc4beschrock * re-initializes them in the process.
92ea8dc4beschrock */
93ea8dc4beschrockvoid
94ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
95ea8dc4beschrock{
96ea8dc4beschrock	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
97ea8dc4beschrock
98ea8dc4beschrock	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
99ea8dc4beschrock	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
100ea8dc4beschrock
101ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
102ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
103ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
104ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
105ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
106ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
107ea8dc4beschrock}
108ea8dc4beschrock
109fa9e406ahrens/*
110fa9e406ahrens * Activate an uninitialized pool.
111fa9e406ahrens */
112fa9e406ahrensstatic void
113fa9e406ahrensspa_activate(spa_t *spa)
114fa9e406ahrens{
115fa9e406ahrens	int t;
116fa9e406ahrens
117fa9e406ahrens	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
118fa9e406ahrens
119fa9e406ahrens	spa->spa_state = POOL_STATE_ACTIVE;
120fa9e406ahrens
121fa9e406ahrens	spa->spa_normal_class = metaslab_class_create();
1228654d02perrin	spa->spa_log_class = metaslab_class_create();
123fa9e406ahrens
124fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
125fa9e406ahrens		spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue",
126416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
127fa9e406ahrens		    TASKQ_PREPOPULATE);
128fa9e406ahrens		spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr",
129416e0cdek		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
130fa9e406ahrens		    TASKQ_PREPOPULATE);
131fa9e406ahrens	}
132fa9e406ahrens
133fa9e406ahrens	rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL);
134fa9e406ahrens
1355ad8204nd	mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
1365ad8204nd	mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL);
1375ad8204nd	mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
1385ad8204nd	mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
1395ad8204nd	mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
1405ad8204nd	mutex_init(&spa->spa_config_lock.scl_lock, NULL, MUTEX_DEFAULT, NULL);
1415ad8204nd	mutex_init(&spa->spa_sync_bplist.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
14206eeb2aek	mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
143b1b8ab3lling	mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
1445ad8204nd
145fa9e406ahrens	list_create(&spa->spa_dirty_list, sizeof (vdev_t),
146fa9e406ahrens	    offsetof(vdev_t, vdev_dirty_node));
147fa9e406ahrens
148fa9e406ahrens	txg_list_create(&spa->spa_vdev_txg_list,
149fa9e406ahrens	    offsetof(struct vdev, vdev_txg_node));
150ea8dc4beschrock
151ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
152ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
153ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
154ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
155ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
156ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
157fa9e406ahrens}
158fa9e406ahrens
159fa9e406ahrens/*
160fa9e406ahrens * Opposite of spa_activate().
161fa9e406ahrens */
162fa9e406ahrensstatic void
163fa9e406ahrensspa_deactivate(spa_t *spa)
164fa9e406ahrens{
165fa9e406ahrens	int t;
166fa9e406ahrens
167fa9e406ahrens	ASSERT(spa->spa_sync_on == B_FALSE);
168fa9e406ahrens	ASSERT(spa->spa_dsl_pool == NULL);
169fa9e406ahrens	ASSERT(spa->spa_root_vdev == NULL);
170fa9e406ahrens
171fa9e406ahrens	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
172fa9e406ahrens
173fa9e406ahrens	txg_list_destroy(&spa->spa_vdev_txg_list);
174fa9e406ahrens
175fa9e406ahrens	list_destroy(&spa->spa_dirty_list);
176fa9e406ahrens
177fa9e406ahrens	rw_destroy(&spa->spa_traverse_lock);
178fa9e406ahrens
179fa9e406ahrens	for (t = 0; t < ZIO_TYPES; t++) {
180fa9e406ahrens		taskq_destroy(spa->spa_zio_issue_taskq[t]);
181fa9e406ahrens		taskq_destroy(spa->spa_zio_intr_taskq[t]);
182fa9e406ahrens		spa->spa_zio_issue_taskq[t] = NULL;
183fa9e406ahrens		spa->spa_zio_intr_taskq[t] = NULL;
184fa9e406ahrens	}
185fa9e406ahrens
186fa9e406ahrens	metaslab_class_destroy(spa->spa_normal_class);
187fa9e406ahrens	spa->spa_normal_class = NULL;
188fa9e406ahrens
1898654d02perrin	metaslab_class_destroy(spa->spa_log_class);
1908654d02perrin	spa->spa_log_class = NULL;
1918654d02perrin
192ea8dc4beschrock	/*
193ea8dc4beschrock	 * If this was part of an import or the open otherwise failed, we may
194ea8dc4beschrock	 * still have errors left in the queues.  Empty them just in case.
195ea8dc4beschrock	 */
196ea8dc4beschrock	spa_errlog_drain(spa);
197ea8dc4beschrock
198ea8dc4beschrock	avl_destroy(&spa->spa_errlist_scrub);
199ea8dc4beschrock	avl_destroy(&spa->spa_errlist_last);
200ea8dc4beschrock
201fa9e406ahrens	spa->spa_state = POOL_STATE_UNINITIALIZED;
202fa9e406ahrens}
203fa9e406ahrens
204fa9e406ahrens/*
205fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately.  This
206fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev
207fa9e406ahrens * in the CLOSED state.  This will prep the pool before open/creation/import.
208fa9e406ahrens * All vdev validation is done by the vdev_alloc() routine.
209fa9e406ahrens */
21099653d4eschrockstatic int
21199653d4eschrockspa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
21299653d4eschrock    uint_t id, int atype)
213fa9e406ahrens{
214fa9e406ahrens	nvlist_t **child;
215fa9e406ahrens	uint_t c, children;
21699653d4eschrock	int error;
217fa9e406ahrens
21899653d4eschrock	if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0)
21999653d4eschrock		return (error);
220fa9e406ahrens
22199653d4eschrock	if ((*vdp)->vdev_ops->vdev_op_leaf)
22299653d4eschrock		return (0);
223fa9e406ahrens
224fa9e406ahrens	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
225fa9e406ahrens	    &child, &children) != 0) {
22699653d4eschrock		vdev_free(*vdp);
22799653d4eschrock		*vdp = NULL;
22899653d4eschrock		return (EINVAL);
229fa9e406ahrens	}
230fa9e406ahrens
231fa9e406ahrens	for (c = 0; c < children; c++) {
23299653d4eschrock		vdev_t *vd;
23399653d4eschrock		if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c,
23499653d4eschrock		    atype)) != 0) {
23599653d4eschrock			vdev_free(*vdp);
23699653d4eschrock			*vdp = NULL;
23799653d4eschrock			return (error);
238fa9e406ahrens		}
239fa9e406ahrens	}
240fa9e406ahrens
24199653d4eschrock	ASSERT(*vdp != NULL);
24299653d4eschrock
24399653d4eschrock	return (0);
244fa9e406ahrens}
245fa9e406ahrens
246fa9e406ahrens/*
247fa9e406ahrens * Opposite of spa_load().
248fa9e406ahrens */
249fa9e406ahrensstatic void
250fa9e406ahrensspa_unload(spa_t *spa)
251fa9e406ahrens{
25299653d4eschrock	int i;
25399653d4eschrock
254fa9e406ahrens	/*
255ea8dc4beschrock	 * Stop async tasks.
256ea8dc4beschrock	 */
257ea8dc4beschrock	spa_async_suspend(spa);
258ea8dc4beschrock
259ea8dc4beschrock	/*
260fa9e406ahrens	 * Stop syncing.
261fa9e406ahrens	 */
262fa9e406ahrens	if (spa->spa_sync_on) {
263fa9e406ahrens		txg_sync_stop(spa->spa_dsl_pool);
264fa9e406ahrens		spa->spa_sync_on = B_FALSE;
265fa9e406ahrens	}
266fa9e406ahrens
267fa9e406ahrens	/*
268fa9e406ahrens	 * Wait for any outstanding prefetch I/O to complete.
269fa9e406ahrens	 */
270ea8dc4beschrock	spa_config_enter(spa, RW_WRITER, FTAG);
271ea8dc4beschrock	spa_config_exit(spa, FTAG);
272fa9e406ahrens
273fa9e406ahrens	/*
274fa9e406ahrens	 * Close the dsl pool.
275fa9e406ahrens	 */
276fa9e406ahrens	if (spa->spa_dsl_pool) {
277fa9e406ahrens		dsl_pool_close(spa->spa_dsl_pool);
278fa9e406ahrens		spa->spa_dsl_pool = NULL;
279fa9e406ahrens	}
280fa9e406ahrens
281fa9e406ahrens	/*
282fa9e406ahrens	 * Close all vdevs.
283fa9e406ahrens	 */
2840e34b6abonwick	if (spa->spa_root_vdev)
285fa9e406ahrens		vdev_free(spa->spa_root_vdev);
2860e34b6abonwick	ASSERT(spa->spa_root_vdev == NULL);
287ea8dc4beschrock
28899653d4eschrock	for (i = 0; i < spa->spa_nspares; i++)
28999653d4eschrock		vdev_free(spa->spa_spares[i]);
29099653d4eschrock	if (spa->spa_spares) {
29199653d4eschrock		kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *));
29299653d4eschrock		spa->spa_spares = NULL;
29399653d4eschrock	}
29499653d4eschrock	if (spa->spa_sparelist) {
29599653d4eschrock		nvlist_free(spa->spa_sparelist);
29699653d4eschrock		spa->spa_sparelist = NULL;
29799653d4eschrock	}
29899653d4eschrock
299ea8dc4beschrock	spa->spa_async_suspended = 0;
300fa9e406ahrens}
301fa9e406ahrens
302fa9e406ahrens/*
30399653d4eschrock * Load (or re-load) the current list of vdevs describing the active spares for
30499653d4eschrock * this pool.  When this is called, we have some form of basic information in
30599653d4eschrock * 'spa_sparelist'.  We parse this into vdevs, try to open them, and then
30699653d4eschrock * re-generate a more complete list including status information.
30799653d4eschrock */
30899653d4eschrockstatic void
30999653d4eschrockspa_load_spares(spa_t *spa)
31099653d4eschrock{
31199653d4eschrock	nvlist_t **spares;
31299653d4eschrock	uint_t nspares;
31399653d4eschrock	int i;
31439c2341eschrock	vdev_t *vd, *tvd;
31599653d4eschrock
31699653d4eschrock	/*
31799653d4eschrock	 * First, close and free any existing spare vdevs.
31899653d4eschrock	 */
31999653d4eschrock	for (i = 0; i < spa->spa_nspares; i++) {
32039c2341eschrock		vd = spa->spa_spares[i];
32139c2341eschrock
32239c2341eschrock		/* Undo the call to spa_activate() below */
32339c2341eschrock		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL &&
32439c2341eschrock		    tvd->vdev_isspare)
32539c2341eschrock			spa_spare_remove(tvd);
32639c2341eschrock		vdev_close(vd);
32739c2341eschrock		vdev_free(vd);
32899653d4eschrock	}
32939c2341eschrock
33099653d4eschrock	if (spa->spa_spares)
33199653d4eschrock		kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *));
33299653d4eschrock
33399653d4eschrock	if (spa->spa_sparelist == NULL)
33499653d4eschrock		nspares = 0;
33599653d4eschrock	else
33699653d4eschrock		VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist,
33799653d4eschrock		    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
33899653d4eschrock
33999653d4eschrock	spa->spa_nspares = (int)nspares;
34099653d4eschrock	spa->spa_spares = NULL;
34199653d4eschrock
34299653d4eschrock	if (nspares == 0)
34399653d4eschrock		return;
34499653d4eschrock
34599653d4eschrock	/*
34699653d4eschrock	 * Construct the array of vdevs, opening them to get status in the
34739c2341eschrock	 * process.   For each spare, there is potentially two different vdev_t
34839c2341eschrock	 * structures associated with it: one in the list of spares (used only
34939c2341eschrock	 * for basic validation purposes) and one in the active vdev
35039c2341eschrock	 * configuration (if it's spared in).  During this phase we open and
35139c2341eschrock	 * validate each vdev on the spare list.  If the vdev also exists in the
35239c2341eschrock	 * active configuration, then we also mark this vdev as an active spare.
35399653d4eschrock	 */
35499653d4eschrock	spa->spa_spares = kmem_alloc(nspares * sizeof (void *), KM_SLEEP);
35599653d4eschrock	for (i = 0; i < spa->spa_nspares; i++) {
35699653d4eschrock		VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0,
35799653d4eschrock		    VDEV_ALLOC_SPARE) == 0);
35899653d4eschrock		ASSERT(vd != NULL);
35999653d4eschrock
36099653d4eschrock		spa->spa_spares[i] = vd;
36199653d4eschrock
36239c2341eschrock		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL) {
36339c2341eschrock			if (!tvd->vdev_isspare)
36439c2341eschrock				spa_spare_add(tvd);
36539c2341eschrock
36639c2341eschrock			/*
36739c2341eschrock			 * We only mark the spare active if we were successfully
36839c2341eschrock			 * able to load the vdev.  Otherwise, importing a pool
36939c2341eschrock			 * with a bad active spare would result in strange
37039c2341eschrock			 * behavior, because multiple pool would think the spare
37139c2341eschrock			 * is actively in use.
37239c2341eschrock			 *
37339c2341eschrock			 * There is a vulnerability here to an equally bizarre
37439c2341eschrock			 * circumstance, where a dead active spare is later
37539c2341eschrock			 * brought back to life (onlined or otherwise).  Given
37639c2341eschrock			 * the rarity of this scenario, and the extra complexity
37739c2341eschrock			 * it adds, we ignore the possibility.
37839c2341eschrock			 */
37939c2341eschrock			if (!vdev_is_dead(tvd))
38039c2341eschrock				spa_spare_activate(tvd);
38139c2341eschrock		}
38239c2341eschrock
38399653d4eschrock		if (vdev_open(vd) != 0)
38499653d4eschrock			continue;
38599653d4eschrock
38699653d4eschrock		vd->vdev_top = vd;
38799653d4eschrock		(void) vdev_validate_spare(vd);
38899653d4eschrock	}
38999653d4eschrock
39099653d4eschrock	/*
39199653d4eschrock	 * Recompute the stashed list of spares, with status information
39299653d4eschrock	 * this time.
39399653d4eschrock	 */
39499653d4eschrock	VERIFY(nvlist_remove(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
39599653d4eschrock	    DATA_TYPE_NVLIST_ARRAY) == 0);
39699653d4eschrock
39799653d4eschrock	spares = kmem_alloc(spa->spa_nspares * sizeof (void *), KM_SLEEP);
39899653d4eschrock	for (i = 0; i < spa->spa_nspares; i++)
39999653d4eschrock		spares[i] = vdev_config_generate(spa, spa->spa_spares[i],
40099653d4eschrock		    B_TRUE, B_TRUE);
40199653d4eschrock	VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
40299653d4eschrock	    spares, spa->spa_nspares) == 0);
40399653d4eschrock	for (i = 0; i < spa->spa_nspares; i++)
40499653d4eschrock		nvlist_free(spares[i]);
40599653d4eschrock	kmem_free(spares, spa->spa_nspares * sizeof (void *));
40699653d4eschrock}
40799653d4eschrock
40899653d4eschrockstatic int
40999653d4eschrockload_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value)
41099653d4eschrock{
41199653d4eschrock	dmu_buf_t *db;
41299653d4eschrock	char *packed = NULL;
41399653d4eschrock	size_t nvsize = 0;
41499653d4eschrock	int error;
41599653d4eschrock	*value = NULL;
41699653d4eschrock
41799653d4eschrock	VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
41899653d4eschrock	nvsize = *(uint64_t *)db->db_data;
41999653d4eschrock	dmu_buf_rele(db, FTAG);
42099653d4eschrock
42199653d4eschrock	packed = kmem_alloc(nvsize, KM_SLEEP);
42299653d4eschrock	error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed);
42399653d4eschrock	if (error == 0)
42499653d4eschrock		error = nvlist_unpack(packed, nvsize, value, 0);
42599653d4eschrock	kmem_free(packed, nvsize);
42699653d4eschrock
42799653d4eschrock	return (error);
42899653d4eschrock}
42999653d4eschrock
43099653d4eschrock/*
4313d7072feschrock * Checks to see if the given vdev could not be opened, in which case we post a
4323d7072feschrock * sysevent to notify the autoreplace code that the device has been removed.
4333d7072feschrock */
4343d7072feschrockstatic void
4353d7072feschrockspa_check_removed(vdev_t *vd)
4363d7072feschrock{
4373d7072feschrock	int c;
4383d7072feschrock
4393d7072feschrock	for (c = 0; c < vd->vdev_children; c++)
4403d7072feschrock		spa_check_removed(vd->vdev_child[c]);
4413d7072feschrock
4423d7072feschrock	if (vd->vdev_ops->vdev_op_leaf && vdev_is_dead(vd)) {
4433d7072feschrock		zfs_post_autoreplace(vd->vdev_spa, vd);
4443d7072feschrock		spa_event_notify(vd->vdev_spa, vd, ESC_ZFS_VDEV_CHECK);
4453d7072feschrock	}
4463d7072feschrock}
4473d7072feschrock
4483d7072feschrock/*
449fa9e406ahrens * Load an existing storage pool, using the pool's builtin spa_config as a
450ea8dc4beschrock * source of configuration information.
451fa9e406ahrens */
452fa9e406ahrensstatic int
453ea8dc4beschrockspa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
454fa9e406ahrens{
455fa9e406ahrens	int error = 0;
456fa9e406ahrens	nvlist_t *nvroot = NULL;
457fa9e406ahrens	vdev_t *rvd;
458fa9e406ahrens	uberblock_t *ub = &spa->spa_uberblock;
4590373e76bonwick	uint64_t config_cache_txg = spa->spa_config_txg;
460fa9e406ahrens	uint64_t pool_guid;
46199653d4eschrock	uint64_t version;
462fa9e406ahrens	zio_t *zio;
4633d7072feschrock	uint64_t autoreplace = 0;
464fa9e406ahrens
465ea8dc4beschrock	spa->spa_load_state = state;
4660373e76bonwick
467fa9e406ahrens	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) ||
468a9926bfbonwick	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid)) {
469ea8dc4beschrock		error = EINVAL;
470ea8dc4beschrock		goto out;
471ea8dc4beschrock	}
472fa9e406ahrens
47399653d4eschrock	/*
47499653d4eschrock	 * Versioning wasn't explicitly added to the label until later, so if
47599653d4eschrock	 * it's not present treat it as the initial version.
47699653d4eschrock	 */
47799653d4eschrock	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) != 0)
47899653d4eschrock		version = ZFS_VERSION_INITIAL;
47999653d4eschrock
480a9926bfbonwick	(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
481a9926bfbonwick	    &spa->spa_config_txg);
482a9926bfbonwick
4830373e76bonwick	if ((state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT) &&
484ea8dc4beschrock	    spa_guid_exists(pool_guid, 0)) {
485