spa.c revision 990b4856d0eaada6f8140335733a1b1771ed2746
1fa9e406ahrens/* 2fa9e406ahrens * CDDL HEADER START 3fa9e406ahrens * 4fa9e406ahrens * The contents of this file are subject to the terms of the 5ea8dc4beschrock * Common Development and Distribution License (the "License"). 6ea8dc4beschrock * You may not use this file except in compliance with the License. 7fa9e406ahrens * 8fa9e406ahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fa9e406ahrens * or http://www.opensolaris.org/os/licensing. 10fa9e406ahrens * See the License for the specific language governing permissions 11fa9e406ahrens * and limitations under the License. 12fa9e406ahrens * 13fa9e406ahrens * When distributing Covered Code, include this CDDL HEADER in each 14fa9e406ahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fa9e406ahrens * If applicable, add the following below this CDDL HEADER, with the 16fa9e406ahrens * fields enclosed by brackets "[]" replaced with your own identifying 17fa9e406ahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18fa9e406ahrens * 19fa9e406ahrens * CDDL HEADER END 20fa9e406ahrens */ 2199653d4eschrock 22fa9e406ahrens/* 2339c2341eschrock * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24fa9e406ahrens * Use is subject to license terms. 25fa9e406ahrens */ 26fa9e406ahrens 27fa9e406ahrens#pragma ident "%Z%%M% %I% %E% SMI" 28fa9e406ahrens 29fa9e406ahrens/* 30fa9e406ahrens * This file contains all the routines used when modifying on-disk SPA state. 31fa9e406ahrens * This includes opening, importing, destroying, exporting a pool, and syncing a 32fa9e406ahrens * pool. 33fa9e406ahrens */ 34fa9e406ahrens 35fa9e406ahrens#include <sys/zfs_context.h> 36ea8dc4beschrock#include <sys/fm/fs/zfs.h> 37fa9e406ahrens#include <sys/spa_impl.h> 38fa9e406ahrens#include <sys/zio.h> 39fa9e406ahrens#include <sys/zio_checksum.h> 40fa9e406ahrens#include <sys/zio_compress.h> 41fa9e406ahrens#include <sys/dmu.h> 42fa9e406ahrens#include <sys/dmu_tx.h> 43fa9e406ahrens#include <sys/zap.h> 44fa9e406ahrens#include <sys/zil.h> 45fa9e406ahrens#include <sys/vdev_impl.h> 46fa9e406ahrens#include <sys/metaslab.h> 47fa9e406ahrens#include <sys/uberblock_impl.h> 48fa9e406ahrens#include <sys/txg.h> 49fa9e406ahrens#include <sys/avl.h> 50fa9e406ahrens#include <sys/dmu_traverse.h> 51b1b8ab3lling#include <sys/dmu_objset.h> 52fa9e406ahrens#include <sys/unique.h> 53fa9e406ahrens#include <sys/dsl_pool.h> 54b1b8ab3lling#include <sys/dsl_dataset.h> 55fa9e406ahrens#include <sys/dsl_dir.h> 56fa9e406ahrens#include <sys/dsl_prop.h> 57b1b8ab3lling#include <sys/dsl_synctask.h> 58fa9e406ahrens#include <sys/fs/zfs.h> 59fa9e406ahrens#include <sys/callb.h> 609517395ek#include <sys/systeminfo.h> 619517395ek#include <sys/sunddi.h> 62fa9e406ahrens 63990b485lling#include "zfs_prop.h" 64990b485lling 65416e0cdekint zio_taskq_threads = 8; 66416e0cdek 67990b485llingstatic void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx); 68990b485lling 69990b485lling/* 70990b485lling * ========================================================================== 71990b485lling * SPA properties routines 72990b485lling * ========================================================================== 73990b485lling */ 74990b485lling 75990b485lling/* 76990b485lling * Add a (source=src, propname=propval) list to an nvlist. 77990b485lling */ 78990b485llingstatic int 79990b485llingspa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval, 80990b485lling uint64_t intval, zprop_source_t src) 81990b485lling{ 82990b485lling const char *propname = zpool_prop_to_name(prop); 83990b485lling nvlist_t *propval; 84990b485lling int err = 0; 85990b485lling 86990b485lling if (err = nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP)) 87990b485lling return (err); 88990b485lling 89990b485lling if (err = nvlist_add_uint64(propval, ZPROP_SOURCE, src)) 90990b485lling goto out; 91990b485lling 92990b485lling if (strval != NULL) { 93990b485lling if (err = nvlist_add_string(propval, ZPROP_VALUE, strval)) 94990b485lling goto out; 95990b485lling } else { 96990b485lling if (err = nvlist_add_uint64(propval, ZPROP_VALUE, intval)) 97990b485lling goto out; 98990b485lling } 99990b485lling 100990b485lling err = nvlist_add_nvlist(nvl, propname, propval); 101990b485llingout: 102990b485lling nvlist_free(propval); 103990b485lling return (err); 104990b485lling} 105990b485lling 106990b485lling/* 107990b485lling * Get property values from the spa configuration. 108990b485lling */ 109990b485llingstatic int 110990b485llingspa_prop_get_config(spa_t *spa, nvlist_t **nvp) 111990b485lling{ 112990b485lling uint64_t size = spa_get_space(spa); 113990b485lling uint64_t used = spa_get_alloc(spa); 114990b485lling uint64_t cap, version; 115990b485lling zprop_source_t src = ZPROP_SRC_NONE; 116990b485lling int err; 117990b485lling 118990b485lling /* 119990b485lling * readonly properties 120990b485lling */ 121990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name, 122990b485lling 0, src)) 123990b485lling return (err); 124990b485lling 125990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src)) 126990b485lling return (err); 127990b485lling 128990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src)) 129990b485lling return (err); 130990b485lling 131990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL, 132990b485lling size - used, src)) 133990b485lling return (err); 134990b485lling 135990b485lling cap = (size == 0) ? 0 : (used * 100 / size); 136990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src)) 137990b485lling return (err); 138990b485lling 139990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, 140990b485lling spa_guid(spa), src)) 141990b485lling return (err); 142990b485lling 143990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL, 144990b485lling spa->spa_root_vdev->vdev_state, src)) 145990b485lling return (err); 146990b485lling 147990b485lling /* 148990b485lling * settable properties that are not stored in the pool property object. 149990b485lling */ 150990b485lling version = spa_version(spa); 151990b485lling if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) 152990b485lling src = ZPROP_SRC_DEFAULT; 153990b485lling else 154990b485lling src = ZPROP_SRC_LOCAL; 155990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, 156990b485lling version, src)) 157990b485lling return (err); 158990b485lling 159990b485lling if (spa->spa_root != NULL) { 160990b485lling src = ZPROP_SRC_LOCAL; 161990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, 162990b485lling spa->spa_root, 0, src)) 163990b485lling return (err); 164990b485lling } 165990b485lling 166990b485lling if (spa->spa_temporary == 167990b485lling zpool_prop_default_numeric(ZPOOL_PROP_TEMPORARY)) 168990b485lling src = ZPROP_SRC_DEFAULT; 169990b485lling else 170990b485lling src = ZPROP_SRC_LOCAL; 171990b485lling if (err = spa_prop_add_list(*nvp, ZPOOL_PROP_TEMPORARY, NULL, 172990b485lling spa->spa_temporary, src)) 173990b485lling return (err); 174990b485lling 175990b485lling return (0); 176990b485lling} 177990b485lling 178990b485lling/* 179990b485lling * Get zpool property values. 180990b485lling */ 181990b485llingint 182990b485llingspa_prop_get(spa_t *spa, nvlist_t **nvp) 183990b485lling{ 184990b485lling zap_cursor_t zc; 185990b485lling zap_attribute_t za; 186990b485lling objset_t *mos = spa->spa_meta_objset; 187990b485lling int err; 188990b485lling 189990b485lling if (err = nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP)) 190990b485lling return (err); 191990b485lling 192990b485lling /* 193990b485lling * Get properties from the spa config. 194990b485lling */ 195990b485lling if (err = spa_prop_get_config(spa, nvp)) 196990b485lling goto out; 197990b485lling 198990b485lling mutex_enter(&spa->spa_props_lock); 199990b485lling /* If no pool property object, no more prop to get. */ 200990b485lling if (spa->spa_pool_props_object == 0) { 201990b485lling mutex_exit(&spa->spa_props_lock); 202990b485lling return (0); 203990b485lling } 204990b485lling 205990b485lling /* 206990b485lling * Get properties from the MOS pool property object. 207990b485lling */ 208990b485lling for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object); 209990b485lling (err = zap_cursor_retrieve(&zc, &za)) == 0; 210990b485lling zap_cursor_advance(&zc)) { 211990b485lling uint64_t intval = 0; 212990b485lling char *strval = NULL; 213990b485lling zprop_source_t src = ZPROP_SRC_DEFAULT; 214990b485lling zpool_prop_t prop; 215990b485lling 216990b485lling if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL) 217990b485lling continue; 218990b485lling 219990b485lling switch (za.za_integer_length) { 220990b485lling case 8: 221990b485lling /* integer property */ 222990b485lling if (za.za_first_integer != 223990b485lling zpool_prop_default_numeric(prop)) 224990b485lling src = ZPROP_SRC_LOCAL; 225990b485lling 226990b485lling if (prop == ZPOOL_PROP_BOOTFS) { 227990b485lling dsl_pool_t *dp; 228990b485lling dsl_dataset_t *ds = NULL; 229990b485lling 230990b485lling dp = spa_get_dsl(spa); 231990b485lling rw_enter(&dp->dp_config_rwlock, RW_READER); 232990b485lling if (err = dsl_dataset_open_obj(dp, 233990b485lling za.za_first_integer, NULL, DS_MODE_NONE, 234990b485lling FTAG, &ds)) { 235990b485lling rw_exit(&dp->dp_config_rwlock); 236990b485lling break; 237990b485lling } 238990b485lling 239990b485lling strval = kmem_alloc( 240990b485lling MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, 241990b485lling KM_SLEEP); 242990b485lling dsl_dataset_name(ds, strval); 243990b485lling dsl_dataset_close(ds, DS_MODE_NONE, FTAG); 244990b485lling rw_exit(&dp->dp_config_rwlock); 245990b485lling } else { 246990b485lling strval = NULL; 247990b485lling intval = za.za_first_integer; 248990b485lling } 249990b485lling 250990b485lling err = spa_prop_add_list(*nvp, prop, strval, 251990b485lling intval, src); 252990b485lling 253990b485lling if (strval != NULL) 254990b485lling kmem_free(strval, 255990b485lling MAXNAMELEN + strlen(MOS_DIR_NAME) + 1); 256990b485lling 257990b485lling break; 258990b485lling 259990b485lling case 1: 260990b485lling /* string property */ 261990b485lling strval = kmem_alloc(za.za_num_integers, KM_SLEEP); 262990b485lling err = zap_lookup(mos, spa->spa_pool_props_object, 263990b485lling za.za_name, 1, za.za_num_integers, strval); 264990b485lling if (err) { 265990b485lling kmem_free(strval, za.za_num_integers); 266990b485lling break; 267990b485lling } 268990b485lling err = spa_prop_add_list(*nvp, prop, strval, 0, src); 269990b485lling kmem_free(strval, za.za_num_integers); 270990b485lling break; 271990b485lling 272990b485lling default: 273990b485lling break; 274990b485lling } 275990b485lling } 276990b485lling zap_cursor_fini(&zc); 277990b485lling mutex_exit(&spa->spa_props_lock); 278990b485llingout: 279990b485lling if (err && err != ENOENT) { 280990b485lling nvlist_free(*nvp); 281990b485lling return (err); 282990b485lling } 283990b485lling 284990b485lling return (0); 285990b485lling} 286990b485lling 287990b485lling/* 288990b485lling * Validate the given pool properties nvlist and modify the list 289990b485lling * for the property values to be set. 290990b485lling */ 291990b485llingstatic int 292990b485llingspa_prop_validate(spa_t *spa, nvlist_t *props) 293990b485lling{ 294990b485lling nvpair_t *elem; 295990b485lling int error = 0, reset_bootfs = 0; 296990b485lling uint64_t objnum; 297990b485lling 298990b485lling elem = NULL; 299990b485lling while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { 300990b485lling zpool_prop_t prop; 301990b485lling char *propname, *strval; 302990b485lling uint64_t intval; 303990b485lling vdev_t *rvdev; 304990b485lling char *vdev_type; 305990b485lling objset_t *os; 306990b485lling 307990b485lling propname = nvpair_name(elem); 308990b485lling 309990b485lling if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) 310990b485lling return (EINVAL); 311990b485lling 312990b485lling switch (prop) { 313990b485lling case ZPOOL_PROP_VERSION: 314990b485lling error = nvpair_value_uint64(elem, &intval); 315990b485lling if (!error && 316990b485lling (intval < spa_version(spa) || intval > SPA_VERSION)) 317990b485lling error = EINVAL; 318990b485lling break; 319990b485lling 320990b485lling case ZPOOL_PROP_DELEGATION: 321990b485lling case ZPOOL_PROP_AUTOREPLACE: 322990b485lling error = nvpair_value_uint64(elem, &intval); 323990b485lling if (!error && intval > 1) 324990b485lling error = EINVAL; 325990b485lling break; 326990b485lling 327990b485lling case ZPOOL_PROP_BOOTFS: 328990b485lling if (spa_version(spa) < SPA_VERSION_BOOTFS) { 329990b485lling error = ENOTSUP; 330990b485lling break; 331990b485lling } 332990b485lling 333990b485lling /* 334990b485lling * A bootable filesystem can not be on a RAIDZ pool 335990b485lling * nor a striped pool with more than 1 device. 336990b485lling */ 337990b485lling rvdev = spa->spa_root_vdev; 338990b485lling vdev_type = 339990b485lling rvdev->vdev_child[0]->vdev_ops->vdev_op_type; 340990b485lling if (rvdev->vdev_children > 1 || 341990b485lling strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 || 342990b485lling strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { 343990b485lling error = ENOTSUP; 344990b485lling break; 345990b485lling } 346990b485lling 347990b485lling reset_bootfs = 1; 348990b485lling 349990b485lling error = nvpair_value_string(elem, &strval); 350990b485lling 351990b485lling if (!error) { 352990b485lling if (strval == NULL || strval[0] == '\0') { 353990b485lling objnum = zpool_prop_default_numeric( 354990b485lling ZPOOL_PROP_BOOTFS); 355990b485lling break; 356990b485lling } 357990b485lling 358990b485lling if (error = dmu_objset_open(strval, DMU_OST_ZFS, 359990b485lling DS_MODE_STANDARD | DS_MODE_READONLY, &os)) 360990b485lling break; 361990b485lling objnum = dmu_objset_id(os); 362990b485lling dmu_objset_close(os); 363990b485lling } 364990b485lling break; 365990b485lling } 366990b485lling 367990b485lling if (error) 368990b485lling break; 369990b485lling } 370990b485lling 371990b485lling if (!error && reset_bootfs) { 372990b485lling error = nvlist_remove(props, 373990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING); 374990b485lling 375990b485lling if (!error) { 376990b485lling error = nvlist_add_uint64(props, 377990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum); 378990b485lling } 379990b485lling } 380990b485lling 381990b485lling return (error); 382990b485lling} 383990b485lling 384990b485llingint 385990b485llingspa_prop_set(spa_t *spa, nvlist_t *nvp) 386990b485lling{ 387990b485lling int error; 388990b485lling 389990b485lling if ((error = spa_prop_validate(spa, nvp)) != 0) 390990b485lling return (error); 391990b485lling 392990b485lling return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props, 393990b485lling spa, nvp, 3)); 394990b485lling} 395990b485lling 396990b485lling/* 397990b485lling * If the bootfs property value is dsobj, clear it. 398990b485lling */ 399990b485llingvoid 400990b485llingspa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx) 401990b485lling{ 402990b485lling if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) { 403990b485lling VERIFY(zap_remove(spa->spa_meta_objset, 404990b485lling spa->spa_pool_props_object, 405990b485lling zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0); 406990b485lling spa->spa_bootfs = 0; 407990b485lling } 408990b485lling} 409990b485lling 410fa9e406ahrens/* 411fa9e406ahrens * ========================================================================== 412fa9e406ahrens * SPA state manipulation (open/create/destroy/import/export) 413fa9e406ahrens * ========================================================================== 414fa9e406ahrens */ 415fa9e406ahrens 416ea8dc4beschrockstatic int 417ea8dc4beschrockspa_error_entry_compare(const void *a, const void *b) 418ea8dc4beschrock{ 419ea8dc4beschrock spa_error_entry_t *sa = (spa_error_entry_t *)a; 420ea8dc4beschrock spa_error_entry_t *sb = (spa_error_entry_t *)b; 421ea8dc4beschrock int ret; 422ea8dc4beschrock 423ea8dc4beschrock ret = bcmp(&sa->se_bookmark, &sb->se_bookmark, 424ea8dc4beschrock sizeof (zbookmark_t)); 425ea8dc4beschrock 426ea8dc4beschrock if (ret < 0) 427ea8dc4beschrock return (-1); 428ea8dc4beschrock else if (ret > 0) 429ea8dc4beschrock return (1); 430ea8dc4beschrock else 431ea8dc4beschrock return (0); 432ea8dc4beschrock} 433ea8dc4beschrock 434ea8dc4beschrock/* 435ea8dc4beschrock * Utility function which retrieves copies of the current logs and 436ea8dc4beschrock * re-initializes them in the process. 437ea8dc4beschrock */ 438ea8dc4beschrockvoid 439ea8dc4beschrockspa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub) 440ea8dc4beschrock{ 441ea8dc4beschrock ASSERT(MUTEX_HELD(&spa->spa_errlist_lock)); 442ea8dc4beschrock 443ea8dc4beschrock bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t)); 444ea8dc4beschrock bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t)); 445ea8dc4beschrock 446ea8dc4beschrock avl_create(&spa->spa_errlist_scrub, 447ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 448ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 449ea8dc4beschrock avl_create(&spa->spa_errlist_last, 450ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 451ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 452ea8dc4beschrock} 453ea8dc4beschrock 454fa9e406ahrens/* 455fa9e406ahrens * Activate an uninitialized pool. 456fa9e406ahrens */ 457fa9e406ahrensstatic void 458fa9e406ahrensspa_activate(spa_t *spa) 459fa9e406ahrens{ 460fa9e406ahrens int t; 461fa9e406ahrens 462fa9e406ahrens ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); 463fa9e406ahrens 464fa9e406ahrens spa->spa_state = POOL_STATE_ACTIVE; 465fa9e406ahrens 466fa9e406ahrens spa->spa_normal_class = metaslab_class_create(); 4678654d02perrin spa->spa_log_class = metaslab_class_create(); 468fa9e406ahrens 469fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 470fa9e406ahrens spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue", 471416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 472fa9e406ahrens TASKQ_PREPOPULATE); 473fa9e406ahrens spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr", 474416e0cdek zio_taskq_threads, maxclsyspri, 50, INT_MAX, 475fa9e406ahrens TASKQ_PREPOPULATE); 476fa9e406ahrens } 477fa9e406ahrens 478fa9e406ahrens list_create(&spa->spa_dirty_list, sizeof (vdev_t), 479fa9e406ahrens offsetof(vdev_t, vdev_dirty_node)); 480fa9e406ahrens 481fa9e406ahrens txg_list_create(&spa->spa_vdev_txg_list, 482fa9e406ahrens offsetof(struct vdev, vdev_txg_node)); 483ea8dc4beschrock 484ea8dc4beschrock avl_create(&spa->spa_errlist_scrub, 485ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 486ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 487ea8dc4beschrock avl_create(&spa->spa_errlist_last, 488ea8dc4beschrock spa_error_entry_compare, sizeof (spa_error_entry_t), 489ea8dc4beschrock offsetof(spa_error_entry_t, se_avl)); 490fa9e406ahrens} 491fa9e406ahrens 492fa9e406ahrens/* 493fa9e406ahrens * Opposite of spa_activate(). 494fa9e406ahrens */ 495fa9e406ahrensstatic void 496fa9e406ahrensspa_deactivate(spa_t *spa) 497fa9e406ahrens{ 498fa9e406ahrens int t; 499fa9e406ahrens 500fa9e406ahrens ASSERT(spa->spa_sync_on == B_FALSE); 501fa9e406ahrens ASSERT(spa->spa_dsl_pool == NULL); 502fa9e406ahrens ASSERT(spa->spa_root_vdev == NULL); 503fa9e406ahrens 504fa9e406ahrens ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED); 505fa9e406ahrens 506fa9e406ahrens txg_list_destroy(&spa->spa_vdev_txg_list); 507fa9e406ahrens 508fa9e406ahrens list_destroy(&spa->spa_dirty_list); 509fa9e406ahrens 510fa9e406ahrens for (t = 0; t < ZIO_TYPES; t++) { 511fa9e406ahrens taskq_destroy(spa->spa_zio_issue_taskq[t]); 512fa9e406ahrens taskq_destroy(spa->spa_zio_intr_taskq[t]); 513fa9e406ahrens spa->spa_zio_issue_taskq[t] = NULL; 514fa9e406ahrens spa->spa_zio_intr_taskq[t] = NULL; 515fa9e406ahrens } 516fa9e406ahrens 517fa9e406ahrens metaslab_class_destroy(spa->spa_normal_class); 518fa9e406ahrens spa->spa_normal_class = NULL; 519fa9e406ahrens 5208654d02perrin metaslab_class_destroy(spa->spa_log_class); 5218654d02perrin spa->spa_log_class = NULL; 5228654d02perrin 523ea8dc4beschrock /* 524ea8dc4beschrock * If this was part of an import or the open otherwise failed, we may 525ea8dc4beschrock * still have errors left in the queues. Empty them just in case. 526ea8dc4beschrock */ 527ea8dc4beschrock spa_errlog_drain(spa); 528ea8dc4beschrock 529ea8dc4beschrock avl_destroy(&spa->spa_errlist_scrub); 530ea8dc4beschrock avl_destroy(&spa->spa_errlist_last); 531ea8dc4beschrock 532fa9e406ahrens spa->spa_state = POOL_STATE_UNINITIALIZED; 533fa9e406ahrens} 534fa9e406ahrens 535fa9e406ahrens/* 536fa9e406ahrens * Verify a pool configuration, and construct the vdev tree appropriately. This 537fa9e406ahrens * will create all the necessary vdevs in the appropriate layout, with each vdev 538fa9e406ahrens * in the CLOSED state. This will prep the pool before open/creation/import. 539fa9e406ahrens * All vdev validation is done by the vdev_alloc() routine. 540fa9e406ahrens */ 54199653d4eschrockstatic int 54299653d4eschrockspa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, 54399653d4eschrock uint_t id, int atype) 544fa9e406ahrens{ 545fa9e406ahrens nvlist_t **child; 546fa9e406ahrens uint_t c, children; 54799653d4eschrock int error; 548fa9e406ahrens 54999653d4eschrock if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0) 55099653d4eschrock return (error); 551fa9e406ahrens 55299653d4eschrock if ((*vdp)->vdev_ops->vdev_op_leaf) 55399653d4eschrock return (0); 554fa9e406ahrens 555fa9e406ahrens if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 556fa9e406ahrens &child, &children) != 0) { 55799653d4eschrock vdev_free(*vdp); 55899653d4eschrock *vdp = NULL; 55999653d4eschrock return (EINVAL); 560fa9e406ahrens } 561fa9e406ahrens 562fa9e406ahrens for (c = 0; c < children; c++) { 56399653d4eschrock vdev_t *vd; 56499653d4eschrock if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c, 56599653d4eschrock atype)) != 0) { 56699653d4eschrock vdev_free(*vdp); 56799653d4eschrock *vdp = NULL; 56899653d4eschrock return (error); 569fa9e406ahrens } 570fa9e406ahrens } 571fa9e406ahrens 57299653d4eschrock ASSERT(*vdp != NULL); 57399653d4eschrock 57499653d4eschrock return (0); 575fa9e406ahrens} 576fa9e406ahrens 577fa9e406ahrens/* 578fa9e406ahrens * Opposite of spa_load(). 579fa9e406ahrens */ 580fa9e406ahrensstatic void 581fa9e406ahrensspa_unload(spa_t *spa) 582fa9e406ahrens{ 58399653d4eschrock int i; 58499653d4eschrock 585fa9e406ahrens /* 586