spa.c revision 5679c89fcd2facbb4334df8870d3d7a4d2b11673
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/*
23379c004Eric Schrock * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24fa9e406ahrens * Use is subject to license terms.
25fa9e406ahrens */
26fa9e406ahrens
27fa9e406ahrens/*
28fa9e406ahrens * This file contains all the routines used when modifying on-disk SPA state.
29fa9e406ahrens * This includes opening, importing, destroying, exporting a pool, and syncing a
30fa9e406ahrens * pool.
31fa9e406ahrens */
32fa9e406ahrens
33fa9e406ahrens#include <sys/zfs_context.h>
34ea8dc4beschrock#include <sys/fm/fs/zfs.h>
35fa9e406ahrens#include <sys/spa_impl.h>
36fa9e406ahrens#include <sys/zio.h>
37fa9e406ahrens#include <sys/zio_checksum.h>
38fa9e406ahrens#include <sys/zio_compress.h>
39fa9e406ahrens#include <sys/dmu.h>
40fa9e406ahrens#include <sys/dmu_tx.h>
41fa9e406ahrens#include <sys/zap.h>
42fa9e406ahrens#include <sys/zil.h>
43fa9e406ahrens#include <sys/vdev_impl.h>
44fa9e406ahrens#include <sys/metaslab.h>
45fa9e406ahrens#include <sys/uberblock_impl.h>
46fa9e406ahrens#include <sys/txg.h>
47fa9e406ahrens#include <sys/avl.h>
48fa9e406ahrens#include <sys/dmu_traverse.h>
49b1b8ab3lling#include <sys/dmu_objset.h>
50fa9e406ahrens#include <sys/unique.h>
51fa9e406ahrens#include <sys/dsl_pool.h>
52b1b8ab3lling#include <sys/dsl_dataset.h>
53fa9e406ahrens#include <sys/dsl_dir.h>
54fa9e406ahrens#include <sys/dsl_prop.h>
55b1b8ab3lling#include <sys/dsl_synctask.h>
56fa9e406ahrens#include <sys/fs/zfs.h>
57fa94a07brendan#include <sys/arc.h>
58fa9e406ahrens#include <sys/callb.h>
599517395ek#include <sys/systeminfo.h>
609517395ek#include <sys/sunddi.h>
61e7cbe64gw#include <sys/spa_boot.h>
62fa9e406ahrens
635679c89jv#ifdef	_KERNEL
645679c89jv#include <sys/zone.h>
655679c89jv#endif	/* _KERNEL */
665679c89jv
67990b485lling#include "zfs_prop.h"
68b7b9745perrin#include "zfs_comutil.h"
69990b485lling
70e14bb32Jeff Bonwickint zio_taskq_threads[ZIO_TYPES][ZIO_TASKQ_TYPES] = {
71e14bb32Jeff Bonwick	/*	ISSUE	INTR					*/
72e14bb32Jeff Bonwick	{	1,	1	},	/* ZIO_TYPE_NULL	*/
73e14bb32Jeff Bonwick	{	1,	8	},	/* ZIO_TYPE_READ	*/
74e14bb32Jeff Bonwick	{	8,	1	},	/* ZIO_TYPE_WRITE	*/
75e14bb32Jeff Bonwick	{	1,	1	},	/* ZIO_TYPE_FREE	*/
76e14bb32Jeff Bonwick	{	1,	1	},	/* ZIO_TYPE_CLAIM	*/
77e14bb32Jeff Bonwick	{	1,	1	},	/* ZIO_TYPE_IOCTL	*/
78e14bb32Jeff Bonwick};
79416e0cdek
80990b485llingstatic void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx);
8189a89ebllingstatic boolean_t spa_has_active_shared_spare(spa_t *spa);
82990b485lling
83990b485lling/*
84990b485lling * ==========================================================================
85990b485lling * SPA properties routines
86990b485lling * ==========================================================================
87990b485lling */
88990b485lling
89990b485lling/*
90990b485lling * Add a (source=src, propname=propval) list to an nvlist.
91990b485lling */
929d82f4fllingstatic void
93990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval,
94990b485lling    uint64_t intval, zprop_source_t src)
95990b485lling{
96990b485lling	const char *propname = zpool_prop_to_name(prop);
97990b485lling	nvlist_t *propval;
98990b485lling
999d82f4flling	VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1009d82f4flling	VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0);
101990b485lling
1029d82f4flling	if (strval != NULL)
1039d82f4flling		VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0);
1049d82f4flling	else
1059d82f4flling		VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, intval) == 0);
106990b485lling
1079d82f4flling	VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0);
108990b485lling	nvlist_free(propval);
109990b485lling}
110990b485lling
111990b485lling/*
112990b485lling * Get property values from the spa configuration.
113990b485lling */
1149d82f4fllingstatic void
115990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp)
116990b485lling{
117379c004Eric Schrock	uint64_t size;
118379c004Eric Schrock	uint64_t used;
119990b485lling	uint64_t cap, version;
120990b485lling	zprop_source_t src = ZPROP_SRC_NONE;
121c5904d1eschrock	spa_config_dirent_t *dp;
122990b485lling
123e14bb32Jeff Bonwick	ASSERT(MUTEX_HELD(&spa->spa_props_lock));
124e14bb32Jeff Bonwick
125379c004Eric Schrock	if (spa->spa_root_vdev != NULL) {
126379c004Eric Schrock		size = spa_get_space(spa);
127379c004Eric Schrock		used = spa_get_alloc(spa);
128379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src);
129379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src);
130379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src);
131379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL,
132379c004Eric Schrock		    size - used, src);
133379c004Eric Schrock
134379c004Eric Schrock		cap = (size == 0) ? 0 : (used * 100 / size);
135379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src);
136379c004Eric Schrock
137379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
138379c004Eric Schrock		    spa->spa_root_vdev->vdev_state, src);
139379c004Eric Schrock
140379c004Eric Schrock		version = spa_version(spa);
141379c004Eric Schrock		if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))
142379c004Eric Schrock			src = ZPROP_SRC_DEFAULT;
143379c004Eric Schrock		else
144379c004Eric Schrock			src = ZPROP_SRC_LOCAL;
145379c004Eric Schrock		spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
146379c004Eric Schrock	}
147990b485lling
1489d82f4flling	spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src);
149990b485lling
1509d82f4flling	if (spa->spa_root != NULL)
1519d82f4flling		spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root,
1529d82f4flling		    0, ZPROP_SRC_LOCAL);
153990b485lling
154c5904d1eschrock	if ((dp = list_head(&spa->spa_config_list)) != NULL) {
155c5904d1eschrock		if (dp->scd_path == NULL) {
1569d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
157c5904d1eschrock			    "none", 0, ZPROP_SRC_LOCAL);
158c5904d1eschrock		} else if (strcmp(dp->scd_path, spa_config_path) != 0) {
1599d82f4flling			spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE,
160c5904d1eschrock			    dp->scd_path, 0, ZPROP_SRC_LOCAL);
1612f8aaabeschrock		}
1622f8aaabeschrock	}
163990b485lling}
164990b485lling
165990b485lling/*
166990b485lling * Get zpool property values.
167990b485lling */
168990b485llingint
169990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp)
170990b485lling{
171990b485lling	zap_cursor_t zc;
172990b485lling	zap_attribute_t za;
173990b485lling	objset_t *mos = spa->spa_meta_objset;
174990b485lling	int err;
175990b485lling
1769d82f4flling	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
177990b485lling
178e14bb32Jeff Bonwick	mutex_enter(&spa->spa_props_lock);
179e14bb32Jeff Bonwick
180990b485lling	/*
181990b485lling	 * Get properties from the spa config.
182990b485lling	 */
1839d82f4flling	spa_prop_get_config(spa, nvp);
184990b485lling
185990b485lling	/* If no pool property object, no more prop to get. */
186990b485lling	if (spa->spa_pool_props_object == 0) {
187990b485lling		mutex_exit(&spa->spa_props_lock);
188990b485lling		return (0);
189990b485lling	}
190990b485lling
191990b485lling	/*
192990b485lling	 * Get properties from the MOS pool property object.
193990b485lling	 */
194990b485lling	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
195990b485lling	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
196990b485lling	    zap_cursor_advance(&zc)) {
197990b485lling		uint64_t intval = 0;
198990b485lling		char *strval = NULL;
199990b485lling		zprop_source_t src = ZPROP_SRC_DEFAULT;
200990b485lling		zpool_prop_t prop;
201990b485lling
202990b485lling		if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL)
203990b485lling			continue;
204990b485lling
205990b485lling		switch (za.za_integer_length) {
206990b485lling		case 8:
207990b485lling			/* integer property */
208990b485lling			if (za.za_first_integer !=
209990b485lling			    zpool_prop_default_numeric(prop))
210990b485lling				src = ZPROP_SRC_LOCAL;
211990b485lling
212990b485lling			if (prop == ZPOOL_PROP_BOOTFS) {
213990b485lling				dsl_pool_t *dp;
214990b485lling				dsl_dataset_t *ds = NULL;
215990b485lling
216990b485lling				dp = spa_get_dsl(spa);
217990b485lling				rw_enter(&dp->dp_config_rwlock, RW_READER);
218745cd3cmaybee				if (err = dsl_dataset_hold_obj(dp,
219745cd3cmaybee				    za.za_first_integer, FTAG, &ds)) {
220990b485lling					rw_exit(&dp->dp_config_rwlock);
221990b485lling					break;
222990b485lling				}
223990b485lling
224990b485lling				strval = kmem_alloc(
225990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
226990b485lling				    KM_SLEEP);
227990b485lling				dsl_dataset_name(ds, strval);
228745cd3cmaybee				dsl_dataset_rele(ds, FTAG);
229990b485lling				rw_exit(&dp->dp_config_rwlock);
230990b485lling			} else {
231990b485lling				strval = NULL;
232990b485lling				intval = za.za_first_integer;
233990b485lling			}
234990b485lling
2359d82f4flling			spa_prop_add_list(*nvp, prop, strval, intval, src);
236990b485lling
237990b485lling			if (strval != NULL)
238990b485lling				kmem_free(strval,
239990b485lling				    MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
240990b485lling
241990b485lling			break;
242990b485lling
243990b485lling		case 1:
244990b485lling			/* string property */
245990b485lling			strval = kmem_alloc(za.za_num_integers, KM_SLEEP);
246990b485lling			err = zap_lookup(mos, spa->spa_pool_props_object,
247990b485lling			    za.za_name, 1, za.za_num_integers, strval);
248990b485lling			if (err) {
249990b485lling				kmem_free(strval, za.za_num_integers);
250990b485lling				break;
251990b485lling			}
2529d82f4flling			spa_prop_add_list(*nvp, prop, strval, 0, src);
253990b485lling			kmem_free(strval, za.za_num_integers);
254990b485lling			break;
255990b485lling
256990b485lling		default:
257990b485lling			break;
258990b485lling		}
259990b485lling	}
260990b485lling	zap_cursor_fini(&zc);
261990b485lling	mutex_exit(&spa->spa_props_lock);
262990b485llingout:
263990b485lling	if (err && err != ENOENT) {
264990b485lling		nvlist_free(*nvp);
2659d82f4flling		*nvp = NULL;
266990b485lling		return (err);
267990b485lling	}
268990b485lling
269990b485lling	return (0);
270990b485lling}
271990b485lling
272990b485lling/*
273990b485lling * Validate the given pool properties nvlist and modify the list
274990b485lling * for the property values to be set.
275990b485lling */
276990b485llingstatic int
277990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props)
278990b485lling{
279990b485lling	nvpair_t *elem;
280990b485lling	int error = 0, reset_bootfs = 0;
281990b485lling	uint64_t objnum;
282990b485lling
283990b485lling	elem = NULL;
284990b485lling	while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
285990b485lling		zpool_prop_t prop;
286990b485lling		char *propname, *strval;
287990b485lling		uint64_t intval;
288990b485lling		objset_t *os;
2892f8aaabeschrock		char *slash;
290990b485lling
291990b485lling		propname = nvpair_name(elem);
292990b485lling
293990b485lling		if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL)
294990b485lling			return (EINVAL);
295990b485lling
296990b485lling		switch (prop) {
297990b485lling		case ZPOOL_PROP_VERSION:
298990b485lling			error = nvpair_value_uint64(elem, &intval);
299990b485lling			if (!error &&
300990b485lling			    (intval < spa_version(spa) || intval > SPA_VERSION))
301990b485lling				error = EINVAL;
302990b485lling			break;
303990b485lling
304990b485lling		case ZPOOL_PROP_DELEGATION:
305990b485lling		case ZPOOL_PROP_AUTOREPLACE:
306d5b5bb2Rich Morris		case ZPOOL_PROP_LISTSNAPS:
307990b485lling			error = nvpair_value_uint64(elem, &intval);
308990b485lling			if (!error && intval > 1)
309990b485lling				error = EINVAL;
310990b485lling			break;
311990b485lling
312990b485lling		case ZPOOL_PROP_BOOTFS:
313990b485lling			if (spa_version(spa) < SPA_VERSION_BOOTFS) {
314990b485lling				error = ENOTSUP;
315990b485lling				break;
316990b485lling			}
317990b485lling
318990b485lling			/*
31915e6edfgw			 * Make sure the vdev config is bootable
320990b485lling			 */
32115e6edfgw			if (!vdev_is_bootable(spa->spa_root_vdev)) {
322990b485lling				error = ENOTSUP;
323990b485lling				break;
324990b485lling			}
325990b485lling
326990b485lling			reset_bootfs = 1;
327990b485lling
328990b485lling			error = nvpair_value_string(elem, &strval);
329990b485lling
330990b485lling			if (!error) {
33115e6edfgw				uint64_t compress;
33215e6edfgw
333990b485lling				if (strval == NULL || strval[0] == '\0') {
334990b485lling					objnum = zpool_prop_default_numeric(
335990b485lling					    ZPOOL_PROP_BOOTFS);
336990b485lling					break;
337990b485lling				}
338990b485lling
339990b485lling				if (error = dmu_objset_open(strval, DMU_OST_ZFS,
340745cd3cmaybee				    DS_MODE_USER | DS_MODE_READONLY, &os))
341990b485lling					break;
34215e6edfgw
34315e6edfgw				/* We don't support gzip bootable datasets */
34415e6edfgw				if ((error = dsl_prop_get_integer(strval,
34515e6edfgw				    zfs_prop_to_name(ZFS_PROP_COMPRESSION),
34615e6edfgw				    &compress, NULL)) == 0 &&
34715e6edfgw				    !BOOTFS_COMPRESS_VALID(compress)) {
34815e6edfgw					error = ENOTSUP;
34915e6edfgw				} else {
35015e6edfgw					objnum = dmu_objset_id(os);
35115e6edfgw				}
352990b485lling				dmu_objset_close(os);
353990b485lling			}
354990b485lling			break;
355e14bb32Jeff Bonwick
3560a4e951gw		case ZPOOL_PROP_FAILUREMODE:
3570a4e951gw			error = nvpair_value_uint64(elem, &intval);
3580a4e951gw			if (!error && (intval < ZIO_FAILURE_MODE_WAIT ||
3590a4e951gw			    intval > ZIO_FAILURE_MODE_PANIC))
3600a4e951gw				error = EINVAL;
3610a4e951gw
3620a4e951gw			/*
3630a4e951gw			 * This is a special case which only occurs when
3640a4e951gw			 * the pool has completely failed. This allows
3650a4e951gw			 * the user to change the in-core failmode property
3660a4e951gw			 * without syncing it out to disk (I/Os might
3670a4e951gw			 * currently be blocked). We do this by returning
3680a4e951gw			 * EIO to the caller (spa_prop_set) to trick it
3690a4e951gw			 * into thinking we encountered a property validation
3700a4e951gw			 * error.
3710a4e951gw			 */
372e14bb32Jeff Bonwick			if (!error && spa_suspended(spa)) {
3730a4e951gw				spa->spa_failmode = intval;
3740a4e951gw				error = EIO;
3750a4e951gw			}
3760a4e951gw			break;
3772f8aaabeschrock
3782f8aaabeschrock		case ZPOOL_PROP_CACHEFILE:
3792f8aaabeschrock			if ((error = nvpair_value_string(elem, &strval)) != 0)
3802f8aaabeschrock				break;
3812f8aaabeschrock
3822f8aaabeschrock			if (strval[0] == '\0')
3832f8aaabeschrock				break;
3842f8aaabeschrock
3852f8aaabeschrock			if (strcmp(strval, "none") == 0)
3862f8aaabeschrock				break;
3872f8aaabeschrock
3882f8aaabeschrock			if (strval[0] != '/') {
3892f8aaabeschrock				error = EINVAL;
3902f8aaabeschrock				break;
3912f8aaabeschrock			}
3922f8aaabeschrock
3932f8aaabeschrock			slash = strrchr(strval, '/');
3942f8aaabeschrock			ASSERT(slash != NULL);
3952f8aaabeschrock
3962f8aaabeschrock			if (slash[1] == '\0' || strcmp(slash, "/.") == 0 ||
3972f8aaabeschrock			    strcmp(slash, "/..") == 0)
3982f8aaabeschrock				error = EINVAL;
3992f8aaabeschrock			break;
400990b485lling		}
401990b485lling
402990b485lling		if (error)
403990b485lling			break;
404990b485lling	}
405990b485lling
406990b485lling	if (!error && reset_bootfs) {
407990b485lling		error = nvlist_remove(props,
408990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING);
409990b485lling
410990b485lling		if (!error) {
411990b485lling			error = nvlist_add_uint64(props,
412990b485lling			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum);
413990b485lling		}
414990b485lling	}
415990b485lling
416990b485lling	return (error);
417990b485lling}
418990b485lling
419379c004Eric Schrockvoid
420379c004Eric Schrockspa_configfile_set(spa_t *spa, nvlist_t *nvp, boolean_t need_sync)
421379c004Eric Schrock{
422379c004Eric Schrock	char *cachefile;
423379c004Eric Schrock	spa_config_dirent_t *dp;
424379c004Eric Schrock
425379c004Eric Schrock	if (nvlist_lookup_string(nvp, zpool_prop_to_name(ZPOOL_PROP_CACHEFILE),
426379c004Eric Schrock	    &cachefile) != 0)
427379c004Eric Schrock		return;
428379c004Eric Schrock
429379c004Eric Schrock	dp = kmem_alloc(sizeof (spa_config_dirent_t),
430379c004Eric Schrock	    KM_SLEEP);
431379c004Eric Schrock
432379c004Eric Schrock	if (cachefile[0] == '\0')
433379c004Eric Schrock		dp->scd_path = spa_strdup(spa_config_path);
434379c004Eric Schrock	else if (strcmp(cachefile, "none") == 0)
435379c004Eric Schrock		dp->scd_path = NULL;
436379c004Eric Schrock	else
437379c004Eric Schrock		dp->scd_path = spa_strdup(cachefile);
438379c004Eric Schrock
439379c004Eric Schrock	list_insert_head(&spa->spa_config_list, dp);
440379c004Eric Schrock	if (need_sync)
441379c004Eric Schrock		spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
442379c004Eric Schrock}
443379c004Eric Schrock
444990b485llingint
445990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp)
446990b485lling{
447990b485lling	int error;
448379c004Eric Schrock	nvpair_t *elem;
449379c004Eric Schrock	boolean_t need_sync = B_FALSE;
450379c004Eric Schrock	zpool_prop_t prop;
451990b485lling
452990b485lling	if ((error = spa_prop_validate(spa, nvp)) != 0)
453990b485lling		return (error);
454990b485lling
455379c004Eric Schrock	elem = NULL;
456379c004Eric Schrock	while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) {
457379c004Eric Schrock		if ((prop = zpool_name_to_prop(
458379c004Eric Schrock		    nvpair_name(elem))) == ZPROP_INVAL)
459379c004Eric Schrock			return (EINVAL);
460379c004Eric Schrock
461379c004Eric Schrock		if (prop == ZPOOL_PROP_CACHEFILE || prop == ZPOOL_PROP_ALTROOT)
462379c004Eric Schrock			continue;
463379c004Eric Schrock
464379c004Eric Schrock		need_sync = B_TRUE;
465379c004Eric Schrock		break;
466379c004Eric Schrock	}
467379c004Eric Schrock
468379c004Eric Schrock	if (need_sync)
469379c004Eric Schrock		return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props,
470379c004Eric Schrock		    spa, nvp, 3));
471379c004Eric Schrock	else
472379c004Eric Schrock		return (0);
473990b485lling}
474990b485lling
475990b485lling/*
476990b485lling * If the bootfs property value is dsobj, clear it.
477990b485lling */
478990b485llingvoid
479990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
480990b485lling{
481990b485lling	if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) {
482990b485lling		VERIFY(zap_remove(spa->spa_meta_objset,
483990b485lling		    spa->spa_pool_props_object,
484990b485lling		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0);
485990b485lling		spa->spa_bootfs = 0;
486990b485lling	}
487990b485lling}
488990b485lling
489fa9e406ahrens/*
490fa9e406ahrens * ==========================================================================
491fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export)
492fa9e406ahrens * ==========================================================================
493fa9e406ahrens */
494fa9e406ahrens
495ea8dc4beschrockstatic int
496ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b)
497ea8dc4beschrock{
498ea8dc4beschrock	spa_error_entry_t *sa = (spa_error_entry_t *)a;
499ea8dc4beschrock	spa_error_entry_t *sb = (spa_error_entry_t *)b;
500ea8dc4beschrock	int ret;
501ea8dc4beschrock
502ea8dc4beschrock	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
503ea8dc4beschrock	    sizeof (zbookmark_t));
504ea8dc4beschrock
505ea8dc4beschrock	if (ret < 0)
506ea8dc4beschrock		return (-1);
507ea8dc4beschrock	else if (ret > 0)
508ea8dc4beschrock		return (1);
509ea8dc4beschrock	else
510ea8dc4beschrock		return (0);
511ea8dc4beschrock}
512ea8dc4beschrock
513ea8dc4beschrock/*
514ea8dc4beschrock * Utility function which retrieves copies of the current logs and
515ea8dc4beschrock * re-initializes them in the process.
516ea8dc4beschrock */
517ea8dc4beschrockvoid
518ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
519ea8dc4beschrock{
520ea8dc4beschrock	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
521ea8dc4beschrock
522ea8dc4beschrock	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
523ea8dc4beschrock	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
524ea8dc4beschrock
525ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
526ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
527ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
528ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
529ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
530ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
531ea8dc4beschrock}
532ea8dc4beschrock
533fa9e406ahrens/*
534fa9e406ahrens * Activate an uninitialized pool.
535fa9e406ahrens */
536fa9e406ahrensstatic void
5378ad4d6dJeff Bonwickspa_activate(spa_t *spa, int mode)
538fa9e406ahrens{
539fa9e406ahrens	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
540fa9e406ahrens
541fa9e406ahrens	spa->spa_state = POOL_STATE_ACTIVE;
5428ad4d6dJeff Bonwick	spa->spa_mode = mode;
543fa9e406ahrens
544fa9e406ahrens	spa->spa_normal_class = metaslab_class_create();
5458654d02perrin	spa->spa_log_class = metaslab_class_create();
546fa9e406ahrens
547e14bb32Jeff Bonwick	for (int t = 0; t < ZIO_TYPES; t++) {
548e14bb32Jeff Bonwick		for (int q = 0; q < ZIO_TASKQ_TYPES; q++) {
549e14bb32Jeff Bonwick			spa->spa_zio_taskq[t][q] = taskq_create("spa_zio",
550e14bb32Jeff Bonwick			    zio_taskq_threads[t][q], maxclsyspri, 50,
551e14bb32Jeff Bonwick			    INT_MAX, TASKQ_PREPOPULATE);
552e14bb32Jeff Bonwick		}
553fa9e406ahrens	}
554fa9e406ahrens
555e14bb32Jeff Bonwick	list_create(&spa->spa_config_dirty_list, sizeof (vdev_t),
556e14bb32Jeff Bonwick	    offsetof(vdev_t, vdev_config_dirty_node));
557e14bb32Jeff Bonwick	list_create(&spa->spa_state_dirty_list, sizeof (vdev_t),
558e14bb32Jeff Bonwick	    offsetof(vdev_t, vdev_state_dirty_node));
559fa9e406ahrens
560fa9e406ahrens	txg_list_create(&spa->spa_vdev_txg_list,
561fa9e406ahrens	    offsetof(struct vdev, vdev_txg_node));
562ea8dc4beschrock
563ea8dc4beschrock	avl_create(&spa->spa_errlist_scrub,
564ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
565ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
566ea8dc4beschrock	avl_create(&spa->spa_errlist_last,
567ea8dc4beschrock	    spa_error_entry_compare, sizeof (spa_error_entry_t),
568ea8dc4beschrock	    offsetof(spa_error_entry_t, se_avl));
569fa9e406ahrens}
570fa9e406ahrens
571fa9e406ahrens/*
572fa9e406ahrens * Opposite of spa_activate().
573fa9e406ahrens */
574fa9e406ahrensstatic void
575fa9e406ahrensspa_deactivate(spa_t *spa)
576fa9e406ahrens{
577fa9e406ahrens	ASSERT(spa->spa_sync_on == B_FALSE);
578fa9e406ahrens	ASSERT(spa->spa_dsl_pool == NULL);
579fa9e406ahrens	ASSERT(spa->spa_root_vdev == NULL);
580fa9e406ahrens
581fa9e406ahrens	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
582fa9e406ahrens
583fa9e406ahrens	txg_list_destroy(&spa->spa_vdev_txg_list);
584fa9e406ahrens
585e14bb32Jeff Bonwick	list_destroy(&spa->spa_config_dirty_list);
586e14bb32Jeff Bonwick	list_destroy(&spa->spa_state_dirty_list);
587fa9e406ahrens
588e14bb32Jeff Bonwick	for (int t = 0; t < ZIO_TYPES; t++) {
589e14bb32Jeff Bonwick		for (int q = 0; q < ZIO_TASKQ_TYPES; q++) {
590e14bb32Jeff Bonwick			taskq_destroy(spa->spa_zio_taskq[t][q]);
591e14bb32Jeff Bonwick			spa->spa_zio_taskq[t][q] = NULL;
592e14bb32Jeff Bonwick		}
593fa9e406ahrens	}
594fa9e406ahrens
595fa9e406ahrens	metaslab_class_destroy(spa->spa_normal_class);
596fa9e406ahrens	spa->spa_normal_class = NULL;
597fa9e406ahrens
5988654d02perrin	metaslab_class_destroy(spa->spa_log_class);
5998654d02perrin	spa->spa_log_class = NULL;
6008654d02perrin
601ea8dc4beschrock	/*
602ea8dc4beschrock	 * If this was part of an import or the open otherwise failed, we may
603ea8dc4beschrock	 * still have errors left in the queues.  Empty them just in case.
604ea8dc4beschrock	 */
605ea8dc4beschrock	spa_errlog_drain(spa);
606ea8dc4beschrock
607ea8dc4beschrock	avl_destroy(&spa->spa_errlist_scrub);
608ea8dc4beschrock	avl_destroy(&spa->spa_errlist_last);
609ea8dc4beschrock
610fa9e406ahrens	spa->spa_state = POOL_STATE_UNINITIALIZED;
611fa9e406ahrens}
612fa9e406ahrens
613fa9e406ahrens/*
614fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately.  This
615fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev
616fa9e406ahrens * in the CLOSED state.  This will prep the pool before open/creation/import.
617fa9e406ahrens * All vdev validation is done by the vdev_alloc() routine.
618fa9e406ahrens */
61999653d4eschrockstatic int
62099653d4eschrockspa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
621