spa.c revision 95173954d2b811ceb583a9012c3b16e1d0dd6438
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(); 122fa9e406ahrens 123fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 124fa9e406ahrens spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue", 125416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 126fa9e406ahrens TASKQ_PREPOPULATE); 127fa9e406ahrens spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr", 128416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 129fa9e406ahrens TASKQ_PREPOPULATE); 130fa9e406ahrens } 131fa9e406ahrens 132fa9e406ahrens rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL); 133fa9e406ahrens 1345ad8204nd mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL); 1355ad8204nd mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL); 1365ad8204nd mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL); 1375ad8204nd mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL); 1385ad8204nd mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL); 1395ad8204nd mutex_init(&spa->spa_config_lock.scl_lock, NULL, MUTEX_DEFAULT, NULL); 1405ad8204nd mutex_init(&spa->spa_sync_bplist.bpl_lock, NULL, MUTEX_DEFAULT, NULL); 14106eeb2aek mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL); 142b1b8ab3lling mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL); 1435ad8204nd 144fa9e406ahrens list_create(&spa->spa_dirty_list, sizeof (vdev_t), 145fa9e406ahrens offsetof(vdev_t, vdev_dirty_node)); 146fa9e406ahrens 147fa9e406ahrens txg_list_create(&spa->spa_vdev_txg_list, 148fa9e406ahrens offsetof(struct vdev, vdev_txg_node)); 149ea8dc4beschrock 150ea8dc4beschrock avl_create(&spa->spa_errlist_scrub, 151ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 152ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 153ea8dc4beschrock avl_create(&spa->spa_errlist_last, 154ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 155ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 156fa9e406ahrens} 157fa9e406ahrens 158fa9e406ahrens/* 159fa9e406ahrens * Opposite of spa_activate(). 160fa9e406ahrens */ 161fa9e406ahrensstatic void 162fa9e406ahrensspa_deactivate(spa_t *spa) 163fa9e406ahrens{ 164fa9e406ahrens int t; 165fa9e406ahrens 166fa9e406ahrens ASSERT(spa->spa_sync_on == B_FALSE); 167fa9e406ahrens ASSERT(spa->spa_dsl_pool == NULL); 168fa9e406ahrens ASSERT(spa->spa_root_vdev == NULL); 169fa9e406ahrens 170fa9e406ahrens ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED); 171fa9e406ahrens 172fa9e406ahrens txg_list_destroy(&spa->spa_vdev_txg_list); 173fa9e406ahrens 174fa9e406ahrens list_destroy(&spa->spa_dirty_list); 175fa9e406ahrens 176fa9e406ahrens rw_destroy(&spa->spa_traverse_lock); 177fa9e406ahrens 178fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 179fa9e406ahrens taskq_destroy(spa->spa_zio_issue_taskq[t]); 180fa9e406ahrens taskq_destroy(spa->spa_zio_intr_taskq[t]); 181fa9e406ahrens spa->spa_zio_issue_taskq[t] = NULL; 182fa9e406ahrens spa->spa_zio_intr_taskq[t] = NULL; 183fa9e406ahrens } 184fa9e406ahrens 185fa9e406ahrens metaslab_class_destroy(spa->spa_normal_class); 186fa9e406ahrens spa->spa_normal_class = NULL; 187fa9e406ahrens 188ea8dc4beschrock /* 189ea8dc4beschrock * If this was part of an import or the open otherwise failed, we may 190ea8dc4beschrock * still have errors left in the queues. Empty them just in case. 191ea8dc4beschrock */ 192ea8dc4beschrock spa_errlog_drain(spa); 193ea8dc4beschrock 194ea8dc4beschrock avl_destroy(&spa->spa_errlist_scrub); 195ea8dc4beschrock avl_destroy(&spa->spa_errlist_last); 196ea8dc4beschrock 197fa9e406ahrens spa->spa_state = POOL_STATE_UNINITIALIZED; 198fa9e406ahrens} 199fa9e406ahrens 200fa9e406ahrens/* 201fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately. This 202fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev 203fa9e406ahrens * in the CLOSED state. This will prep the pool before open/creation/import. 204fa9e406ahrens * All vdev validation is done by the vdev_alloc() routine. 205fa9e406ahrens */ 20699653d4eschrockstatic int 20799653d4eschrockspa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, 20899653d4eschrock uint_t id, int atype) 209fa9e406ahrens{ 210fa9e406ahrens nvlist_t **child; 211fa9e406ahrens uint_t c, children; 21299653d4eschrock int error; 213fa9e406ahrens 21499653d4eschrock if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0) 21599653d4eschrock return (error); 216fa9e406ahrens 21799653d4eschrock if ((*vdp)->vdev_ops->vdev_op_leaf) 21899653d4eschrock return (0); 219fa9e406ahrens 220fa9e406ahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 221fa9e406ahrens &child, &children) != 0) { 22299653d4eschrock vdev_free(*vdp); 22399653d4eschrock *vdp = NULL; 22499653d4eschrock return (EINVAL); 225fa9e406ahrens } 226fa9e406ahrens 227fa9e406ahrens for (c = 0; c < children; c++) { 22899653d4eschrock vdev_t *vd; 22999653d4eschrock if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c, 23099653d4eschrock atype)) != 0) { 23199653d4eschrock vdev_free(*vdp); 23299653d4eschrock *vdp = NULL; 23399653d4eschrock return (error); 234fa9e406ahrens } 235fa9e406ahrens } 236fa9e406ahrens 23799653d4eschrock ASSERT(*vdp != NULL); 23899653d4eschrock 23999653d4eschrock return (0); 240fa9e406ahrens} 241fa9e406ahrens 242fa9e406ahrens/* 243fa9e406ahrens * Opposite of spa_load(). 244fa9e406ahrens */ 245fa9e406ahrensstatic void 246fa9e406ahrensspa_unload(spa_t *spa) 247fa9e406ahrens{ 24899653d4eschrock int i; 24999653d4eschrock 250fa9e406ahrens /* 251ea8dc4beschrock * Stop async tasks. 252ea8dc4beschrock */ 253ea8dc4beschrock spa_async_suspend(spa); 254ea8dc4beschrock 255ea8dc4beschrock /* 256fa9e406ahrens * Stop syncing. 257fa9e406ahrens */ 258fa9e406ahrens if (spa->spa_sync_on) { 259fa9e406ahrens txg_sync_stop(spa->spa_dsl_pool); 260fa9e406ahrens spa->spa_sync_on = B_FALSE; 261fa9e406ahrens } 262fa9e406ahrens 263fa9e406ahrens /* 264fa9e406ahrens * Wait for any outstanding prefetch I/O to complete. 265fa9e406ahrens */ 266ea8dc4beschrock spa_config_enter(spa, RW_WRITER, FTAG); 267ea8dc4beschrock spa_config_exit(spa, FTAG); 268fa9e406ahrens 269fa9e406ahrens /* 270fa9e406ahrens * Close the dsl pool. 271fa9e406ahrens */ 272fa9e406ahrens if (spa->spa_dsl_pool) { 273fa9e406ahrens dsl_pool_close(spa->spa_dsl_pool); 274fa9e406ahrens spa->spa_dsl_pool = NULL; 275fa9e406ahrens } 276fa9e406ahrens 277fa9e406ahrens /* 278fa9e406ahrens * Close all vdevs. 279fa9e406ahrens */ 2800e34b6abonwick if (spa->spa_root_vdev) 281fa9e406ahrens vdev_free(spa->spa_root_vdev); 2820e34b6abonwick ASSERT(spa->spa_root_vdev == NULL); 283ea8dc4beschrock 28499653d4eschrock for (i = 0; i < spa->spa_nspares; i++) 28599653d4eschrock vdev_free(spa->spa_spares[i]); 28699653d4eschrock if (spa->spa_spares) { 28799653d4eschrock kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *)); 28899653d4eschrock spa->spa_spares = NULL; 28999653d4eschrock } 29099653d4eschrock if (spa->spa_sparelist) { 29199653d4eschrock nvlist_free(spa->spa_sparelist); 29299653d4eschrock spa->spa_sparelist = NULL; 29399653d4eschrock } 29499653d4eschrock 295ea8dc4beschrock spa->spa_async_suspended = 0; 296fa9e406ahrens} 297fa9e406ahrens 298fa9e406ahrens/* 29999653d4eschrock * Load (or re-load) the current list of vdevs describing the active spares for 30099653d4eschrock * this pool. When this is called, we have some form of basic information in 30199653d4eschrock * 'spa_sparelist'. We parse this into vdevs, try to open them, and then 30299653d4eschrock * re-generate a more complete list including status information. 30399653d4eschrock */ 30499653d4eschrockstatic void 30599653d4eschrockspa_load_spares(spa_t *spa) 30699653d4eschrock{ 30799653d4eschrock nvlist_t **spares; 30899653d4eschrock uint_t nspares; 30999653d4eschrock int i; 31039c2341eschrock vdev_t *vd, *tvd; 31199653d4eschrock 31299653d4eschrock /* 31399653d4eschrock * First, close and free any existing spare vdevs. 31499653d4eschrock */ 31599653d4eschrock for (i = 0; i < spa->spa_nspares; i++) { 31639c2341eschrock vd = spa->spa_spares[i]; 31739c2341eschrock 31839c2341eschrock /* Undo the call to spa_activate() below */ 31939c2341eschrock if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL && 32039c2341eschrock tvd->vdev_isspare) 32139c2341eschrock spa_spare_remove(tvd); 32239c2341eschrock vdev_close(vd); 32339c2341eschrock vdev_free(vd); 32499653d4eschrock } 32539c2341eschrock 32699653d4eschrock if (spa->spa_spares) 32799653d4eschrock kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *)); 32899653d4eschrock 32999653d4eschrock if (spa->spa_sparelist == NULL) 33099653d4eschrock nspares = 0; 33199653d4eschrock else 33299653d4eschrock VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist, 33399653d4eschrock ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0); 33499653d4eschrock 33599653d4eschrock spa->spa_nspares = (int)nspares; 33699653d4eschrock spa->spa_spares = NULL; 33799653d4eschrock 33899653d4eschrock if (nspares == 0) 33999653d4eschrock return; 34099653d4eschrock 34199653d4eschrock /* 34299653d4eschrock * Construct the array of vdevs, opening them to get status in the 34339c2341eschrock * process. For each spare, there is potentially two different vdev_t 34439c2341eschrock * structures associated with it: one in the list of spares (used only 34539c2341eschrock * for basic validation purposes) and one in the active vdev 34639c2341eschrock * configuration (if it's spared in). During this phase we open and 34739c2341eschrock * validate each vdev on the spare list. If the vdev also exists in the 34839c2341eschrock * active configuration, then we also mark this vdev as an active spare. 34999653d4eschrock */ 35099653d4eschrock spa->spa_spares = kmem_alloc(nspares * sizeof (void *), KM_SLEEP); 35199653d4eschrock for (i = 0; i < spa->spa_nspares; i++) { 35299653d4eschrock VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0, 35399653d4eschrock VDEV_ALLOC_SPARE) == 0); 35499653d4eschrock ASSERT(vd != NULL); 35599653d4eschrock 35699653d4eschrock spa->spa_spares[i] = vd; 35799653d4eschrock 35839c2341eschrock if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL) { 35939c2341eschrock if (!tvd->vdev_isspare) 36039c2341eschrock spa_spare_add(tvd); 36139c2341eschrock 36239c2341eschrock /* 36339c2341eschrock * We only mark the spare active if we were successfully 36439c2341eschrock * able to load the vdev. Otherwise, importing a pool 36539c2341eschrock * with a bad active spare would result in strange 36639c2341eschrock * behavior, because multiple pool would think the spare 36739c2341eschrock * is actively in use. 36839c2341eschrock * 36939c2341eschrock * There is a vulnerability here to an equally bizarre 37039c2341eschrock * circumstance, where a dead active spare is later 37139c2341eschrock * brought back to life (onlined or otherwise). Given 37239c2341eschrock * the rarity of this scenario, and the extra complexity 37339c2341eschrock * it adds, we ignore the possibility. 37439c2341eschrock */ 37539c2341eschrock if (!vdev_is_dead(tvd)) 37639c2341eschrock spa_spare_activate(tvd); 37739c2341eschrock } 37839c2341eschrock 37999653d4eschrock if (vdev_open(vd) != 0) 38099653d4eschrock continue; 38199653d4eschrock 38299653d4eschrock vd->vdev_top = vd; 38399653d4eschrock (void) vdev_validate_spare(vd); 38499653d4eschrock } 38599653d4eschrock 38699653d4eschrock /* 38799653d4eschrock * Recompute the stashed list of spares, with status information 38899653d4eschrock * this time. 38999653d4eschrock */ 39099653d4eschrock VERIFY(nvlist_remove(spa->spa_sparelist, ZPOOL_CONFIG_SPARES, 39199653d4eschrock DATA_TYPE_NVLIST_ARRAY) == 0); 39299653d4eschrock 39399653d4eschrock spares = kmem_alloc(spa->spa_nspares * sizeof (void *), KM_SLEEP); 39499653d4eschrock for (i = 0; i < spa->spa_nspares; i++) 39599653d4eschrock spares[i] = vdev_config_generate(spa, spa->spa_spares[i], 39699653d4eschrock B_TRUE, B_TRUE); 39799653d4eschrock VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist, ZPOOL_CONFIG_SPARES, 39899653d4eschrock spares, spa->spa_nspares) == 0); 39999653d4eschrock for (i = 0; i < spa->spa_nspares; i++) 40099653d4eschrock nvlist_free(spares[i]); 40199653d4eschrock kmem_free(spares, spa->spa_nspares * sizeof (void *)); 40299653d4eschrock} 40399653d4eschrock 40499653d4eschrockstatic int 40599653d4eschrockload_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value) 40699653d4eschrock{ 40799653d4eschrock dmu_buf_t *db; 40899653d4eschrock char *packed = NULL; 40999653d4eschrock size_t nvsize = 0; 41099653d4eschrock int error; 41199653d4eschrock *value = NULL; 41299653d4eschrock 41399653d4eschrock VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db)); 41499653d4eschrock nvsize = *(uint64_t *)db->db_data; 41599653d4eschrock dmu_buf_rele(db, FTAG); 41699653d4eschrock 41799653d4eschrock packed = kmem_alloc(nvsize, KM_SLEEP); 41899653d4eschrock error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed); 41999653d4eschrock if (error == 0) 42099653d4eschrock error = nvlist_unpack(packed, nvsize, value, 0); 42199653d4eschrock kmem_free(packed, nvsize); 42299653d4eschrock 42399653d4eschrock return (error); 42499653d4eschrock} 42599653d4eschrock 42699653d4eschrock/* 427fa9e406ahrens * Load an existing storage pool, using the pool's builtin spa_config as a 428ea8dc4beschrock * source of configuration information. 429fa9e406ahrens */ 430fa9e406ahrensstatic int 431ea8dc4beschrockspa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) 432fa9e406ahrens{ 433fa9e406ahrens int error = 0; 434fa9e406ahrens nvlist_t *nvroot = NULL; 435fa9e406ahrens vdev_t *rvd; 436fa9e406ahrens uberblock_t *ub = &spa->spa_uberblock; 4370373e76bonwick uint64_t config_cache_txg = spa->spa_config_txg; 438fa9e406ahrens uint64_t pool_guid; 43999653d4eschrock uint64_t version; 440fa9e406ahrens zio_t *zio; 441fa9e406ahrens 442ea8dc4beschrock spa->spa_load_state = state; 4430373e76bonwick 444fa9e406ahrens if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) || 445a9926bfbonwick nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid)) { 446ea8dc4beschrock error = EINVAL; 447ea8dc4beschrock goto out; 448ea8dc4beschrock } 449fa9e406ahrens 45099653d4eschrock /* 45199653d4eschrock * Versioning wasn't explicitly added to the label until later, so if 45299653d4eschrock * it's not present treat it as the initial version. 45399653d4eschrock */ 45499653d4eschrock if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) != 0) 45599653d4eschrock version = ZFS_VERSION_INITIAL; 45699653d4eschrock 457a9926bfbonwick (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, 458a9926bfbonwick &spa->spa_config_txg); 459a9926bfbonwick 4600373e76bonwick if ((state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT) && 461ea8dc4beschrock spa_guid_exists(pool_guid, 0)) { 462ea8dc4beschrock error = EEXIST; 463ea8dc4beschrock goto out; 464ea8dc4beschrock } 465fa9e406ahrens 466b5989eceschrock spa->spa_load_guid = pool_guid; 467b5989eceschrock 468fa9e406ahrens /* 46999653d4eschrock * Parse the configuration into a vdev tree. We explicitly set the 47099653d4eschrock * value that will be returned by spa_version() since parsing the 47199653d4eschrock * configuration requires knowing the version number. 472fa9e406ahrens */ 473ea8dc4beschrock spa_config_enter(spa, RW_WRITER, FTAG); 47499653d4eschrock spa->spa_ubsync.ub_version = version; 47599653d4eschrock error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_LOAD); 476ea8dc4beschrock spa_config_exit(spa, FTAG); 477fa9e406ahrens 47899653d4eschrock if (error != 0) 479ea8dc4beschrock goto out; 480fa9e406ahrens 4810e34b6abonwick ASSERT(spa->spa_root_vdev == rvd); 482fa9e406ahrens ASSERT(spa_guid(spa) == pool_guid); 483fa9e406ahrens 484fa9e406ahrens /* 485fa9e406ahrens * Try to open all vdevs, loading each label in the process. 486fa9e406ahrens */ 487ea8dc4beschrock if (vdev_open(rvd) != 0) { 488ea8dc4beschrock error = ENXIO; 489ea8dc4beschrock goto out; 490