usr/src/uts/common/fs/zfs/spa.c
author eschrock
Tue, 12 Jun 2007 13:18:17 -0700
changeset 4451 24fbf2d7a5d7
parent 4309 3dfde0f4662d
child 4527 5d5b6ba91b17
permissions -rw-r--r--
PSARC 2007/197 ZFS hotplug PSARC 2007/283 FMA for ZFS Phase 2 6401126 ZFS DE should verify that diagnosis is still valid before solving cases 6500545 ZFS does not handle changes in devids 6508521 zpool online should warn when it is being used incorrectly 6509807 ZFS checksum ereports are not being posted 6514712 zfs_nicenum() doesn't work with perfectly-sized buffers 6520510 media state doesn't get updated properly on device removal 6520513 ZFS should have better support for device removal 6520514 vdev state should be controlled through a single ioctl() 6520519 ZFS should diagnose faulty devices 6520947 ZFS DE should close cases which no longer apply 6521393 ZFS case timeout should be FMD_TYPE_TIME 6521624 fmd_hash_walk() can dump core when given a bad address 6521946 ZFS DE needlessly subscribes to faults 6522085 ZFS dictionary files contain spelling errors 6523185 vdev_reopen() doesn't correctly propagate state 6523555 'zpool online' should be less chatty unless something goes wrong 6527379 zpool(1M) should not try to open faulted devices 6527700 ZFS should post a sysevent when topology changes 6528194 lofi should support force unmap and DKIO_DEV_GONE 6528732 ZFS should store physical device path in addition to /dev path 6532635 ZFS keeps devices open unnecessarily 6532979 bad argument to ZFS_IOC_VDEV_ATTACH can panic system 6567983 deadlock with spa_scrub_thread() and spa_namespace_lock
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
    21
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    22
/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
    23
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 * This file contains all the routines used when modifying on-disk SPA state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * This includes opening, importing, destroying, exporting a pool, and syncing a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 * pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/zfs_context.h>
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    36
#include <sys/fm/fs/zfs.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/spa_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/zio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/zio_checksum.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <sys/zio_compress.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <sys/zil.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <sys/metaslab.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <sys/uberblock_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
#include <sys/txg.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include <sys/avl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/dmu_traverse.h>
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
    51
#include <sys/dmu_objset.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <sys/unique.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
#include <sys/dsl_pool.h>
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
    54
#include <sys/dsl_dataset.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
#include <sys/dsl_dir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
#include <sys/dsl_prop.h>
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
    57
#include <sys/dsl_synctask.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
#include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
#include <sys/callb.h>
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
    60
#include <sys/systeminfo.h>
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
    61
#include <sys/sunddi.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
2986
c782fcf7a319 6485204 more tuneable tweakin
ek110237
parents: 2926
diff changeset
    63
int zio_taskq_threads = 8;
c782fcf7a319 6485204 more tuneable tweakin
ek110237
parents: 2926
diff changeset
    64
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
 * SPA state manipulation (open/create/destroy/import/export)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    71
static int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    72
spa_error_entry_compare(const void *a, const void *b)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    73
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    74
	spa_error_entry_t *sa = (spa_error_entry_t *)a;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    75
	spa_error_entry_t *sb = (spa_error_entry_t *)b;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    76
	int ret;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    77
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    78
	ret = bcmp(&sa->se_bookmark, &sb->se_bookmark,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    79
	    sizeof (zbookmark_t));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    80
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    81
	if (ret < 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    82
		return (-1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    83
	else if (ret > 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    84
		return (1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    85
	else
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    86
		return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    87
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    88
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    89
/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    90
 * Utility function which retrieves copies of the current logs and
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    91
 * re-initializes them in the process.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    92
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    93
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    94
spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    95
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    96
	ASSERT(MUTEX_HELD(&spa->spa_errlist_lock));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    97
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    98
	bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
    99
	bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   100
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   101
	avl_create(&spa->spa_errlist_scrub,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   102
	    spa_error_entry_compare, sizeof (spa_error_entry_t),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   103
	    offsetof(spa_error_entry_t, se_avl));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   104
	avl_create(&spa->spa_errlist_last,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   105
	    spa_error_entry_compare, sizeof (spa_error_entry_t),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   106
	    offsetof(spa_error_entry_t, se_avl));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   107
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   108
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
 * Activate an uninitialized pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
spa_activate(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
	int t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
	ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
	spa->spa_state = POOL_STATE_ACTIVE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	spa->spa_normal_class = metaslab_class_create();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	for (t = 0; t < ZIO_TYPES; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue",
2986
c782fcf7a319 6485204 more tuneable tweakin
ek110237
parents: 2926
diff changeset
   125
		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
		    TASKQ_PREPOPULATE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
		spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr",
2986
c782fcf7a319 6485204 more tuneable tweakin
ek110237
parents: 2926
diff changeset
   128
		    zio_taskq_threads, maxclsyspri, 50, INT_MAX,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
		    TASKQ_PREPOPULATE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	rw_init(&spa->spa_traverse_lock, NULL, RW_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
2856
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   134
	mutex_init(&spa->spa_async_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   135
	mutex_init(&spa->spa_config_cache_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   136
	mutex_init(&spa->spa_scrub_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   137
	mutex_init(&spa->spa_errlog_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   138
	mutex_init(&spa->spa_errlist_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   139
	mutex_init(&spa->spa_config_lock.scl_lock, NULL, MUTEX_DEFAULT, NULL);
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   140
	mutex_init(&spa->spa_sync_bplist.bpl_lock, NULL, MUTEX_DEFAULT, NULL);
2926
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   141
	mutex_init(&spa->spa_history_lock, NULL, MUTEX_DEFAULT, NULL);
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   142
	mutex_init(&spa->spa_props_lock, NULL, MUTEX_DEFAULT, NULL);
2856
6f4d5ee1906a 6463348 ZFS code could be more portable
nd150628
parents: 2417
diff changeset
   143
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	list_create(&spa->spa_dirty_list, sizeof (vdev_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	    offsetof(vdev_t, vdev_dirty_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
	txg_list_create(&spa->spa_vdev_txg_list,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	    offsetof(struct vdev, vdev_txg_node));
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   149
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   150
	avl_create(&spa->spa_errlist_scrub,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   151
	    spa_error_entry_compare, sizeof (spa_error_entry_t),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   152
	    offsetof(spa_error_entry_t, se_avl));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   153
	avl_create(&spa->spa_errlist_last,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   154
	    spa_error_entry_compare, sizeof (spa_error_entry_t),
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   155
	    offsetof(spa_error_entry_t, se_avl));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
 * Opposite of spa_activate().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
spa_deactivate(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	int t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
	ASSERT(spa->spa_sync_on == B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	ASSERT(spa->spa_dsl_pool == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	ASSERT(spa->spa_root_vdev == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	txg_list_destroy(&spa->spa_vdev_txg_list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	list_destroy(&spa->spa_dirty_list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	rw_destroy(&spa->spa_traverse_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	for (t = 0; t < ZIO_TYPES; t++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
		taskq_destroy(spa->spa_zio_issue_taskq[t]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
		taskq_destroy(spa->spa_zio_intr_taskq[t]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
		spa->spa_zio_issue_taskq[t] = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
		spa->spa_zio_intr_taskq[t] = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	metaslab_class_destroy(spa->spa_normal_class);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	spa->spa_normal_class = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   188
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   189
	 * If this was part of an import or the open otherwise failed, we may
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   190
	 * still have errors left in the queues.  Empty them just in case.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   191
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   192
	spa_errlog_drain(spa);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   193
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   194
	avl_destroy(&spa->spa_errlist_scrub);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   195
	avl_destroy(&spa->spa_errlist_last);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   196
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	spa->spa_state = POOL_STATE_UNINITIALIZED;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
 * Verify a pool configuration, and construct the vdev tree appropriately.  This
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
 * will create all the necessary vdevs in the appropriate layout, with each vdev
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
 * in the CLOSED state.  This will prep the pool before open/creation/import.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
 * All vdev validation is done by the vdev_alloc() routine.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   206
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   207
spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   208
    uint_t id, int atype)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	nvlist_t **child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	uint_t c, children;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   212
	int error;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   213
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   214
	if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   215
		return (error);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   216
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   217
	if ((*vdp)->vdev_ops->vdev_op_leaf)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   218
		return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	    &child, &children) != 0) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   222
		vdev_free(*vdp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   223
		*vdp = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   224
		return (EINVAL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	for (c = 0; c < children; c++) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   228
		vdev_t *vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   229
		if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   230
		    atype)) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   231
			vdev_free(*vdp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   232
			*vdp = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   233
			return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   237
	ASSERT(*vdp != NULL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   238
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   239
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
 * Opposite of spa_load().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
spa_unload(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
{
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   248
	int i;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   249
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   251
	 * Stop async tasks.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   252
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   253
	spa_async_suspend(spa);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   254
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   255
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	 * Stop syncing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	if (spa->spa_sync_on) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
		txg_sync_stop(spa->spa_dsl_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
		spa->spa_sync_on = B_FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	 * Wait for any outstanding prefetch I/O to complete.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   266
	spa_config_enter(spa, RW_WRITER, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   267
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	 * Close the dsl pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
	if (spa->spa_dsl_pool) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		dsl_pool_close(spa->spa_dsl_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		spa->spa_dsl_pool = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
	 * Close all vdevs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
	 */
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   280
	if (spa->spa_root_vdev)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		vdev_free(spa->spa_root_vdev);
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   282
	ASSERT(spa->spa_root_vdev == NULL);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   283
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   284
	for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   285
		vdev_free(spa->spa_spares[i]);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   286
	if (spa->spa_spares) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   287
		kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   288
		spa->spa_spares = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   289
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   290
	if (spa->spa_sparelist) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   291
		nvlist_free(spa->spa_sparelist);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   292
		spa->spa_sparelist = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   293
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   294
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   295
	spa->spa_async_suspended = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   299
 * Load (or re-load) the current list of vdevs describing the active spares for
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   300
 * this pool.  When this is called, we have some form of basic information in
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   301
 * 'spa_sparelist'.  We parse this into vdevs, try to open them, and then
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   302
 * re-generate a more complete list including status information.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   303
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   304
static void
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   305
spa_load_spares(spa_t *spa)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   306
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   307
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   308
	uint_t nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   309
	int i;
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   310
	vdev_t *vd, *tvd;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   311
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   312
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   313
	 * First, close and free any existing spare vdevs.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   314
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   315
	for (i = 0; i < spa->spa_nspares; i++) {
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   316
		vd = spa->spa_spares[i];
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   317
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   318
		/* Undo the call to spa_activate() below */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   319
		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL &&
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   320
		    tvd->vdev_isspare)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   321
			spa_spare_remove(tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   322
		vdev_close(vd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   323
		vdev_free(vd);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   324
	}
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   325
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   326
	if (spa->spa_spares)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   327
		kmem_free(spa->spa_spares, spa->spa_nspares * sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   328
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   329
	if (spa->spa_sparelist == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   330
		nspares = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   331
	else
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   332
		VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   333
		    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   334
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   335
	spa->spa_nspares = (int)nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   336
	spa->spa_spares = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   337
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   338
	if (nspares == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   339
		return;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   340
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   341
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   342
	 * Construct the array of vdevs, opening them to get status in the
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   343
	 * process.   For each spare, there is potentially two different vdev_t
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   344
	 * structures associated with it: one in the list of spares (used only
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   345
	 * for basic validation purposes) and one in the active vdev
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   346
	 * configuration (if it's spared in).  During this phase we open and
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   347
	 * validate each vdev on the spare list.  If the vdev also exists in the
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   348
	 * active configuration, then we also mark this vdev as an active spare.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   349
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   350
	spa->spa_spares = kmem_alloc(nspares * sizeof (void *), KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   351
	for (i = 0; i < spa->spa_nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   352
		VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   353
		    VDEV_ALLOC_SPARE) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   354
		ASSERT(vd != NULL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   355
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   356
		spa->spa_spares[i] = vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   357
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   358
		if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid)) != NULL) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   359
			if (!tvd->vdev_isspare)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   360
				spa_spare_add(tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   361
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   362
			/*
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   363
			 * We only mark the spare active if we were successfully
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   364
			 * able to load the vdev.  Otherwise, importing a pool
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   365
			 * with a bad active spare would result in strange
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   366
			 * behavior, because multiple pool would think the spare
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   367
			 * is actively in use.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   368
			 *
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   369
			 * There is a vulnerability here to an equally bizarre
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   370
			 * circumstance, where a dead active spare is later
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   371
			 * brought back to life (onlined or otherwise).  Given
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   372
			 * the rarity of this scenario, and the extra complexity
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   373
			 * it adds, we ignore the possibility.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   374
			 */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   375
			if (!vdev_is_dead(tvd))
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   376
				spa_spare_activate(tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   377
		}
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   378
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   379
		if (vdev_open(vd) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   380
			continue;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   381
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   382
		vd->vdev_top = vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   383
		(void) vdev_validate_spare(vd);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   384
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   385
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   386
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   387
	 * Recompute the stashed list of spares, with status information
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   388
	 * this time.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   389
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   390
	VERIFY(nvlist_remove(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   391
	    DATA_TYPE_NVLIST_ARRAY) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   392
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   393
	spares = kmem_alloc(spa->spa_nspares * sizeof (void *), KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   394
	for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   395
		spares[i] = vdev_config_generate(spa, spa->spa_spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   396
		    B_TRUE, B_TRUE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   397
	VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   398
	    spares, spa->spa_nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   399
	for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   400
		nvlist_free(spares[i]);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   401
	kmem_free(spares, spa->spa_nspares * sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   402
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   403
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   404
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   405
load_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   406
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   407
	dmu_buf_t *db;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   408
	char *packed = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   409
	size_t nvsize = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   410
	int error;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   411
	*value = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   412
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   413
	VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   414
	nvsize = *(uint64_t *)db->db_data;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   415
	dmu_buf_rele(db, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   416
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   417
	packed = kmem_alloc(nvsize, KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   418
	error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   419
	if (error == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   420
		error = nvlist_unpack(packed, nvsize, value, 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   421
	kmem_free(packed, nvsize);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   422
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   423
	return (error);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   424
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   425
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   426
/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   427
 * Checks to see if the given vdev could not be opened, in which case we post a
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   428
 * sysevent to notify the autoreplace code that the device has been removed.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   429
 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   430
static void
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   431
spa_check_removed(vdev_t *vd)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   432
{
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   433
	int c;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   434
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   435
	for (c = 0; c < vd->vdev_children; c++)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   436
		spa_check_removed(vd->vdev_child[c]);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   437
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   438
	if (vd->vdev_ops->vdev_op_leaf && vdev_is_dead(vd)) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   439
		zfs_post_autoreplace(vd->vdev_spa, vd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   440
		spa_event_notify(vd->vdev_spa, vd, ESC_ZFS_VDEV_CHECK);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   441
	}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   442
}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   443
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   444
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
 * Load an existing storage pool, using the pool's builtin spa_config as a
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   446
 * source of configuration information.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
static int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   449
spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	nvlist_t *nvroot = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
	vdev_t *rvd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
	uberblock_t *ub = &spa->spa_uberblock;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   455
	uint64_t config_cache_txg = spa->spa_config_txg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	uint64_t pool_guid;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   457
	uint64_t version;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
	zio_t *zio;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   459
	uint64_t autoreplace = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   461
	spa->spa_load_state = state;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   462
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
	if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) ||
1733
a7c3bc84e012 6407377 spa_tryimport() is broken
bonwick
parents: 1732
diff changeset
   464
	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid)) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   465
		error = EINVAL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   466
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   467
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   469
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   470
	 * Versioning wasn't explicitly added to the label until later, so if
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   471
	 * it's not present treat it as the initial version.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   472
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   473
	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   474
		version = ZFS_VERSION_INITIAL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   475
1733
a7c3bc84e012 6407377 spa_tryimport() is broken
bonwick
parents: 1732
diff changeset
   476
	(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
a7c3bc84e012 6407377 spa_tryimport() is broken
bonwick
parents: 1732
diff changeset
   477
	    &spa->spa_config_txg);
a7c3bc84e012 6407377 spa_tryimport() is broken
bonwick
parents: 1732
diff changeset
   478
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   479
	if ((state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT) &&
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   480
	    spa_guid_exists(pool_guid, 0)) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   481
		error = EEXIST;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   482
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   483
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
2174
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   485
	spa->spa_load_guid = pool_guid;
73de7a781492 6433717 offline devices should not be marked persistently unavailble
eschrock
parents: 2082
diff changeset
   486
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   488
	 * Parse the configuration into a vdev tree.  We explicitly set the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   489
	 * value that will be returned by spa_version() since parsing the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   490
	 * configuration requires knowing the version number.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   492
	spa_config_enter(spa, RW_WRITER, FTAG);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   493
	spa->spa_ubsync.ub_version = version;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   494
	error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_LOAD);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   495
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   497
	if (error != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   498
		goto out;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   500
	ASSERT(spa->spa_root_vdev == rvd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
	ASSERT(spa_guid(spa) == pool_guid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	 * Try to open all vdevs, loading each label in the process.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
	 */
4070
4390ea390a1e 6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents: 3975
diff changeset
   506
	error = vdev_open(rvd);
4390ea390a1e 6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents: 3975
diff changeset
   507
	if (error != 0)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   508
		goto out;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
	/*
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   511
	 * Validate the labels for all leaf vdevs.  We need to grab the config
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   512
	 * lock because all label I/O is done with the ZIO_FLAG_CONFIG_HELD
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   513
	 * flag.
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   514
	 */
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   515
	spa_config_enter(spa, RW_READER, FTAG);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   516
	error = vdev_validate(rvd);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   517
	spa_config_exit(spa, FTAG);
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   518
4070
4390ea390a1e 6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents: 3975
diff changeset
   519
	if (error != 0)
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   520
		goto out;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   521
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   522
	if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) {
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   523
		error = ENXIO;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   524
		goto out;
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   525
	}
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   526
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   527
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
	 * Find the best uberblock.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	bzero(ub, sizeof (uberblock_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
	zio = zio_root(spa, NULL, NULL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	    ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
	vdev_uberblock_load(zio, rvd, ub);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
	error = zio_wait(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
	 * If we weren't able to find a single valid uberblock, return failure.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	if (ub->ub_txg == 0) {
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
   541
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
   542
		    VDEV_AUX_CORRUPT_DATA);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   543
		error = ENXIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   544
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   545
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   546
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   547
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   548
	 * If the pool is newer than the code, we can't open it.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   549
	 */
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
   550
	if (ub->ub_version > ZFS_VERSION) {
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
   551
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
   552
		    VDEV_AUX_VERSION_NEWER);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   553
		error = ENOTSUP;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   554
		goto out;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	 * If the vdev guid sum doesn't match the uberblock, we have an
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
	 * incomplete configuration.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
   561
	if (rvd->vdev_guid_sum != ub->ub_guid_sum && mosconfig) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   562
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   563
		    VDEV_AUX_BAD_GUID_SUM);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   564
		error = ENXIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   565
		goto out;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	 * Initialize internal SPA structures.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
	spa->spa_state = POOL_STATE_ACTIVE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
	spa->spa_ubsync = spa->spa_uberblock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	spa->spa_first_txg = spa_last_synced_txg(spa) + 1;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   574
	error = dsl_pool_open(spa, spa->spa_first_txg, &spa->spa_dsl_pool);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   575
	if (error) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   576
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   577
		    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   578
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   579
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   582
	if (zap_lookup(spa->spa_meta_objset,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   584
	    sizeof (uint64_t), 1, &spa->spa_config_object) != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   585
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   586
		    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   587
		error = EIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   588
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   589
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	if (!mosconfig) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   592
		nvlist_t *newconfig;
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   593
		uint64_t hostid;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   594
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   595
		if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   596
			vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   597
			    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   598
			error = EIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   599
			goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   600
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   602
		if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   603
		    &hostid) == 0) {
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   604
			char *hostname;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   605
			unsigned long myhostid = 0;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   606
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   607
			VERIFY(nvlist_lookup_string(newconfig,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   608
			    ZPOOL_CONFIG_HOSTNAME, &hostname) == 0);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   609
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   610
			(void) ddi_strtoul(hw_serial, NULL, 10, &myhostid);
4178
ad95fd86760b 6553537 zfs root fails to boot from a snv_63+zfsboot-pfinstall netinstall image
lling
parents: 4070
diff changeset
   611
			if (hostid != 0 && myhostid != 0 &&
ad95fd86760b 6553537 zfs root fails to boot from a snv_63+zfsboot-pfinstall netinstall image
lling
parents: 4070
diff changeset
   612
			    (unsigned long)hostid != myhostid) {
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   613
				cmn_err(CE_WARN, "pool '%s' could not be "
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   614
				    "loaded as it was last accessed by "
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   615
				    "another system (host: %s hostid: 0x%lx).  "
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   616
				    "See: http://www.sun.com/msg/ZFS-8000-EY",
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   617
				    spa->spa_name, hostname,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   618
				    (unsigned long)hostid);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   619
				error = EBADF;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   620
				goto out;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   621
			}
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   622
		}
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
   623
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
		spa_config_set(spa, newconfig);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
		spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
		spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
		spa_activate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   629
		return (spa_load(spa, newconfig, state, B_TRUE));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   630
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   631
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   632
	if (zap_lookup(spa->spa_meta_objset,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   633
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPLIST,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   634
	    sizeof (uint64_t), 1, &spa->spa_sync_bplist_obj) != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   635
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   636
		    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   637
		error = EIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   638
		goto out;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   639
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   640
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   641
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   642
	 * Load the bit that tells us to use the new accounting function
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   643
	 * (raid-z deflation).  If we have an older pool, this will not
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   644
	 * be present.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   645
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   646
	error = zap_lookup(spa->spa_meta_objset,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   647
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   648
	    sizeof (uint64_t), 1, &spa->spa_deflate);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   649
	if (error != 0 && error != ENOENT) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   650
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   651
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   652
		error = EIO;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   653
		goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   654
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   655
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   656
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   657
	 * Load the persistent error log.  If we have an older pool, this will
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   658
	 * not be present.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   659
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   660
	error = zap_lookup(spa->spa_meta_objset,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   661
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_LAST,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   662
	    sizeof (uint64_t), 1, &spa->spa_errlog_last);
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
   663
	if (error != 0 && error != ENOENT) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   664
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   665
		    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   666
		error = EIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   667
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   668
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   669
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   670
	error = zap_lookup(spa->spa_meta_objset,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   671
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_SCRUB,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   672
	    sizeof (uint64_t), 1, &spa->spa_errlog_scrub);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   673
	if (error != 0 && error != ENOENT) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   674
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   675
		    VDEV_AUX_CORRUPT_DATA);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   676
		error = EIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   677
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   678
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   679
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   680
	/*
2926
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   681
	 * Load the history object.  If we have an older pool, this
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   682
	 * will not be present.
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   683
	 */
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   684
	error = zap_lookup(spa->spa_meta_objset,
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   685
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_HISTORY,
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   686
	    sizeof (uint64_t), 1, &spa->spa_history);
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   687
	if (error != 0 && error != ENOENT) {
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   688
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   689
		    VDEV_AUX_CORRUPT_DATA);
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   690
		error = EIO;
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   691
		goto out;
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   692
	}
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   693
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
   694
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   695
	 * Load any hot spares for this pool.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   696
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   697
	error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   698
	    DMU_POOL_SPARES, sizeof (uint64_t), 1, &spa->spa_spares_object);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   699
	if (error != 0 && error != ENOENT) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   700
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   701
		    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   702
		error = EIO;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   703
		goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   704
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   705
	if (error == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   706
		ASSERT(spa_version(spa) >= ZFS_VERSION_SPARES);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   707
		if (load_nvlist(spa, spa->spa_spares_object,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   708
		    &spa->spa_sparelist) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   709
			vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   710
			    VDEV_AUX_CORRUPT_DATA);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   711
			error = EIO;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   712
			goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   713
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   714
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   715
		spa_config_enter(spa, RW_WRITER, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   716
		spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   717
		spa_config_exit(spa, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   718
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   719
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   720
	error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   721
	    DMU_POOL_PROPS, sizeof (uint64_t), 1, &spa->spa_pool_props_object);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   722
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   723
	if (error && error != ENOENT) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   724
		vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   725
		    VDEV_AUX_CORRUPT_DATA);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   726
		error = EIO;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   727
		goto out;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   728
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   729
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   730
	if (error == 0) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   731
		(void) zap_lookup(spa->spa_meta_objset,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   732
		    spa->spa_pool_props_object,
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   733
		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS),
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   734
		    sizeof (uint64_t), 1, &spa->spa_bootfs);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   735
		(void) zap_lookup(spa->spa_meta_objset,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   736
		    spa->spa_pool_props_object,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   737
		    zpool_prop_to_name(ZPOOL_PROP_AUTOREPLACE),
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   738
		    sizeof (uint64_t), 1, &autoreplace);
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   739
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
   740
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   741
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   742
	 * If the 'autoreplace' property is set, then post a resource notifying
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   743
	 * the ZFS DE that it should not issue any faults for unopenable
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   744
	 * devices.  We also iterate over the vdevs, and post a sysevent for any
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   745
	 * unopenable vdevs so that the normal autoreplace handler can take
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   746
	 * over.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   747
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   748
	if (autoreplace)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   749
		spa_check_removed(spa->spa_root_vdev);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   750
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   751
	/*
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   752
	 * Load the vdev state for all toplevel vdevs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
	 */
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   754
	vdev_load(rvd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
	 * Propagate the leaf DTLs we just loaded all the way up the tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   759
	spa_config_enter(spa, RW_WRITER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
	vdev_dtl_reassess(rvd, 0, 0, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   761
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
	 * Check the state of the root vdev.  If it can't be opened, it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
	 * indicates one or more toplevel vdevs are faulted.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   767
	if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   768
		error = ENXIO;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   769
		goto out;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   770
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   772
	if ((spa_mode & FWRITE) && state != SPA_LOAD_TRYIMPORT) {
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   773
		dmu_tx_t *tx;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   774
		int need_update = B_FALSE;
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   775
		int c;
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
   776
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   777
		/*
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   778
		 * Claim log blocks that haven't been committed yet.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   779
		 * This must all happen in a single txg.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   780
		 */
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
   781
		tx = dmu_tx_create_assigned(spa_get_dsl(spa),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
		    spa_first_txg(spa));
2417
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2329
diff changeset
   783
		(void) dmu_objset_find(spa->spa_name,
694d5de97348 6444346 zfs promote fails in zone
ahrens
parents: 2329
diff changeset
   784
		    zil_claim, tx, DS_FIND_CHILDREN);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   785
		dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   787
		spa->spa_sync_on = B_TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   788
		txg_sync_start(spa->spa_dsl_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
		 * Wait for all claims to sync.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   792
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
		txg_wait_synced(spa->spa_dsl_pool, 0);
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   794
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   795
		/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   796
		 * If the config cache is stale, or we have uninitialized
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   797
		 * metaslabs (see spa_vdev_add()), then update the config.
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   798
		 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   799
		if (config_cache_txg != spa->spa_config_txg ||
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   800
		    state == SPA_LOAD_IMPORT)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   801
			need_update = B_TRUE;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   802
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   803
		for (c = 0; c < rvd->vdev_children; c++)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   804
			if (rvd->vdev_child[c]->vdev_ms_array == 0)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   805
				need_update = B_TRUE;
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   806
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   807
		/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   808
		 * Update the config cache asychronously in case we're the
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   809
		 * root pool, in which case the config cache isn't writable yet.
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
   810
		 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   811
		if (need_update)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   812
			spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   815
	error = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   816
out:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   817
	if (error && error != EBADF)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   818
		zfs_ereport_post(FM_EREPORT_ZFS_POOL, spa, NULL, NULL, 0, 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   819
	spa->spa_load_state = SPA_LOAD_NONE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   820
	spa->spa_ena = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   821
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   822
	return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   823
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   824
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   825
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   826
 * Pool Open/Import
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   828
 * The import case is identical to an open except that the configuration is sent
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
 * down from userland, instead of grabbed from the configuration cache.  For the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   830
 * case of an open, the pool configuration will exist in the
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   831
 * POOL_STATE_UNINITIALIZED state.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   832
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   833
 * The stats information (gen/count/ustats) is used to gather vdev statistics at
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
 * the same time open the pool, without having to keep around the spa_t in some
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   835
 * ambiguous state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   836
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   837
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   838
spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   839
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   840
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   841
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   842
	int loaded = B_FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   843
	int locked = B_FALSE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   844
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   845
	*spapp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   846
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   847
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   848
	 * As disgusting as this is, we need to support recursive calls to this
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   849
	 * function because dsl_dir_open() is called during spa_load(), and ends
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   850
	 * up calling spa_open() again.  The real fix is to figure out how to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   851
	 * avoid dsl_dir_open() calling this in the first place.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
	if (mutex_owner(&spa_namespace_lock) != curthread) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
		locked = B_TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   858
	if ((spa = spa_lookup(pool)) == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   859
		if (locked)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   860
			mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   861
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   863
	if (spa->spa_state == POOL_STATE_UNINITIALIZED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
		spa_activate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   867
		error = spa_load(spa, spa->spa_config, SPA_LOAD_OPEN, B_FALSE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   868
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
		if (error == EBADF) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   870
			/*
1986
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   871
			 * If vdev_validate() returns failure (indicated by
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   872
			 * EBADF), it indicates that one of the vdevs indicates
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   873
			 * that the pool has been exported or destroyed.  If
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   874
			 * this is the case, the config cache is out of sync and
628267397204 6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents: 1807
diff changeset
   875
			 * we should remove the pool from the namespace.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   876
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   877
			zfs_post_ok(spa, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   878
			spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   879
			spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   880
			spa_remove(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   881
			spa_config_sync();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   882
			if (locked)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
				mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
			return (ENOENT);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   885
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   886
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   887
		if (error) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   888
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   889
			 * We can't open the pool, but we still have useful
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   890
			 * information: the state of each vdev after the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   891
			 * attempted vdev_open().  Return this to the user.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   892
			 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   893
			if (config != NULL && spa->spa_root_vdev != NULL) {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   894
				spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   895
				*config = spa_config_generate(spa, NULL, -1ULL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   896
				    B_TRUE);
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   897
				spa_config_exit(spa, FTAG);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
   898
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   899
			spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   900
			spa_deactivate(spa);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   901
			spa->spa_last_open_failed = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   902
			if (locked)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   903
				mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   904
			*spapp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   905
			return (error);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   906
		} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   907
			zfs_post_ok(spa, NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   908
			spa->spa_last_open_failed = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   909
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   910
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   911
		loaded = B_TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   912
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   913
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
	spa_open_ref(spa, tag);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   915
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   916
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   917
	 * If we just loaded the pool, resilver anything that's out of date.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   918
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   919
	if (loaded && (spa_mode & FWRITE))
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   920
		VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
   921
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   922
	if (locked)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   923
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   924
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   925
	*spapp = spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   926
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   927
	if (config != NULL) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   928
		spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   929
		*config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   930
		spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   931
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   932
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   933
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   934
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   935
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   936
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   937
spa_open(const char *name, spa_t **spapp, void *tag)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   938
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   939
	return (spa_open_common(name, spapp, tag, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   940
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   941
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   942
/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   943
 * Lookup the given spa_t, incrementing the inject count in the process,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   944
 * preventing it from being exported or destroyed.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   945
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   946
spa_t *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   947
spa_inject_addref(char *name)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   948
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   949
	spa_t *spa;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   950
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   951
	mutex_enter(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   952
	if ((spa = spa_lookup(name)) == NULL) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   953
		mutex_exit(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   954
		return (NULL);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   955
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   956
	spa->spa_inject_ref++;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   957
	mutex_exit(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   958
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   959
	return (spa);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   960
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   961
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   962
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   963
spa_inject_delref(spa_t *spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   964
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   965
	mutex_enter(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   966
	spa->spa_inject_ref--;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   967
	mutex_exit(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   968
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
   969
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   970
static void
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   971
spa_add_spares(spa_t *spa, nvlist_t *config)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   972
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   973
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   974
	uint_t i, nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   975
	nvlist_t *nvroot;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   976
	uint64_t guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   977
	vdev_stat_t *vs;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   978
	uint_t vsc;
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
   979
	uint64_t pool;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   980
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   981
	if (spa->spa_nspares == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   982
		return;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   983
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   984
	VERIFY(nvlist_lookup_nvlist(config,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   985
	    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   986
	VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   987
	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   988
	if (nspares != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   989
		VERIFY(nvlist_add_nvlist_array(nvroot,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   990
		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   991
		VERIFY(nvlist_lookup_nvlist_array(nvroot,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   992
		    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   993
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   994
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   995
		 * Go through and find any spares which have since been
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   996
		 * repurposed as an active spare.  If this is the case, update
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   997
		 * their status appropriately.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   998
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
   999
		for (i = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1000
			VERIFY(nvlist_lookup_uint64(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1001
			    ZPOOL_CONFIG_GUID, &guid) == 0);
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1002
			if (spa_spare_exists(guid, &pool) && pool != 0ULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1003
				VERIFY(nvlist_lookup_uint64_array(
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1004
				    spares[i], ZPOOL_CONFIG_STATS,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1005
				    (uint64_t **)&vs, &vsc) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1006
				vs->vs_state = VDEV_STATE_CANT_OPEN;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1007
				vs->vs_aux = VDEV_AUX_SPARED;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1008
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1009
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1010
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1011
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1012
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1013
int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1014
spa_get_stats(const char *name, nvlist_t **config, char *altroot, size_t buflen)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1015
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1016
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1017
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1018
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1019
	*config = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1020
	error = spa_open_common(name, &spa, FTAG, config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1021
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1022
	if (spa && *config != NULL) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1023
		VERIFY(nvlist_add_uint64(*config, ZPOOL_CONFIG_ERRCOUNT,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1024
		    spa_get_errlog_size(spa)) == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1025
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1026
		spa_add_spares(spa, *config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1027
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1028
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1029
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1030
	 * We want to get the alternate root even for faulted pools, so we cheat
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1031
	 * and call spa_lookup() directly.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1032
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1033
	if (altroot) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1034
		if (spa == NULL) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1035
			mutex_enter(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1036
			spa = spa_lookup(name);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1037
			if (spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1038
				spa_altroot(spa, altroot, buflen);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1039
			else
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1040
				altroot[0] = '\0';
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1041
			spa = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1042
			mutex_exit(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1043
		} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1044
			spa_altroot(spa, altroot, buflen);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1045
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1046
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1047
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1048
	if (spa != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1049
		spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1050
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1051
	return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1052
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1053
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1054
/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1055
 * Validate that the 'spares' array is well formed.  We must have an array of
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1056
 * nvlists, each which describes a valid leaf vdev.  If this is an import (mode
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1057
 * is VDEV_ALLOC_SPARE), then we allow corrupted spares to be specified, as long
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1058
 * as they are well-formed.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1059
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1060
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1061
spa_validate_spares(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1062
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1063
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1064
	uint_t i, nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1065
	vdev_t *vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1066
	int error;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1067
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1068
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1069
	 * It's acceptable to have no spares specified.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1070
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1071
	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1072
	    &spares, &nspares) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1073
		return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1074
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1075
	if (nspares == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1076
		return (EINVAL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1077
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1078
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1079
	 * Make sure the pool is formatted with a version that supports hot
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1080
	 * spares.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1081
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1082
	if (spa_version(spa) < ZFS_VERSION_SPARES)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1083
		return (ENOTSUP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1084
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1085
	/*
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1086
	 * Set the pending spare list so we correctly handle device in-use
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1087
	 * checking.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1088
	 */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1089
	spa->spa_pending_spares = spares;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1090
	spa->spa_pending_nspares = nspares;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1091
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1092
	for (i = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1093
		if ((error = spa_config_parse(spa, &vd, spares[i], NULL, 0,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1094
		    mode)) != 0)
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1095
			goto out;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1096
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1097
		if (!vd->vdev_ops->vdev_op_leaf) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1098
			vdev_free(vd);
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1099
			error = EINVAL;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1100
			goto out;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1101
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1102
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1103
		vd->vdev_top = vd;
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1104
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1105
		if ((error = vdev_open(vd)) == 0 &&
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1106
		    (error = vdev_label_init(vd, crtxg,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1107
		    VDEV_LABEL_SPARE)) == 0) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1108
			VERIFY(nvlist_add_uint64(spares[i], ZPOOL_CONFIG_GUID,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1109
			    vd->vdev_guid) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1110
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1111
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1112
		vdev_free(vd);
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1113
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1114
		if (error && mode != VDEV_ALLOC_SPARE)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1115
			goto out;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1116
		else
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1117
			error = 0;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1118
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1119
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1120
out:
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1121
	spa->spa_pending_spares = NULL;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1122
	spa->spa_pending_nspares = 0;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1123
	return (error);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1124
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1125
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1126
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1127
 * Pool Creation
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1128
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1129
int
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1130
spa_create(const char *pool, nvlist_t *nvroot, const char *altroot)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1131
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1132
	spa_t *spa;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1133
	vdev_t *rvd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1134
	dsl_pool_t *dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1135
	dmu_tx_t *tx;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1136
	int c, error = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1137
	uint64_t txg = TXG_INITIAL;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1138
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1139
	uint_t nspares;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1140
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1141
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1142
	 * If this pool already exists, return failure.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1143
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1144
	mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1145
	if (spa_lookup(pool) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1146
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1147
		return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1148
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1149
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
	 * Allocate a new spa_t structure.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
	 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1153
	spa = spa_add(pool, altroot);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
	spa_activate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
	spa->spa_uberblock.ub_txg = txg - 1;
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  1157
	spa->spa_uberblock.ub_version = ZFS_VERSION;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1158
	spa->spa_ubsync = spa->spa_uberblock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1159
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1160
	/*
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1161
	 * Create the root vdev.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1162
	 */
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1163
	spa_config_enter(spa, RW_WRITER, FTAG);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1164
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1165
	error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1166
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1167
	ASSERT(error != 0 || rvd != NULL);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1168
	ASSERT(error != 0 || spa->spa_root_vdev == rvd);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1169
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1170
	if (error == 0 && rvd->vdev_children == 0)
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1171
		error = EINVAL;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1172
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1173
	if (error == 0 &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1174
	    (error = vdev_create(rvd, txg, B_FALSE)) == 0 &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1175
	    (error = spa_validate_spares(spa, nvroot, txg,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1176
	    VDEV_ALLOC_ADD)) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1177
		for (c = 0; c < rvd->vdev_children; c++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1178
			vdev_init(rvd->vdev_child[c], txg);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1179
		vdev_config_dirty(rvd);
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1180
	}
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1181
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1182
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1184
	if (error != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
		spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1186
		spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1187
		spa_remove(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1188
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1189
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1190
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1191
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1192
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1193
	 * Get the list of spares, if specified.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1194
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1195
	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1196
	    &spares, &nspares) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1197
		VERIFY(nvlist_alloc(&spa->spa_sparelist, NV_UNIQUE_NAME,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1198
		    KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1199
		VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1200
		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1201
		spa_config_enter(spa, RW_WRITER, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1202
		spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1203
		spa_config_exit(spa, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1204
		spa->spa_sync_spares = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1205
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1206
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1207
	spa->spa_dsl_pool = dp = dsl_pool_create(spa, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1208
	spa->spa_meta_objset = dp->dp_meta_objset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1210
	tx = dmu_tx_create_assigned(dp, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1211
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
	 * Create the pool config object.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
	spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
	    DMU_OT_PACKED_NVLIST, 1 << 14,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
	    DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1218
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1219
	if (zap_add(spa->spa_meta_objset,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1220
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1221
	    sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1222
		cmn_err(CE_PANIC, "failed to add pool config");
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1223
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1225
	/* Newly created pools are always deflated. */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1226
	spa->spa_deflate = TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1227
	if (zap_add(spa->spa_meta_objset,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1228
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1229
	    sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1230
		cmn_err(CE_PANIC, "failed to add deflate");
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1231
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1232
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1233
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1234
	 * Create the deferred-free bplist object.  Turn off compression
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1235
	 * because sync-to-convergence takes longer if the blocksize
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1236
	 * keeps changing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1237
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1238
	spa->spa_sync_bplist_obj = bplist_create(spa->spa_meta_objset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1239
	    1 << 14, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1240
	dmu_object_set_compress(spa->spa_meta_objset, spa->spa_sync_bplist_obj,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1241
	    ZIO_COMPRESS_OFF, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1242
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1243
	if (zap_add(spa->spa_meta_objset,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
	    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPLIST,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1245
	    sizeof (uint64_t), 1, &spa->spa_sync_bplist_obj, tx) != 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1246
		cmn_err(CE_PANIC, "failed to add bplist");
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1247
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1248
2926
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  1249
	/*
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  1250
	 * Create the pool's history object.
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  1251
	 */
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  1252
	spa_history_create_obj(spa, tx);
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  1253
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1254
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1255
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1256
	spa->spa_bootfs = zpool_prop_default_numeric(ZPOOL_PROP_BOOTFS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1257
	spa->spa_sync_on = B_TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1258
	txg_sync_start(spa->spa_dsl_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1259
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1260
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1261
	 * We explicitly wait for the first transaction to complete so that our
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1262
	 * bean counters are appropriately updated.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1263
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1264
	txg_wait_synced(spa->spa_dsl_pool, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1265
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1266
	spa_config_sync();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1267
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1268
	mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1270
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1271
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1272
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1273
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1274
 * Import the given pool into the system.  We set up the necessary spa_t and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1275
 * then call spa_load() to do the dirty work.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1276
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1277
int
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1278
spa_import(const char *pool, nvlist_t *config, const char *altroot)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1279
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1280
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1281
	int error;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1282
	nvlist_t *nvroot;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1283
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1284
	uint_t nspares;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1285
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1286
	if (!(spa_mode & FWRITE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
	 * If a pool with this name exists, return failure.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1291
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
	mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1293
	if (spa_lookup(pool) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1294
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1295
		return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1296
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1297
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1298
	/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1299
	 * Create and initialize the spa structure.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1300
	 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1301
	spa = spa_add(pool, altroot);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1302
	spa_activate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1303
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1304
	/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1305
	 * Pass off the heavy lifting to spa_load().
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1306
	 * Pass TRUE for mosconfig because the user-supplied config
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1307
	 * is actually the one to trust when doing an import.
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1308
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1309
	error = spa_load(spa, config, SPA_LOAD_IMPORT, B_TRUE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1310
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1311
	spa_config_enter(spa, RW_WRITER, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1312
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1313
	 * Toss any existing sparelist, as it doesn't have any validity anymore,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1314
	 * and conflicts with spa_has_spare().
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1315
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1316
	if (spa->spa_sparelist) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1317
		nvlist_free(spa->spa_sparelist);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1318
		spa->spa_sparelist = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1319
		spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1320
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1321
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1322
	VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1323
	    &nvroot) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1324
	if (error == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1325
		error = spa_validate_spares(spa, nvroot, -1ULL,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1326
		    VDEV_ALLOC_SPARE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1327
	spa_config_exit(spa, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1328
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1329
	if (error != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1330
		spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1331
		spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1332
		spa_remove(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1333
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1334
		return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1335
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1336
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1337
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1338
	 * Override any spares as specified by the user, as these may have
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1339
	 * correct device names/devids, etc.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1340
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1341
	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1342
	    &spares, &nspares) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1343
		if (spa->spa_sparelist)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1344
			VERIFY(nvlist_remove(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1345
			    ZPOOL_CONFIG_SPARES, DATA_TYPE_NVLIST_ARRAY) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1346
		else
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1347
			VERIFY(nvlist_alloc(&spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1348
			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1349
		VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1350
		    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1351
		spa_config_enter(spa, RW_WRITER, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1352
		spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1353
		spa_config_exit(spa, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1354
		spa->spa_sync_spares = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1355
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1356
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1357
	/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1358
	 * Update the config cache to include the newly-imported pool.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1359
	 */
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1360
	spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1361
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1362
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1363
	 * Resilver anything that's out of date.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1364
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1365
	if (spa_mode & FWRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1366
		VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1367
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1368
	mutex_exit(&spa_namespace_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1369
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1370
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1371
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1373
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1374
 * This (illegal) pool name is used when temporarily importing a spa_t in order
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1375
 * to get the vdev stats associated with the imported devices.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1376
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1377
#define	TRYIMPORT_NAME	"$import"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1378
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1379
nvlist_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1380
spa_tryimport(nvlist_t *tryconfig)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1381
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1382
	nvlist_t *config = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1383
	char *poolname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1384
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1385
	uint64_t state;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1386
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1387
	if (nvlist_lookup_string(tryconfig, ZPOOL_CONFIG_POOL_NAME, &poolname))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1388
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1389
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1390
	if (nvlist_lookup_uint64(tryconfig, ZPOOL_CONFIG_POOL_STATE, &state))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1391
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1392
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1393
	/*
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1394
	 * Create and initialize the spa structure.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1395
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1396
	mutex_enter(&spa_namespace_lock);
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1397
	spa = spa_add(TRYIMPORT_NAME, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1398
	spa_activate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1399
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1400
	/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1401
	 * Pass off the heavy lifting to spa_load().
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1402
	 * Pass TRUE for mosconfig because the user-supplied config
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1403
	 * is actually the one to trust when doing an import.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1404
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1405
	(void) spa_load(spa, tryconfig, SPA_LOAD_TRYIMPORT, B_TRUE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1406
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1407
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1408
	 * If 'tryconfig' was at least parsable, return the current config.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1409
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1410
	if (spa->spa_root_vdev != NULL) {
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1411
		spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1412
		config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1413
		spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1414
		VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1415
		    poolname) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1416
		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1417
		    state) == 0);
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
  1418
		VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3912
diff changeset
  1419
		    spa->spa_uberblock.ub_timestamp) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1420
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1421
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1422
		 * Add the list of hot spares.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1423
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1424
		spa_add_spares(spa, config);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1425
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1426
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1427
	spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1428
	spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1429
	spa_remove(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1430
	mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1431
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1432
	return (config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1433
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1434
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1435
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1436
 * Pool export/destroy
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1437
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1438
 * The act of destroying or exporting a pool is very simple.  We make sure there
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1439
 * is no more pending I/O and any references to the pool are gone.  Then, we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1440
 * update the pool state and sync all the labels to disk, removing the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1441
 * configuration from the cache afterwards.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1442
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1443
static int
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1444
spa_export_common(char *pool, int new_state, nvlist_t **oldconfig)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1445
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1446
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1447
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1448
	if (oldconfig)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1449
		*oldconfig = NULL;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1450
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1451
	if (!(spa_mode & FWRITE))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1452
		return (EROFS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1453
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1454
	mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1455
	if ((spa = spa_lookup(pool)) == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1456
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1457
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1458
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1459
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1460
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1461
	 * Put a hold on the pool, drop the namespace lock, stop async tasks,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1462
	 * reacquire the namespace lock, and see if we can export.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1463
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1464
	spa_open_ref(spa, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1465
	mutex_exit(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1466
	spa_async_suspend(spa);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1467
	mutex_enter(&spa_namespace_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1468
	spa_close(spa, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1469
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1470
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1471
	 * The pool will be in core if it's openable,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1472
	 * in which case we can modify its state.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1473
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1474
	if (spa->spa_state != POOL_STATE_UNINITIALIZED && spa->spa_sync_on) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1475
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1476
		 * Objsets may be open only because they're dirty, so we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1477
		 * have to force it to sync before checking spa_refcnt.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1478
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1479
		spa_scrub_suspend(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1480
		txg_wait_synced(spa->spa_dsl_pool, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1481
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1482
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1483
		 * A pool cannot be exported or destroyed if there are active
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1484
		 * references.  If we are resetting a pool, allow references by
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1485
		 * fault injection handlers.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1486
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1487
		if (!spa_refcount_zero(spa) ||
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1488
		    (spa->spa_inject_ref != 0 &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1489
		    new_state != POOL_STATE_UNINITIALIZED)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1490
			spa_scrub_resume(spa);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1491
			spa_async_resume(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1492
			mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1493
			return (EBUSY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1494
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1496
		spa_scrub_resume(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1497
		VERIFY(spa_scrub(spa, POOL_SCRUB_NONE, B_TRUE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1498
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1499
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1500
		 * We want this to be reflected on every label,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1501
		 * so mark them all dirty.  spa_unload() will do the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1502
		 * final sync that pushes these changes out.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1503
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1504
		if (new_state != POOL_STATE_UNINITIALIZED) {
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1505
			spa_config_enter(spa, RW_WRITER, FTAG);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1506
			spa->spa_state = new_state;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1507
			spa->spa_final_txg = spa_last_synced_txg(spa) + 1;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1508
			vdev_config_dirty(spa->spa_root_vdev);
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  1509
			spa_config_exit(spa, FTAG);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1510
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1511
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1512
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1513
	spa_event_notify(spa, NULL, ESC_ZFS_POOL_DESTROY);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1514
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1515
	if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1516
		spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1517
		spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1518
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1519
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1520
	if (oldconfig && spa->spa_config)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1521
		VERIFY(nvlist_dup(spa->spa_config, oldconfig, 0) == 0);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1522
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1523
	if (new_state != POOL_STATE_UNINITIALIZED) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1524
		spa_remove(spa);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1525
		spa_config_sync();
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1526
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1527
	mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1529
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1530
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1531
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1532
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1533
 * Destroy a storage pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1534
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1535
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1536
spa_destroy(char *pool)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1537
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1538
	return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1539
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1540
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1541
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1542
 * Export a storage pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1543
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1544
int
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1545
spa_export(char *pool, nvlist_t **oldconfig)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1546
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1547
	return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1548
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1549
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1550
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1551
 * Similar to spa_export(), this unloads the spa_t without actually removing it
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1552
 * from the namespace in any way.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1553
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1554
int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1555
spa_reset(char *pool)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1556
{
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  1557
	return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL));
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1558
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1559
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1560
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1561
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1562
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1563
 * Device manipulation
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1564
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1565
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1566
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1567
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1568
 * Add capacity to a storage pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1569
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1570
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1571
spa_vdev_add(spa_t *spa, nvlist_t *nvroot)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1572
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1573
	uint64_t txg;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1574
	int c, error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1575
	vdev_t *rvd = spa->spa_root_vdev;
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1576
	vdev_t *vd, *tvd;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1577
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1578
	uint_t i, nspares;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1579
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1580
	txg = spa_vdev_enter(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1581
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1582
	if ((error = spa_config_parse(spa, &vd, nvroot, NULL, 0,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1583
	    VDEV_ALLOC_ADD)) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1584
		return (spa_vdev_exit(spa, NULL, txg, error));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1585
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1586
	spa->spa_pending_vdev = vd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1587
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1588
	if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1589
	    &spares, &nspares) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1590
		nspares = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1591
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1592
	if (vd->vdev_children == 0 && nspares == 0) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1593
		spa->spa_pending_vdev = NULL;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1594
		return (spa_vdev_exit(spa, vd, txg, EINVAL));
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1595
	}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1596
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1597
	if (vd->vdev_children != 0) {
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1598
		if ((error = vdev_create(vd, txg, B_FALSE)) != 0) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1599
			spa->spa_pending_vdev = NULL;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1600
			return (spa_vdev_exit(spa, vd, txg, error));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1601
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1602
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1603
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1604
	/*
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1605
	 * We must validate the spares after checking the children.  Otherwise,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1606
	 * vdev_inuse() will blindly overwrite the spare.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1607
	 */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1608
	if ((error = spa_validate_spares(spa, nvroot, txg,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1609
	    VDEV_ALLOC_ADD)) != 0) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1610
		spa->spa_pending_vdev = NULL;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1611
		return (spa_vdev_exit(spa, vd, txg, error));
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1612
	}
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1613
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1614
	spa->spa_pending_vdev = NULL;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1615
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1616
	/*
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1617
	 * Transfer each new top-level vdev from vd to rvd.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1618
	 */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1619
	for (c = 0; c < vd->vdev_children; c++) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1620
		tvd = vd->vdev_child[c];
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1621
		vdev_remove_child(vd, tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1622
		tvd->vdev_id = rvd->vdev_children;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1623
		vdev_add_child(rvd, tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1624
		vdev_config_dirty(tvd);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1625
	}
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1626
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1627
	if (nspares != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1628
		if (spa->spa_sparelist != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1629
			nvlist_t **oldspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1630
			uint_t oldnspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1631
			nvlist_t **newspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1632
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1633
			VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1634
			    ZPOOL_CONFIG_SPARES, &oldspares, &oldnspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1635
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1636
			newspares = kmem_alloc(sizeof (void *) *
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1637
			    (nspares + oldnspares), KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1638
			for (i = 0; i < oldnspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1639
				VERIFY(nvlist_dup(oldspares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1640
				    &newspares[i], KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1641
			for (i = 0; i < nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1642
				VERIFY(nvlist_dup(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1643
				    &newspares[i + oldnspares],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1644
				    KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1645
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1646
			VERIFY(nvlist_remove(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1647
			    ZPOOL_CONFIG_SPARES, DATA_TYPE_NVLIST_ARRAY) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1648
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1649
			VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1650
			    ZPOOL_CONFIG_SPARES, newspares,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1651
			    nspares + oldnspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1652
			for (i = 0; i < oldnspares + nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1653
				nvlist_free(newspares[i]);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1654
			kmem_free(newspares, (oldnspares + nspares) *
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1655
			    sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1656
		} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1657
			VERIFY(nvlist_alloc(&spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1658
			    NV_UNIQUE_NAME, KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1659
			VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1660
			    ZPOOL_CONFIG_SPARES, spares, nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1661
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1662
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1663
		spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1664
		spa->spa_sync_spares = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1665
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1666
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1667
	/*
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1668
	 * We have to be careful when adding new vdevs to an existing pool.
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1669
	 * If other threads start allocating from these vdevs before we
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1670
	 * sync the config cache, and we lose power, then upon reboot we may
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1671
	 * fail to open the pool because there are DVAs that the config cache
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1672
	 * can't translate.  Therefore, we first add the vdevs without
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1673
	 * initializing metaslabs; sync the config cache (via spa_vdev_exit());
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1674
	 * and then let spa_config_update() initialize the new metaslabs.
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1675
	 *
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1676
	 * spa_load() checks for added-but-not-initialized vdevs, so that
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1677
	 * if we lose power at any point in this sequence, the remaining
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1678
	 * steps will be completed the next time we load the pool.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1679
	 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1680
	(void) spa_vdev_exit(spa, vd, txg, 0);
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1681
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1682
	mutex_enter(&spa_namespace_lock);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1683
	spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1684
	mutex_exit(&spa_namespace_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1685
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  1686
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1687
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1688
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1689
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1690
 * Attach a device to a mirror.  The arguments are the path to any device
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1691
 * in the mirror, and the nvroot for the new device.  If the path specifies
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1692
 * a device that is not mirrored, we automatically insert the mirror vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1693
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1694
 * If 'replacing' is specified, the new device is intended to replace the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1695
 * existing device; in this case the two devices are made into their own
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1696
 * mirror using the 'replacing' vdev, which is functionally identical to
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1697
 * the mirror vdev (it actually reuses all the same ops) but has a few
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1698
 * extra rules: you can't attach to it after it's been created, and upon
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1699
 * completion of resilvering, the first disk (the one being replaced)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1700
 * is automatically detached.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1701
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1702
int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1703
spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1704
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1705
	uint64_t txg, open_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1706
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1707
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1708
	vdev_t *oldvd, *newvd, *newrootvd, *pvd, *tvd;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1709
	vdev_ops_t *pvops;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1710
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1711
	txg = spa_vdev_enter(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1712
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1713
	oldvd = vdev_lookup_by_guid(rvd, guid);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1714
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1715
	if (oldvd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1716
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1717
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1718
	if (!oldvd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1719
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1720
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1721
	pvd = oldvd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1722
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1723
	if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0,
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1724
	    VDEV_ALLOC_ADD)) != 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1725
		return (spa_vdev_exit(spa, NULL, txg, EINVAL));
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1726
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1727
	if (newrootvd->vdev_children != 1)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1728
		return (spa_vdev_exit(spa, newrootvd, txg, EINVAL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1729
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1730
	newvd = newrootvd->vdev_child[0];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1732
	if (!newvd->vdev_ops->vdev_op_leaf)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1733
		return (spa_vdev_exit(spa, newrootvd, txg, EINVAL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1734
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1735
	if ((error = vdev_create(newrootvd, txg, replacing)) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1736
		return (spa_vdev_exit(spa, newrootvd, txg, error));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1737
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1738
	if (!replacing) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1739
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1740
		 * For attach, the only allowable parent is a mirror or the root
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1741
		 * vdev.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1742
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1743
		if (pvd->vdev_ops != &vdev_mirror_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1744
		    pvd->vdev_ops != &vdev_root_ops)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1745
			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1746
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1747
		pvops = &vdev_mirror_ops;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1748
	} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1749
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1750
		 * Active hot spares can only be replaced by inactive hot
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1751
		 * spares.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1752
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1753
		if (pvd->vdev_ops == &vdev_spare_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1754
		    pvd->vdev_child[1] == oldvd &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1755
		    !spa_has_spare(spa, newvd->vdev_guid))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1756
			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1757
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1758
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1759
		 * If the source is a hot spare, and the parent isn't already a
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1760
		 * spare, then we want to create a new hot spare.  Otherwise, we
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1761
		 * want to create a replacing vdev.  The user is not allowed to
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1762
		 * attach to a spared vdev child unless the 'isspare' state is
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1763
		 * the same (spare replaces spare, non-spare replaces
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1764
		 * non-spare).
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1765
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1766
		if (pvd->vdev_ops == &vdev_replacing_ops)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1767
			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1768
		else if (pvd->vdev_ops == &vdev_spare_ops &&
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1769
		    newvd->vdev_isspare != oldvd->vdev_isspare)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1770
			return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1771
		else if (pvd->vdev_ops != &vdev_spare_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1772
		    newvd->vdev_isspare)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1773
			pvops = &vdev_spare_ops;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1774
		else
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1775
			pvops = &vdev_replacing_ops;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1776
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1777
1175
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 797
diff changeset
  1778
	/*
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 797
diff changeset
  1779
	 * Compare the new device size with the replaceable/attachable
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 797
diff changeset
  1780
	 * device size.
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 797
diff changeset
  1781
	 */
759d20c7e57b 6366265 attach/replace should allow a new device size at least the min of all devs in a mirror/raidz
lling
parents: 797
diff changeset
  1782
	if (newvd->vdev_psize < vdev_get_rsize(oldvd))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1783
		return (spa_vdev_exit(spa, newrootvd, txg, EOVERFLOW));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1784
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1785
	/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1786
	 * The new device cannot have a higher alignment requirement
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1787
	 * than the top-level vdev.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1788
	 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1789
	if (newvd->vdev_ashift > oldvd->vdev_top->vdev_ashift)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1790
		return (spa_vdev_exit(spa, newrootvd, txg, EDOM));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1791
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1792
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1793
	 * If this is an in-place replacement, update oldvd's path and devid
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1794
	 * to make it distinguishable from newvd, and unopenable from now on.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1795
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1796
	if (strcmp(oldvd->vdev_path, newvd->vdev_path) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1797
		spa_strfree(oldvd->vdev_path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1798
		oldvd->vdev_path = kmem_alloc(strlen(newvd->vdev_path) + 5,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1799
		    KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1800
		(void) sprintf(oldvd->vdev_path, "%s/%s",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1801
		    newvd->vdev_path, "old");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1802
		if (oldvd->vdev_devid != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1803
			spa_strfree(oldvd->vdev_devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1804
			oldvd->vdev_devid = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1805
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1806
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1807
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1808
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1809
	 * If the parent is not a mirror, or if we're replacing, insert the new
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1810
	 * mirror/replacing/spare vdev above oldvd.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1811
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1812
	if (pvd->vdev_ops != pvops)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1813
		pvd = vdev_add_parent(oldvd, pvops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1814
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1815
	ASSERT(pvd->vdev_top->vdev_parent == rvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1816
	ASSERT(pvd->vdev_ops == pvops);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1817
	ASSERT(oldvd->vdev_parent == pvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1818
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1819
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1820
	 * Extract the new device from its root and add it to pvd.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1821
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1822
	vdev_remove_child(newrootvd, newvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1823
	newvd->vdev_id = pvd->vdev_children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1824
	vdev_add_child(pvd, newvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1825
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1826
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1827
	 * If newvd is smaller than oldvd, but larger than its rsize,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1828
	 * the addition of newvd may have decreased our parent's asize.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1829
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1830
	pvd->vdev_asize = MIN(pvd->vdev_asize, newvd->vdev_asize);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1831
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1832
	tvd = newvd->vdev_top;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1833
	ASSERT(pvd->vdev_top == tvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1834
	ASSERT(tvd->vdev_parent == rvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1835
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1836
	vdev_config_dirty(tvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1837
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1838
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1839
	 * Set newvd's DTL to [TXG_INITIAL, open_txg].  It will propagate
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1840
	 * upward when spa_vdev_exit() calls vdev_dtl_reassess().
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1841
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1842
	open_txg = txg + TXG_CONCURRENT_STATES - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1843
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1844
	mutex_enter(&newvd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1845
	space_map_add(&newvd->vdev_dtl_map, TXG_INITIAL,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1846
	    open_txg - TXG_INITIAL + 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1847
	mutex_exit(&newvd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1848
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1849
	if (newvd->vdev_isspare)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1850
		spa_spare_activate(newvd);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1851
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1852
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1853
	 * Mark newvd's DTL dirty in this txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1854
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  1855
	vdev_dirty(tvd, VDD_DTL, newvd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1856
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1857
	(void) spa_vdev_exit(spa, newrootvd, open_txg, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1859
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1860
	 * Kick off a resilver to update newvd.  We need to grab the namespace
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1861
	 * lock because spa_scrub() needs to post a sysevent with the pool name.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1862
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1863
	mutex_enter(&spa_namespace_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1864
	VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  1865
	mutex_exit(&spa_namespace_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1866
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1867
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1868
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1869
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1870
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1871
 * Detach a device from a mirror or replacing vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1872
 * If 'replace_done' is specified, only detach if the parent
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1873
 * is a replacing vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1874
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1875
int
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1876
spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1877
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1878
	uint64_t txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1879
	int c, t, error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1880
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1881
	vdev_t *vd, *pvd, *cvd, *tvd;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1882
	boolean_t unspare = B_FALSE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1883
	uint64_t unspare_guid;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1884
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1885
	txg = spa_vdev_enter(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1886
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  1887
	vd = vdev_lookup_by_guid(rvd, guid);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1888
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1889
	if (vd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1890
		return (spa_vdev_exit(spa, NULL, txg, ENODEV));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1891
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1892
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1893
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  1894
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1895
	pvd = vd->vdev_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1896
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1897
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1898
	 * If replace_done is specified, only remove this device if it's
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1899
	 * the first child of a replacing vdev.  For the 'spare' vdev, either
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1900
	 * disk can be removed.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1901
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1902
	if (replace_done) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1903
		if (pvd->vdev_ops == &vdev_replacing_ops) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1904
			if (vd->vdev_id != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1905
				return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1906
		} else if (pvd->vdev_ops != &vdev_spare_ops) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1907
			return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1908
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1909
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1910
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1911
	ASSERT(pvd->vdev_ops != &vdev_spare_ops ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1912
	    spa_version(spa) >= ZFS_VERSION_SPARES);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1913
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1914
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1915
	 * Only mirror, replacing, and spare vdevs support detach.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1916
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1917
	if (pvd->vdev_ops != &vdev_replacing_ops &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1918
	    pvd->vdev_ops != &vdev_mirror_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1919
	    pvd->vdev_ops != &vdev_spare_ops)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1920
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1921
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1922
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1923
	 * If there's only one replica, you can't detach it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1924
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1925
	if (pvd->vdev_children <= 1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1926
		return (spa_vdev_exit(spa, NULL, txg, EBUSY));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1927
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1928
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1929
	 * If all siblings have non-empty DTLs, this device may have the only
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1930
	 * valid copy of the data, which means we cannot safely detach it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1931
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1932
	 * XXX -- as in the vdev_offline() case, we really want a more
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1933
	 * precise DTL check.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1934
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1935
	for (c = 0; c < pvd->vdev_children; c++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1936
		uint64_t dirty;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1937
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1938
		cvd = pvd->vdev_child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1939
		if (cvd == vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1940
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1941
		if (vdev_is_dead(cvd))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1942
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1943
		mutex_enter(&cvd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1944
		dirty = cvd->vdev_dtl_map.sm_space |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1945
		    cvd->vdev_dtl_scrub.sm_space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1946
		mutex_exit(&cvd->vdev_dtl_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1947
		if (!dirty)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1948
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1949
	}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1950
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1951
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1952
	 * If we are a replacing or spare vdev, then we can always detach the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1953
	 * latter child, as that is how one cancels the operation.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1954
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1955
	if ((pvd->vdev_ops == &vdev_mirror_ops || vd->vdev_id != 1) &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1956
	    c == pvd->vdev_children)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1957
		return (spa_vdev_exit(spa, NULL, txg, EBUSY));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1958
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1959
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1960
	 * If we are detaching the original disk from a spare, then it implies
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1961
	 * that the spare should become a real disk, and be removed from the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1962
	 * active spare list for the pool.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1963
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1964
	if (pvd->vdev_ops == &vdev_spare_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1965
	    vd->vdev_id == 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1966
		unspare = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1967
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1968
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1969
	 * Erase the disk labels so the disk can be used for other things.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1970
	 * This must be done after all other error cases are handled,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1971
	 * but before we disembowel vd (so we can still do I/O to it).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1972
	 * But if we can't do it, don't treat the error as fatal --
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1973
	 * it may be that the unwritability of the disk is the reason
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1974
	 * it's being detached!
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1975
	 */
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1976
	error = vdev_label_init(vd, 0, VDEV_LABEL_REMOVE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1977
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1978
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1979
	 * Remove vd from its parent and compact the parent's children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1980
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1981
	vdev_remove_child(pvd, vd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1982
	vdev_compact_children(pvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1983
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1984
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1985
	 * Remember one of the remaining children so we can get tvd below.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1986
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1987
	cvd = pvd->vdev_child[0];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1988
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1989
	/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1990
	 * If we need to remove the remaining child from the list of hot spares,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1991
	 * do it now, marking the vdev as no longer a spare in the process.  We
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1992
	 * must do this before vdev_remove_parent(), because that can change the
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1993
	 * GUID if it creates a new toplevel GUID.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1994
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1995
	if (unspare) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1996
		ASSERT(cvd->vdev_isspare);
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  1997
		spa_spare_remove(cvd);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1998
		unspare_guid = cvd->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  1999
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2000
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2001
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2002
	 * If the parent mirror/replacing vdev only has one child,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2003
	 * the parent is no longer needed.  Remove it from the tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2004
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2005
	if (pvd->vdev_children == 1)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2006
		vdev_remove_parent(cvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2007
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2008
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2009
	 * We don't set tvd until now because the parent we just removed
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2010
	 * may have been the previous top-level vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2011
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2012
	tvd = cvd->vdev_top;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2013
	ASSERT(tvd->vdev_parent == rvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2014
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2015
	/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2016
	 * Reevaluate the parent vdev state.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2017
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2018
	vdev_propagate_state(cvd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2019
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2020
	/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2021
	 * If the device we just detached was smaller than the others, it may be
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2022
	 * possible to add metaslabs (i.e. grow the pool).  vdev_metaslab_init()
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2023
	 * can't fail because the existing metaslabs are already in core, so
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2024
	 * there's nothing to read from disk.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2025
	 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2026
	VERIFY(vdev_metaslab_init(tvd, txg) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2027
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2028
	vdev_config_dirty(tvd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2029
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2030
	/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2031
	 * Mark vd's DTL as dirty in this txg.  vdev_dtl_sync() will see that
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2032
	 * vd->vdev_detached is set and free vd's DTL object in syncing context.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2033
	 * But first make sure we're not on any *other* txg's DTL list, to
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2034
	 * prevent vd from being accessed after it's freed.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2035
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2036
	for (t = 0; t < TXG_SIZE; t++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2037
		(void) txg_list_remove_this(&tvd->vdev_dtl_list, vd, t);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2038
	vd->vdev_detached = B_TRUE;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2039
	vdev_dirty(tvd, VDD_DTL, vd, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2040
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2041
	spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2042
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2043
	error = spa_vdev_exit(spa, vd, txg, 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2044
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2045
	/*
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2046
	 * If this was the removal of the original device in a hot spare vdev,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2047
	 * then we want to go through and remove the device from the hot spare
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  2048
	 * list of every other pool.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2049
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2050
	if (unspare) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2051
		spa = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2052
		mutex_enter(&spa_namespace_lock);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2053
		while ((spa = spa_next(spa)) != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2054
			if (spa->spa_state != POOL_STATE_ACTIVE)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2055
				continue;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2056
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2057
			(void) spa_vdev_remove(spa, unspare_guid, B_TRUE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2058
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2059
		mutex_exit(&spa_namespace_lock);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2060
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2061
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2062
	return (error);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2063
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2064
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2065
/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2066
 * Remove a device from the pool.  Currently, this supports removing only hot
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2067
 * spares.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2068
 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2069
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2070
spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2071
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2072
	vdev_t *vd;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2073
	nvlist_t **spares, *nv, **newspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2074
	uint_t i, j, nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2075
	int ret = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2076
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2077
	spa_config_enter(spa, RW_WRITER, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2078
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2079
	vd = spa_lookup_by_guid(spa, guid);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2080
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2081
	nv = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2082
	if (spa->spa_spares != NULL &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2083
	    nvlist_lookup_nvlist_array(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2084
	    &spares, &nspares) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2085
		for (i = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2086
			uint64_t theguid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2087
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2088
			VERIFY(nvlist_lookup_uint64(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2089
			    ZPOOL_CONFIG_GUID, &theguid) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2090
			if (theguid == guid) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2091
				nv = spares[i];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2092
				break;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2093
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2094
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2095
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2096
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2097
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2098
	 * We only support removing a hot spare, and only if it's not currently
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2099
	 * in use in this pool.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2100
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2101
	if (nv == NULL && vd == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2102
		ret = ENOENT;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2103
		goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2104
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2105
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2106
	if (nv == NULL && vd != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2107
		ret = ENOTSUP;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2108
		goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2109
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2110
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2111
	if (!unspare && nv != NULL && vd != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2112
		ret = EBUSY;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2113
		goto out;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2114
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2115
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2116
	if (nspares == 1) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2117
		newspares = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2118
	} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2119
		newspares = kmem_alloc((nspares - 1) * sizeof (void *),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2120
		    KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2121
		for (i = 0, j = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2122
			if (spares[i] != nv)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2123
				VERIFY(nvlist_dup(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2124
				    &newspares[j++], KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2125
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2126
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2127
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2128
	VERIFY(nvlist_remove(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2129
	    DATA_TYPE_NVLIST_ARRAY) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2130
	VERIFY(nvlist_add_nvlist_array(spa->spa_sparelist, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2131
	    newspares, nspares - 1) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2132
	for (i = 0; i < nspares - 1; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2133
		nvlist_free(newspares[i]);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2134
	kmem_free(newspares, (nspares - 1) * sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2135
	spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2136
	spa->spa_sync_spares = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2137
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2138
out:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2139
	spa_config_exit(spa, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2140
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2141
	return (ret);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2142
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2143
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2144
/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2145
 * Find any device that's done replacing, or a vdev marked 'unspare' that's
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2146
 * current spared, so we can detach it.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2147
 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2148
static vdev_t *
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2149
spa_vdev_resilver_done_hunt(vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2150
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2151
	vdev_t *newvd, *oldvd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2152
	int c;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2153
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2154
	for (c = 0; c < vd->vdev_children; c++) {
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2155
		oldvd = spa_vdev_resilver_done_hunt(vd->vdev_child[c]);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2156
		if (oldvd != NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2157
			return (oldvd);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2158
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2159
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2160
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2161
	 * Check for a completed replacement.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2162
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2163
	if (vd->vdev_ops == &vdev_replacing_ops && vd->vdev_children == 2) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2164
		oldvd = vd->vdev_child[0];
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2165
		newvd = vd->vdev_child[1];
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2166
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2167
		mutex_enter(&newvd->vdev_dtl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2168
		if (newvd->vdev_dtl_map.sm_space == 0 &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2169
		    newvd->vdev_dtl_scrub.sm_space == 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2170
			mutex_exit(&newvd->vdev_dtl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2171
			return (oldvd);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2172
		}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2173
		mutex_exit(&newvd->vdev_dtl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2174
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2175
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2176
	/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2177
	 * Check for a completed resilver with the 'unspare' flag set.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2178
	 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2179
	if (vd->vdev_ops == &vdev_spare_ops && vd->vdev_children == 2) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2180
		newvd = vd->vdev_child[0];
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2181
		oldvd = vd->vdev_child[1];
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2182
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2183
		mutex_enter(&newvd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2184
		if (newvd->vdev_unspare &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2185
		    newvd->vdev_dtl_map.sm_space == 0 &&
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2186
		    newvd->vdev_dtl_scrub.sm_space == 0) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2187
			newvd->vdev_unspare = 0;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2188
			mutex_exit(&newvd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2189
			return (oldvd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2190
		}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2191
		mutex_exit(&newvd->vdev_dtl_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2192
	}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2193
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2194
	return (NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2195
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2196
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2197
static void
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2198
spa_vdev_resilver_done(spa_t *spa)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2199
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2200
	vdev_t *vd;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2201
	vdev_t *pvd;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2202
	uint64_t guid;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2203
	uint64_t pguid = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2204
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2205
	spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2206
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2207
	while ((vd = spa_vdev_resilver_done_hunt(spa->spa_root_vdev)) != NULL) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2208
		guid = vd->vdev_guid;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2209
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2210
		 * If we have just finished replacing a hot spared device, then
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2211
		 * we need to detach the parent's first child (the original hot
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2212
		 * spare) as well.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2213
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2214
		pvd = vd->vdev_parent;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2215
		if (pvd->vdev_parent->vdev_ops == &vdev_spare_ops &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2216
		    pvd->vdev_id == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2217
			ASSERT(pvd->vdev_ops == &vdev_replacing_ops);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2218
			ASSERT(pvd->vdev_parent->vdev_children == 2);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2219
			pguid = pvd->vdev_parent->vdev_child[1]->vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2220
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2221
		spa_config_exit(spa, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2222
		if (spa_vdev_detach(spa, guid, B_TRUE) != 0)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2223
			return;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2224
		if (pguid != 0 && spa_vdev_detach(spa, pguid, B_TRUE) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2225
			return;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2226
		spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2227
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2228
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2229
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2230
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2231
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2232
/*
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2233
 * Update the stored path for this vdev.  Dirty the vdev configuration, relying
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2234
 * on spa_vdev_enter/exit() to synchronize the labels and cache.
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2235
 */
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2236
int
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2237
spa_vdev_setpath(spa_t *spa, uint64_t guid, const char *newpath)
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2238
{
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2239
	vdev_t *rvd, *vd;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2240
	uint64_t txg;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2241
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2242
	rvd = spa->spa_root_vdev;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2243
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2244
	txg = spa_vdev_enter(spa);
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2245
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2246
	if ((vd = vdev_lookup_by_guid(rvd, guid)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2247
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2248
		 * Determine if this is a reference to a hot spare.  In that
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2249
		 * case, update the path as stored in the spare list.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2250
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2251
		nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2252
		uint_t i, nspares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2253
		if (spa->spa_sparelist != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2254
			VERIFY(nvlist_lookup_nvlist_array(spa->spa_sparelist,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2255
			    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2256
			for (i = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2257
				uint64_t theguid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2258
				VERIFY(nvlist_lookup_uint64(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2259
				    ZPOOL_CONFIG_GUID, &theguid) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2260
				if (theguid == guid)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2261
					break;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2262
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2263
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2264
			if (i == nspares)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2265
				return (spa_vdev_exit(spa, NULL, txg, ENOENT));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2266
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2267
			VERIFY(nvlist_add_string(spares[i],
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2268
			    ZPOOL_CONFIG_PATH, newpath) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2269
			spa_load_spares(spa);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2270
			spa->spa_sync_spares = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2271
			return (spa_vdev_exit(spa, NULL, txg, 0));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2272
		} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2273
			return (spa_vdev_exit(spa, NULL, txg, ENOENT));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2274
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2275
	}
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2276
1585
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  2277
	if (!vd->vdev_ops->vdev_op_leaf)
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  2278
		return (spa_vdev_exit(spa, NULL, txg, ENOTSUP));
4ad213e858a9 6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents: 1544
diff changeset
  2279
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2280
	spa_strfree(vd->vdev_path);
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2281
	vd->vdev_path = spa_strdup(newpath);
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2282
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2283
	vdev_config_dirty(vd->vdev_top);
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2284
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2285
	return (spa_vdev_exit(spa, NULL, txg, 0));
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2286
}
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2287
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1175
diff changeset
  2288
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2289
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2290
 * SPA Scrubbing
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2291
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2292
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2293
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2294
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2295
spa_scrub_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2296
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2297
	spa_t *spa = zio->io_spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2298
4309
3dfde0f4662d 6542676 ARC needs to track meta-data memory overhead
maybee
parents: 4178
diff changeset
  2299
	arc_data_buf_free(zio->io_data, zio->io_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2300
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2301
	mutex_enter(&spa->spa_scrub_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2302
	if (zio->io_error && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2303
		vdev_t *vd = zio->io_vd ? zio->io_vd : spa->spa_root_vdev;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2304
		spa->spa_scrub_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2305
		mutex_enter(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2306
		vd->vdev_stat.vs_scrub_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2307
		mutex_exit(&vd->vdev_stat_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2308
	}
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2309
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2310
	if (--spa->spa_scrub_inflight < spa->spa_scrub_maxinflight)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2311
		cv_broadcast(&spa->spa_scrub_io_cv);
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2312
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2313
	ASSERT(spa->spa_scrub_inflight >= 0);
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2314
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2315
	mutex_exit(&spa->spa_scrub_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2316
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2318
static void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2319
spa_scrub_io_start(spa_t *spa, blkptr_t *bp, int priority, int flags,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2320
    zbookmark_t *zb)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2321
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2322
	size_t size = BP_GET_LSIZE(bp);
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2323
	void *data;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2324
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2325
	mutex_enter(&spa->spa_scrub_lock);
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2326
	/*
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2327
	 * Do not give too much work to vdev(s).
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2328
	 */
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2329
	while (spa->spa_scrub_inflight >= spa->spa_scrub_maxinflight) {
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2330
		cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2331
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2332
	spa->spa_scrub_inflight++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2333
	mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2334
4309
3dfde0f4662d 6542676 ARC needs to track meta-data memory overhead
maybee
parents: 4178
diff changeset
  2335
	data = arc_data_buf_alloc(size);
3697
5340a4d98e0b 6456888 zpool scrubbing leads to memory exhaustion and system hang
mishra
parents: 3377
diff changeset
  2336
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2337
	if (zb->zb_level == -1 && BP_GET_TYPE(bp) != DMU_OT_OBJSET)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2338
		flags |= ZIO_FLAG_SPECULATIVE;	/* intent log block */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2339
1807
35c8b566d7af 6410711 intent log blocks don't get invited to pool parties
bonwick
parents: 1775
diff changeset
  2340
	flags |= ZIO_FLAG_SCRUB_THREAD | ZIO_FLAG_CANFAIL;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2341
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2342
	zio_nowait(zio_read(NULL, spa, bp, data, size,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2343
	    spa_scrub_io_done, NULL, priority, flags, zb));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2344
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2345
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2346
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2347
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2348
spa_scrub_cb(traverse_blk_cache_t *bc, spa_t *spa, void *a)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2349
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2350
	blkptr_t *bp = &bc->bc_blkptr;
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2351
	vdev_t *vd = spa->spa_root_vdev;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2352
	dva_t *dva = bp->blk_dva;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2353
	int needs_resilver = B_FALSE;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2354
	int d;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2355
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2356
	if (bc->bc_errno) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2357
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2358
		 * We can't scrub this block, but we can continue to scrub
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2359
		 * the rest of the pool.  Note the error and move along.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2360
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2361
		mutex_enter(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2362
		spa->spa_scrub_errors++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2363
		mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2364
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2365
		mutex_enter(&vd->vdev_stat_lock);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2366
		vd->vdev_stat.vs_scrub_errors++;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2367
		mutex_exit(&vd->vdev_stat_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2368
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2369
		return (ERESTART);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2370
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2371
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2372
	ASSERT(bp->blk_birth < spa->spa_scrub_maxtxg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2373
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2374
	for (d = 0; d < BP_GET_NDVAS(bp); d++) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2375
		vd = vdev_lookup_top(spa, DVA_GET_VDEV(&dva[d]));
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2376
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2377
		ASSERT(vd != NULL);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2378
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2379
		/*
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2380
		 * Keep track of how much data we've examined so that
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2381
		 * zpool(1M) status can make useful progress reports.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2382
		 */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2383
		mutex_enter(&vd->vdev_stat_lock);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2384
		vd->vdev_stat.vs_scrub_examined += DVA_GET_ASIZE(&dva[d]);
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2385
		mutex_exit(&vd->vdev_stat_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2386
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2387
		if (spa->spa_scrub_type == POOL_SCRUB_RESILVER) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2388
			if (DVA_GET_GANG(&dva[d])) {
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2389
				/*
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2390
				 * Gang members may be spread across multiple
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2391
				 * vdevs, so the best we can do is look at the
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2392
				 * pool-wide DTL.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2393
				 * XXX -- it would be better to change our
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2394
				 * allocation policy to ensure that this can't
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2395
				 * happen.
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2396
				 */
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2397
				vd = spa->spa_root_vdev;
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2398
			}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2399
			if (vdev_dtl_contains(&vd->vdev_dtl_map,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2400
			    bp->blk_birth, 1))
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2401
				needs_resilver = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2402
		}
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2403
	}
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2404
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2405
	if (spa->spa_scrub_type == POOL_SCRUB_EVERYTHING)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2406
		spa_scrub_io_start(spa, bp, ZIO_PRIORITY_SCRUB,
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2407
		    ZIO_FLAG_SCRUB, &bc->bc_bookmark);
1775
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2408
	else if (needs_resilver)
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2409
		spa_scrub_io_start(spa, bp, ZIO_PRIORITY_RESILVER,
e51e26b432c0 6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents: 1760
diff changeset
  2410
		    ZIO_FLAG_RESILVER, &bc->bc_bookmark);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2411
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2412
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2413
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2414
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2415
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2416
spa_scrub_thread(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2417
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2418
	callb_cpr_t cprinfo;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2419
	traverse_handle_t *th = spa->spa_scrub_th;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2420
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2421
	pool_scrub_type_t scrub_type = spa->spa_scrub_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2422
	int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2423
	boolean_t complete;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2424
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2425
	CALLB_CPR_INIT(&cprinfo, &spa->spa_scrub_lock, callb_generic_cpr, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2426
797
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2427
	/*
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2428
	 * If we're restarting due to a snapshot create/delete,
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2429
	 * wait for that to complete.
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2430
	 */
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2431
	txg_wait_synced(spa_get_dsl(spa), 0);
af56ba8b7e41 6344108 snapshot create/delete interlock with scrub/resilver must sync txg
bonwick
parents: 789
diff changeset
  2432
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2433
	dprintf("start %s mintxg=%llu maxtxg=%llu\n",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2434
	    scrub_type == POOL_SCRUB_RESILVER ? "resilver" : "scrub",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2435
	    spa->spa_scrub_mintxg, spa->spa_scrub_maxtxg);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2436
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2437
	spa_config_enter(spa, RW_WRITER, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2438
	vdev_reopen(rvd);		/* purge all vdev caches */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2439
	vdev_config_dirty(rvd);		/* rewrite all disk labels */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2440
	vdev_scrub_stat_update(rvd, scrub_type, B_FALSE);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2441
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2442
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2443
	mutex_enter(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2444
	spa->spa_scrub_errors = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2445
	spa->spa_scrub_active = 1;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2446
	ASSERT(spa->spa_scrub_inflight == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2447
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2448
	while (!spa->spa_scrub_stop) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2449
		CALLB_CPR_SAFE_BEGIN(&cprinfo);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2450
		while (spa->spa_scrub_suspended) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2451
			spa->spa_scrub_active = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2452
			cv_broadcast(&spa->spa_scrub_cv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2453
			cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2454
			spa->spa_scrub_active = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2455
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2456
		CALLB_CPR_SAFE_END(&cprinfo, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2457
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2458
		if (spa->spa_scrub_restart_txg != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2459
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2461
		mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2462
		error = traverse_more(th);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2463
		mutex_enter(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2464
		if (error != EAGAIN)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2465
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2466
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2467
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2468
	while (spa->spa_scrub_inflight)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2469
		cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2470
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2471
	spa->spa_scrub_active = 0;
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2472
	cv_broadcast(&spa->spa_scrub_cv);
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2473
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2474
	mutex_exit(&spa->spa_scrub_lock);
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2475
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2476
	spa_config_enter(spa, RW_WRITER, FTAG);
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2477
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2478
	mutex_enter(&spa->spa_scrub_lock);
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2479
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2480
	/*
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2481
	 * Note: we check spa_scrub_restart_txg under both spa_scrub_lock
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2482
	 * AND the spa config lock to synchronize with any config changes
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2483
	 * that revise the DTLs under spa_vdev_enter() / spa_vdev_exit().
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2484
	 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2485
	if (spa->spa_scrub_restart_txg != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2486
		error = ERESTART;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2487
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2488
	if (spa->spa_scrub_stop)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2489
		error = EINTR;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2490
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2491
	/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2492
	 * Even if there were uncorrectable errors, we consider the scrub
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2493
	 * completed.  The downside is that if there is a transient error during
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2494
	 * a resilver, we won't resilver the data properly to the target.  But
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2495
	 * if the damage is permanent (more likely) we will resilver forever,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2496
	 * which isn't really acceptable.  Since there is enough information for
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2497
	 * the user to know what has failed and why, this seems like a more
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2498
	 * tractable approach.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2499
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2500
	complete = (error == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2501
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2502
	dprintf("end %s to maxtxg=%llu %s, traverse=%d, %llu errors, stop=%u\n",
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2503
	    scrub_type == POOL_SCRUB_RESILVER ? "resilver" : "scrub",
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2504
	    spa->spa_scrub_maxtxg, complete ? "done" : "FAILED",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2505
	    error, spa->spa_scrub_errors, spa->spa_scrub_stop);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2506
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2507
	mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2508
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2509
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2510
	 * If the scrub/resilver completed, update all DTLs to reflect this.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2511
	 * Whether it succeeded or not, vacate all temporary scrub DTLs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2512
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2513
	vdev_dtl_reassess(rvd, spa_last_synced_txg(spa) + 1,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2514
	    complete ? spa->spa_scrub_maxtxg : 0, B_TRUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2515
	vdev_scrub_stat_update(rvd, POOL_SCRUB_NONE, complete);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2516
	spa_errlog_rotate(spa);
1601
438b928f80c7 6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents: 1585
diff changeset
  2517
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2518
	if (scrub_type == POOL_SCRUB_RESILVER && complete)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2519
		spa_event_notify(spa, NULL, ESC_ZFS_RESILVER_FINISH);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2520
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2521
	spa_config_exit(spa, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2522
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2523
	mutex_enter(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2524
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2525
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2526
	 * We may have finished replacing a device.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2527
	 * Let the async thread assess this and handle the detach.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2528
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2529
	spa_async_request(spa, SPA_ASYNC_RESILVER_DONE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2530
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2531
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2532
	 * If we were told to restart, our final act is to start a new scrub.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2533
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2534
	if (error == ERESTART)
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2535
		spa_async_request(spa, scrub_type == POOL_SCRUB_RESILVER ?
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2536
		    SPA_ASYNC_RESILVER : SPA_ASYNC_SCRUB);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2537
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2538
	spa->spa_scrub_type = POOL_SCRUB_NONE;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2539
	spa->spa_scrub_active = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2540
	spa->spa_scrub_thread = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2541
	cv_broadcast(&spa->spa_scrub_cv);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2542
	CALLB_CPR_EXIT(&cprinfo);	/* drops &spa->spa_scrub_lock */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2543
	thread_exit();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2544
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2545
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2546
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2547
spa_scrub_suspend(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2548
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2549
	mutex_enter(&spa->spa_scrub_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2550
	spa->spa_scrub_suspended++;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2551
	while (spa->spa_scrub_active) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2552
		cv_broadcast(&spa->spa_scrub_cv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2553
		cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2554
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2555
	while (spa->spa_scrub_inflight)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2556
		cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2557
	mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2558
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2560
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2561
spa_scrub_resume(spa_t *spa)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2562
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2563
	mutex_enter(&spa->spa_scrub_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2564
	ASSERT(spa->spa_scrub_suspended != 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2565
	if (--spa->spa_scrub_suspended == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2566
		cv_broadcast(&spa->spa_scrub_cv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2567
	mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2568
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2569
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2570
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2571
spa_scrub_restart(spa_t *spa, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2572
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2573
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2574
	 * Something happened (e.g. snapshot create/delete) that means
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2575
	 * we must restart any in-progress scrubs.  The itinerary will
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2576
	 * fix this properly.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2577
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2578
	mutex_enter(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2579
	spa->spa_scrub_restart_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2580
	mutex_exit(&spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2581
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2582
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2583
int
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2584
spa_scrub(spa_t *spa, pool_scrub_type_t type, boolean_t force)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2585
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2586
	space_seg_t *ss;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2587
	uint64_t mintxg, maxtxg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2588
	vdev_t *rvd = spa->spa_root_vdev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2589
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2590
	if ((uint_t)type >= POOL_SCRUB_TYPES)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2591
		return (ENOTSUP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2592
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2593
	mutex_enter(&spa->spa_scrub_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2594
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2595
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2596
	 * If there's a scrub or resilver already in progress, stop it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2597
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2598
	while (spa->spa_scrub_thread != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2599
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2600
		 * Don't stop a resilver unless forced.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2601
		 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2602
		if (spa->spa_scrub_type == POOL_SCRUB_RESILVER && !force) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2603
			mutex_exit(&spa->spa_scrub_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2604
			return (EBUSY);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2605
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2606
		spa->spa_scrub_stop = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2607
		cv_broadcast(&spa->spa_scrub_cv);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2608
		cv_wait(&spa->spa_scrub_cv, &spa->spa_scrub_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2609
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2610
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2611
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2612
	 * Terminate the previous traverse.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2613
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2614
	if (spa->spa_scrub_th != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2615
		traverse_fini(spa->spa_scrub_th);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2616
		spa->spa_scrub_th = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2617
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2618
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2619
	if (rvd == NULL) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2620
		ASSERT(spa->spa_scrub_stop == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2621
		ASSERT(spa->spa_scrub_type == type);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2622
		ASSERT(spa->spa_scrub_restart_txg == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2623
		mutex_exit(&spa->spa_scrub_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2624
		return (0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2625
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2626
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2627
	mintxg = TXG_INITIAL - 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2628
	maxtxg = spa_last_synced_txg(spa) + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2629
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2630
	mutex_enter(&rvd->vdev_dtl_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2631
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2632
	if (rvd->vdev_dtl_map.sm_space == 0) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2633
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2634
		 * The pool-wide DTL is empty.
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2635
		 * If this is a resilver, there's nothing to do except
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2636
		 * check whether any in-progress replacements have completed.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2637
		 */
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2638
		if (type == POOL_SCRUB_RESILVER) {
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2639
			type = POOL_SCRUB_NONE;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2640
			spa_async_request(spa, SPA_ASYNC_RESILVER_DONE);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1635
diff changeset
  2641
		}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2642
	} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2643
		/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2644
		 * The pool-wide DTL is non-empty.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2645
		 * If this is a normal scrub, upgrade to a resilver instead.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2646
		 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2647
		if (type == POOL_SCRUB_EVERYTHING)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2648
			type = POOL_SCRUB_RESILVER;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2649
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2650
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2651
	if (type == POOL_SCRUB_RESILVER) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2652
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2653
		 * Determine the resilvering boundaries.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2654
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2655
		 * Note: (mintxg, maxtxg) is an open interval,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2656
		 * i.e. mintxg and maxtxg themselves are not included.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2657
		 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2658
		 * Note: for maxtxg, we MIN with spa_last_synced_txg(spa) + 1
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2659
		 * so we don't claim to resilver a txg that's still changing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2660
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2661
		ss = avl_first(&rvd->vdev_dtl_map.sm_root);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2662
		mintxg = ss->ss_start - 1;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2663
		ss = avl_last(&rvd->vdev_dtl_map.sm_root);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2664
		maxtxg = MIN(ss->ss_end, maxtxg);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2665
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2666
		spa_event_notify(spa, NULL, ESC_ZFS_RESILVER_START);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2667
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2668
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2669
	mutex_exit(&rvd->vdev_dtl_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2670
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2671
	spa->spa_scrub_stop = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2672
	spa->spa_scrub_type = type;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2673
	spa->spa_scrub_restart_txg = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2674
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2675
	if (type != POOL_SCRUB_NONE) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2676
		spa->spa_scrub_mintxg = mintxg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2677
		spa->spa_scrub_maxtxg = maxtxg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2678
		spa->spa_scrub_th = traverse_init(spa, spa_scrub_cb, NULL,
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2679
		    ADVANCE_PRE | ADVANCE_PRUNE | ADVANCE_ZIL,
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2680
		    ZIO_FLAG_CANFAIL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2681
		traverse_add_pool(spa->spa_scrub_th, mintxg, maxtxg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2682
		spa->spa_scrub_thread = thread_create(NULL, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2683
		    spa_scrub_thread, spa, 0, &p0, TS_RUN, minclsyspri);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2684
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2685
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2686
	mutex_exit(&spa->spa_scrub_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2687
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2688
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2689
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2690
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2691
/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2692
 * ==========================================================================
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2693
 * SPA async task processing
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2694
 * ==========================================================================
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2695
 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2696
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2697
static void
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2698
spa_async_remove(spa_t *spa, vdev_t *vd)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2699
{
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2700
	vdev_t *tvd;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2701
	int c;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2702
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2703
	for (c = 0; c < vd->vdev_children; c++) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2704
		tvd = vd->vdev_child[c];
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2705
		if (tvd->vdev_remove_wanted) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2706
			tvd->vdev_remove_wanted = 0;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2707
			vdev_set_state(tvd, B_FALSE, VDEV_STATE_REMOVED,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2708
			    VDEV_AUX_NONE);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2709
			vdev_clear(spa, tvd);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2710
			vdev_config_dirty(tvd->vdev_top);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2711
		}
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2712
		spa_async_remove(spa, tvd);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2713
	}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2714
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2715
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2716
static void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2717
spa_async_thread(spa_t *spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2718
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2719
	int tasks;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2720
	uint64_t txg;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2721
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2722
	ASSERT(spa->spa_sync_on);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2723
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2724
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2725
	tasks = spa->spa_async_tasks;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2726
	spa->spa_async_tasks = 0;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2727
	mutex_exit(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2728
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2729
	/*
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2730
	 * See if the config needs to be updated.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2731
	 */
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2732
	if (tasks & SPA_ASYNC_CONFIG_UPDATE) {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2733
		mutex_enter(&spa_namespace_lock);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2734
		spa_config_update(spa, SPA_CONFIG_UPDATE_POOL);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2735
		mutex_exit(&spa_namespace_lock);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2736
	}
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2737
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2738
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2739
	 * See if any devices need to be marked REMOVED.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2740
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2741
	if (tasks & SPA_ASYNC_REMOVE) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2742
		txg = spa_vdev_enter(spa);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2743
		spa_async_remove(spa, spa->spa_root_vdev);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2744
		(void) spa_vdev_exit(spa, NULL, txg, 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2745
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2746
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2747
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2748
	 * If any devices are done replacing, detach them.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2749
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2750
	if (tasks & SPA_ASYNC_RESILVER_DONE)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2751
		spa_vdev_resilver_done(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2752
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2753
	/*
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2754
	 * Kick off a scrub.  When starting a RESILVER scrub (or an EVERYTHING
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2755
	 * scrub which can become a resilver), we need to hold
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2756
	 * spa_namespace_lock() because the sysevent we post via
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2757
	 * spa_event_notify() needs to get the name of the pool.
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2758
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2759
	if (tasks & SPA_ASYNC_SCRUB) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2760
		mutex_enter(&spa_namespace_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2761
		VERIFY(spa_scrub(spa, POOL_SCRUB_EVERYTHING, B_TRUE) == 0);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2762
		mutex_exit(&spa_namespace_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2763
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2764
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2765
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2766
	 * Kick off a resilver.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2767
	 */
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2768
	if (tasks & SPA_ASYNC_RESILVER) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2769
		mutex_enter(&spa_namespace_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2770
		VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER, B_TRUE) == 0);
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2771
		mutex_exit(&spa_namespace_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2772
	}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2773
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2774
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2775
	 * Let the world know that we're done.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2776
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2777
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2778
	spa->spa_async_thread = NULL;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2779
	cv_broadcast(&spa->spa_async_cv);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2780
	mutex_exit(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2781
	thread_exit();
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2782
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2783
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2784
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2785
spa_async_suspend(spa_t *spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2786
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2787
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2788
	spa->spa_async_suspended++;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2789
	while (spa->spa_async_thread != NULL)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2790
		cv_wait(&spa->spa_async_cv, &spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2791
	mutex_exit(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2792
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2793
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2794
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2795
spa_async_resume(spa_t *spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2796
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2797
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2798
	ASSERT(spa->spa_async_suspended != 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2799
	spa->spa_async_suspended--;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2800
	mutex_exit(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2801
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2802
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2803
static void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2804
spa_async_dispatch(spa_t *spa)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2805
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2806
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2807
	if (spa->spa_async_tasks && !spa->spa_async_suspended &&
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2808
	    spa->spa_async_thread == NULL &&
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2809
	    rootdir != NULL && !vn_is_readonly(rootdir))
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2810
		spa->spa_async_thread = thread_create(NULL, 0,
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2811
		    spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2812
	mutex_exit(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2813
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2814
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2815
void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2816
spa_async_request(spa_t *spa, int task)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2817
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2818
	mutex_enter(&spa->spa_async_lock);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2819
	spa->spa_async_tasks |= task;
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  2820
	mutex_exit(&spa->spa_async_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2821
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2822
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2823
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2824
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2825
 * SPA syncing routines
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2826
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2827
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2828
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2829
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2830
spa_sync_deferred_frees(spa_t *spa, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2831
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2832
	bplist_t *bpl = &spa->spa_sync_bplist;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2833
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2834
	blkptr_t blk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2835
	uint64_t itor = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2836
	zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2837
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2838
	uint8_t c = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2839
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2840
	zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CONFIG_HELD);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2841
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2842
	while (bplist_iterate(bpl, &itor, &blk) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2843
		zio_nowait(zio_free(zio, spa, txg, &blk, NULL, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2844
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2845
	error = zio_wait(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2846
	ASSERT3U(error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2847
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2848
	tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2849
	bplist_vacate(bpl, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2850
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2851
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2852
	 * Pre-dirty the first block so we sync to convergence faster.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2853
	 * (Usually only the first block is needed.)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2854
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2855
	dmu_write(spa->spa_meta_objset, spa->spa_sync_bplist_obj, 0, 1, &c, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2856
	dmu_tx_commit(tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2857
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2858
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2859
static void
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2860
spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2861
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2862
	char *packed = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2863
	size_t nvsize = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2864
	dmu_buf_t *db;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2865
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2866
	VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2867
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2868
	packed = kmem_alloc(nvsize, KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2869
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2870
	VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2871
	    KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2872
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2873
	dmu_write(spa->spa_meta_objset, obj, 0, nvsize, packed, tx);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2874
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2875
	kmem_free(packed, nvsize);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2876
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2877
	VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2878
	dmu_buf_will_dirty(db, tx);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2879
	*(uint64_t *)db->db_data = nvsize;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2880
	dmu_buf_rele(db, FTAG);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2881
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2882
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2883
static void
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2884
spa_sync_spares(spa_t *spa, dmu_tx_t *tx)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2885
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2886
	nvlist_t *nvroot;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2887
	nvlist_t **spares;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2888
	int i;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2889
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2890
	if (!spa->spa_sync_spares)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2891
		return;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2892
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2893
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2894
	 * Update the MOS nvlist describing the list of available spares.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2895
	 * spa_validate_spares() will have already made sure this nvlist is
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2896
	 * valid and the vdevs are labeled appropriately.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2897
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2898
	if (spa->spa_spares_object == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2899
		spa->spa_spares_object = dmu_object_alloc(spa->spa_meta_objset,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2900
		    DMU_OT_PACKED_NVLIST, 1 << 14,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2901
		    DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2902
		VERIFY(zap_update(spa->spa_meta_objset,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2903
		    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2904
		    sizeof (uint64_t), 1, &spa->spa_spares_object, tx) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2905
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2906
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2907
	VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2908
	if (spa->spa_nspares == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2909
		VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2910
		    NULL, 0) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2911
	} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2912
		spares = kmem_alloc(spa->spa_nspares * sizeof (void *),
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2913
		    KM_SLEEP);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2914
		for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2915
			spares[i] = vdev_config_generate(spa,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2916
			    spa->spa_spares[i], B_FALSE, B_TRUE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2917
		VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2918
		    spares, spa->spa_nspares) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2919
		for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2920
			nvlist_free(spares[i]);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2921
		kmem_free(spares, spa->spa_nspares * sizeof (void *));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2922
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2923
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2924
	spa_sync_nvlist(spa, spa->spa_spares_object, nvroot, tx);
2926
acfcfefbc60d PSARC 2006/288 zpool history
ek110237
parents: 2856
diff changeset
  2925
	nvlist_free(nvroot);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2926
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2927
	spa->spa_sync_spares = B_FALSE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2928
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2929
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2930
static void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2931
spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2932
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2933
	nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2934
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2935
	if (list_is_empty(&spa->spa_dirty_list))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2936
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2937
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2938
	config = spa_config_generate(spa, NULL, dmu_tx_get_txg(tx), B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2939
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2940
	if (spa->spa_config_syncing)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2941
		nvlist_free(spa->spa_config_syncing);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  2942
	spa->spa_config_syncing = config;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2943
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  2944
	spa_sync_nvlist(spa, spa->spa_config_object, config, tx);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2945
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2946
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2947
static void
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2948
spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2949
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2950
	spa_t *spa = arg1;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2951
	nvlist_t *nvp = arg2;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2952
	nvpair_t *nvpair;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2953
	objset_t *mos = spa->spa_meta_objset;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2954
	uint64_t zapobj;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2955
	uint64_t intval;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2956
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2957
	mutex_enter(&spa->spa_props_lock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2958
	if (spa->spa_pool_props_object == 0) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2959
		zapobj = zap_create(mos, DMU_OT_POOL_PROPS, DMU_OT_NONE, 0, tx);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2960
		VERIFY(zapobj > 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2961
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2962
		spa->spa_pool_props_object = zapobj;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2963
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2964
		VERIFY(zap_update(mos, DMU_POOL_DIRECTORY_OBJECT,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2965
		    DMU_POOL_PROPS, 8, 1,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2966
		    &spa->spa_pool_props_object, tx) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2967
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2968
	mutex_exit(&spa->spa_props_lock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2969
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2970
	nvpair = NULL;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2971
	while ((nvpair = nvlist_next_nvpair(nvp, nvpair))) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2972
		switch (zpool_name_to_prop(nvpair_name(nvpair))) {
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2973
		case ZPOOL_PROP_BOOTFS:
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2974
			VERIFY(nvlist_lookup_uint64(nvp,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2975
			    nvpair_name(nvpair), &spa->spa_bootfs) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2976
			VERIFY(zap_update(mos,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2977
			    spa->spa_pool_props_object,
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2978
			    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), 8, 1,
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2979
			    &spa->spa_bootfs, tx) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2980
			break;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2981
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2982
		case ZPOOL_PROP_AUTOREPLACE:
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2983
			VERIFY(nvlist_lookup_uint64(nvp,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2984
			    nvpair_name(nvpair), &intval) == 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2985
			VERIFY(zap_update(mos,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2986
			    spa->spa_pool_props_object,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2987
			    zpool_prop_to_name(ZPOOL_PROP_AUTOREPLACE), 8, 1,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2988
			    &intval, tx) == 0);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  2989
			break;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2990
		}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2991
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2992
}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  2993
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2994
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2995
 * Sync the specified transaction group.  New blocks may be dirtied as
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2996
 * part of the process, so we iterate until it converges.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2997
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2998
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  2999
spa_sync(spa_t *spa, uint64_t txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3000
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3001
	dsl_pool_t *dp = spa->spa_dsl_pool;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3002
	objset_t *mos = spa->spa_meta_objset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3003
	bplist_t *bpl = &spa->spa_sync_bplist;
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3004
	vdev_t *rvd = spa->spa_root_vdev;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3005
	vdev_t *vd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3006
	dmu_tx_t *tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3007
	int dirty_vdevs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3008
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3009
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3010
	 * Lock out configuration changes.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3011
	 */
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3012
	spa_config_enter(spa, RW_READER, FTAG);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3013
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3014
	spa->spa_syncing_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3015
	spa->spa_sync_pass = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3016
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3017
	VERIFY(0 == bplist_open(bpl, mos, spa->spa_sync_bplist_obj));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3018
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3019
	tx = dmu_tx_create_assigned(dp, txg);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3020
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3021
	/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3022
	 * If we are upgrading to ZFS_VERSION_RAIDZ_DEFLATE this txg,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3023
	 * set spa_deflate if we have no raid-z vdevs.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3024
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3025
	if (spa->spa_ubsync.ub_version < ZFS_VERSION_RAIDZ_DEFLATE &&
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3026
	    spa->spa_uberblock.ub_version >= ZFS_VERSION_RAIDZ_DEFLATE) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3027
		int i;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3028
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3029
		for (i = 0; i < rvd->vdev_children; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3030
			vd = rvd->vdev_child[i];
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3031
			if (vd->vdev_deflate_ratio != SPA_MINBLOCKSIZE)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3032
				break;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3033
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3034
		if (i == rvd->vdev_children) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3035
			spa->spa_deflate = TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3036
			VERIFY(0 == zap_add(spa->spa_meta_objset,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3037
			    DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3038
			    sizeof (uint64_t), 1, &spa->spa_deflate, tx));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3039
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3040
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3041
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3042
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3043
	 * If anything has changed in this txg, push the deferred frees
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3044
	 * from the previous txg.  If not, leave them alone so that we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3045
	 * don't generate work on an otherwise idle system.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3046
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3047
	if (!txg_list_empty(&dp->dp_dirty_datasets, txg) ||
2329
e640bebc73b3 6446569 deferred list is hooked on flintstone vitamins
ek110237
parents: 2199
diff changeset
  3048
	    !txg_list_empty(&dp->dp_dirty_dirs, txg) ||
e640bebc73b3 6446569 deferred list is hooked on flintstone vitamins
ek110237
parents: 2199
diff changeset
  3049
	    !txg_list_empty(&dp->dp_sync_tasks, txg))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3050
		spa_sync_deferred_frees(spa, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3051
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3052
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3053
	 * Iterate to convergence.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3054
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3055
	do {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3056
		spa->spa_sync_pass++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3057
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3058
		spa_sync_config_object(spa, tx);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3059
		spa_sync_spares(spa, tx);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3060
		spa_errlog_sync(spa, txg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3061
		dsl_pool_sync(dp, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3062
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3063
		dirty_vdevs = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3064
		while (vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3065
			vdev_sync(vd, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3066
			dirty_vdevs++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3067
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3068
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3069
		bplist_sync(bpl, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3070
	} while (dirty_vdevs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3071
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3072
	bplist_close(bpl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3073
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3074
	dprintf("txg %llu passes %d\n", txg, spa->spa_sync_pass);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3075
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3076
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3077
	 * Rewrite the vdev configuration (which includes the uberblock)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3078
	 * to commit the transaction group.
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3079
	 *
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3080
	 * If there are any dirty vdevs, sync the uberblock to all vdevs.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3081
	 * Otherwise, pick a random top-level vdev that's known to be
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3082
	 * visible in the config cache (see spa_vdev_add() for details).
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3083
	 * If the write fails, try the next vdev until we're tried them all.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3084
	 */
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3085
	if (!list_is_empty(&spa->spa_dirty_list)) {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3086
		VERIFY(vdev_config_sync(rvd, txg) == 0);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3087
	} else {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3088
		int children = rvd->vdev_children;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3089
		int c0 = spa_get_random(children);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3090
		int c;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3091
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3092
		for (c = 0; c < children; c++) {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3093
			vd = rvd->vdev_child[(c0 + c) % children];
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3094
			if (vd->vdev_ms_array == 0)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3095
				continue;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3096
			if (vdev_config_sync(vd, txg) == 0)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3097
				break;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3098
		}
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3099
		if (c == children)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3100
			VERIFY(vdev_config_sync(rvd, txg) == 0);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3101
	}
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3102
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3103
	dmu_tx_commit(tx);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3104
1635
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3105
	/*
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3106
	 * Clear the dirty config list.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3107
	 */
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3108
	while ((vd = list_head(&spa->spa_dirty_list)) != NULL)
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3109
		vdev_config_clean(vd);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3110
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3111
	/*
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3112
	 * Now that the new config has synced transactionally,
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3113
	 * let it become visible to the config cache.
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3114
	 */
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3115
	if (spa->spa_config_syncing != NULL) {
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3116
		spa_config_set(spa, spa->spa_config_syncing);
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3117
		spa->spa_config_txg = txg;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3118
		spa->spa_config_syncing = NULL;
0ab1193d47cb 6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents: 1601
diff changeset
  3119
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3120
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3121
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3122
	 * Make a stable copy of the fully synced uberblock.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3123
	 * We use this as the root for pool traversals.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3124
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3125
	spa->spa_traverse_wanted = 1;	/* tells traverse_more() to stop */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3127
	spa_scrub_suspend(spa);		/* stop scrubbing and finish I/Os */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3128
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3129
	rw_enter(&spa->spa_traverse_lock, RW_WRITER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3130
	spa->spa_traverse_wanted = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3131
	spa->spa_ubsync = spa->spa_uberblock;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3132
	rw_exit(&spa->spa_traverse_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3133
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3134
	spa_scrub_resume(spa);		/* resume scrub with new ubsync */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3136
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3137
	 * Clean up the ZIL records for the synced txg.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3138
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3139
	dsl_pool_zil_clean(dp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3140
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3141
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3142
	 * Update usable space statistics.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3143
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3144
	while (vd = txg_list_remove(&spa->spa_vdev_txg_list, TXG_CLEAN(txg)))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3145
		vdev_sync_done(vd, txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3146
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3147
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3148
	 * It had better be the case that we didn't dirty anything
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3149
	 * since vdev_config_sync().
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3150
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3151
	ASSERT(txg_list_empty(&dp->dp_dirty_datasets, txg));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3152
	ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3153
	ASSERT(txg_list_empty(&spa->spa_vdev_txg_list, txg));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3154
	ASSERT(bpl->bpl_queue == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3155
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3156
	spa_config_exit(spa, FTAG);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3157
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3158
	/*
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3159
	 * If any async tasks have been requested, kick them off.
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3160
	 */
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3161
	spa_async_dispatch(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3162
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3164
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3165
 * Sync all pools.  We don't want to hold the namespace lock across these
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3166
 * operations, so we take a reference on the spa_t and drop the lock during the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3167
 * sync.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3168
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3169
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3170
spa_sync_allpools(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3171
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3172
	spa_t *spa = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3173
	mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3174
	while ((spa = spa_next(spa)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3175
		if (spa_state(spa) != POOL_STATE_ACTIVE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3176
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3177
		spa_open_ref(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3178
		mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3179
		txg_wait_synced(spa_get_dsl(spa), 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3180
		mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3181
		spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3182
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3183
	mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3184
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3185
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3186
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3187
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3188
 * Miscellaneous routines
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3189
 * ==========================================================================
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3190
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3191
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3192
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3193
 * Remove all pools in the system.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3194
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3195
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3196
spa_evict_all(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3197
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3198
	spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3199
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3200
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3201
	 * Remove all cached state.  All pools should be closed now,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3202
	 * so every spa in the AVL tree should be unreferenced.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3203
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3204
	mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3205
	while ((spa = spa_next(NULL)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3206
		/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3207
		 * Stop async tasks.  The async thread may need to detach
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3208
		 * a device that's been replaced, which requires grabbing
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3209
		 * spa_namespace_lock, so we must drop it here.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3210
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3211
		spa_open_ref(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3212
		mutex_exit(&spa_namespace_lock);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3213
		spa_async_suspend(spa);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3214
		VERIFY(spa_scrub(spa, POOL_SCRUB_NONE, B_TRUE) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3215
		mutex_enter(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3216
		spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3217
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3218
		if (spa->spa_state != POOL_STATE_UNINITIALIZED) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3219
			spa_unload(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3220
			spa_deactivate(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3221
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3222
		spa_remove(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3223
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3224
	mutex_exit(&spa_namespace_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  3225
}
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3226
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3227
vdev_t *
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3228
spa_lookup_by_guid(spa_t *spa, uint64_t guid)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3229
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3230
	return (vdev_lookup_by_guid(spa->spa_root_vdev, guid));
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
  3231
}
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3232
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3233
void
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3234
spa_upgrade(spa_t *spa)
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3235
{
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3236
	spa_config_enter(spa, RW_WRITER, FTAG);
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3237
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3238
	/*
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3239
	 * This should only be called for a non-faulted pool, and since a
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3240
	 * future version would result in an unopenable pool, this shouldn't be
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3241
	 * possible.
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3242
	 */
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3243
	ASSERT(spa->spa_uberblock.ub_version <= ZFS_VERSION);
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3244
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3245
	spa->spa_uberblock.ub_version = ZFS_VERSION;
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3246
	vdev_config_dirty(spa->spa_root_vdev);
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3247
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3248
	spa_config_exit(spa, FTAG);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3249
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3250
	txg_wait_synced(spa_get_dsl(spa), 0);
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1733
diff changeset
  3251
}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3252
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3253
boolean_t
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3254
spa_has_spare(spa_t *spa, uint64_t guid)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3255
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3256
	int i;
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3257
	uint64_t spareguid;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3258
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3259
	for (i = 0; i < spa->spa_nspares; i++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3260
		if (spa->spa_spares[i]->vdev_guid == guid)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3261
			return (B_TRUE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3262
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3263
	for (i = 0; i < spa->spa_pending_nspares; i++) {
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3264
		if (nvlist_lookup_uint64(spa->spa_pending_spares[i],
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3265
		    ZPOOL_CONFIG_GUID, &spareguid) == 0 &&
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3266
		    spareguid == guid)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3267
			return (B_TRUE);
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3268
	}
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3290
diff changeset
  3269
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3270
	return (B_FALSE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1986
diff changeset
  3271
}
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3272
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3273
int
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3274
spa_set_props(spa_t *spa, nvlist_t *nvp)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3275
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3276
	return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3277
	    spa, nvp, 3));
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3278
}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3279
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3280
int
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3281
spa_get_props(spa_t *spa, nvlist_t **nvp)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3282
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3283
	zap_cursor_t zc;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3284
	zap_attribute_t za;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3285
	objset_t *mos = spa->spa_meta_objset;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3286
	zfs_source_t src;
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3287
	zpool_prop_t prop;
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3288
	nvlist_t *propval;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3289
	uint64_t value;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3290
	int err;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3291
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3292
	VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3293
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3294
	mutex_enter(&spa->spa_props_lock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3295
	/* If no props object, then just return empty nvlist */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3296
	if (spa->spa_pool_props_object == 0) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3297
		mutex_exit(&spa->spa_props_lock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3298
		return (0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3299
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3300
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3301
	for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3302
	    (err = zap_cursor_retrieve(&zc, &za)) == 0;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3303
	    zap_cursor_advance(&zc)) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3304
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3305
		if ((prop = zpool_name_to_prop(za.za_name)) == ZFS_PROP_INVAL)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3306
			continue;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3307
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3308
		VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3309
		switch (za.za_integer_length) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3310
		case 8:
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3311
			if (zpool_prop_default_numeric(prop) ==
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3312
			    za.za_first_integer)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3313
				src = ZFS_SRC_DEFAULT;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3314
			else
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3315
				src = ZFS_SRC_LOCAL;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3316
			value = za.za_first_integer;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3317
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3318
			if (prop == ZPOOL_PROP_BOOTFS) {
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3319
				dsl_pool_t *dp;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3320
				dsl_dataset_t *ds = NULL;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3321
				char strval[MAXPATHLEN];
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3322
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3323
				dp = spa_get_dsl(spa);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3324
				rw_enter(&dp->dp_config_rwlock, RW_READER);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3325
				if ((err = dsl_dataset_open_obj(dp,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3326
				    za.za_first_integer, NULL, DS_MODE_NONE,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3327
				    FTAG, &ds)) != 0) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3328
					rw_exit(&dp->dp_config_rwlock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3329
					break;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3330
				}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3331
				dsl_dataset_name(ds, strval);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3332
				dsl_dataset_close(ds, DS_MODE_NONE, FTAG);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3333
				rw_exit(&dp->dp_config_rwlock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3334
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3335
				VERIFY(nvlist_add_uint64(propval,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3336
				    ZFS_PROP_SOURCE, src) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3337
				VERIFY(nvlist_add_string(propval,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3338
				    ZFS_PROP_VALUE, strval) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3339
			} else {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3340
				VERIFY(nvlist_add_uint64(propval,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3341
				    ZFS_PROP_SOURCE, src) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3342
				VERIFY(nvlist_add_uint64(propval,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3343
				    ZFS_PROP_VALUE, value) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3344
			}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3345
			VERIFY(nvlist_add_nvlist(*nvp, za.za_name,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3346
			    propval) == 0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3347
			break;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3348
		}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3349
		nvlist_free(propval);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3350
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3351
	zap_cursor_fini(&zc);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3352
	mutex_exit(&spa->spa_props_lock);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3353
	if (err && err != ENOENT) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3354
		nvlist_free(*nvp);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3355
		return (err);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3356
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3357
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3358
	return (0);
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3359
}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3360
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3361
/*
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3362
 * If the bootfs property value is dsobj, clear it.
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3363
 */
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3364
void
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3365
spa_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx)
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3366
{
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3367
	if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) {
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3368
		VERIFY(zap_remove(spa->spa_meta_objset,
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3369
		    spa->spa_pool_props_object,
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3370
		    zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0);
3912
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3371
		spa->spa_bootfs = 0;
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3372
	}
f6891a60bd72 PSARC 2007/083 ZFS bootable datasets
lling
parents: 3697
diff changeset
  3373
}
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3374
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3375
/*
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3376
 * Post a sysevent corresponding to the given event.  The 'name' must be one of
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3377
 * the event definitions in sys/sysevent/eventdefs.h.  The payload will be
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3378
 * filled in from the spa and (optionally) the vdev.  This doesn't do anything
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3379
 * in the userland libzpool, as we don't want consumers to misinterpret ztest
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3380
 * or zdb as real changes.
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3381
 */
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3382
void
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3383
spa_event_notify(spa_t *spa, vdev_t *vd, const char *name)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3384
{
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3385
#ifdef _KERNEL
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3386
	sysevent_t		*ev;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3387
	sysevent_attr_list_t	*attr = NULL;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3388
	sysevent_value_t	value;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3389
	sysevent_id_t		eid;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3390
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3391
	ev = sysevent_alloc(EC_ZFS, (char *)name, SUNW_KERN_PUB "zfs",
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3392
	    SE_SLEEP);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3393
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3394
	value.value_type = SE_DATA_TYPE_STRING;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3395
	value.value.sv_string = spa_name(spa);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3396
	if (sysevent_add_attr(&attr, ZFS_EV_POOL_NAME, &value, SE_SLEEP) != 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3397
		goto done;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3398
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3399
	value.value_type = SE_DATA_TYPE_UINT64;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3400
	value.value.sv_uint64 = spa_guid(spa);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3401
	if (sysevent_add_attr(&attr, ZFS_EV_POOL_GUID, &value, SE_SLEEP) != 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3402
		goto done;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3403
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3404
	if (vd) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3405
		value.value_type = SE_DATA_TYPE_UINT64;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3406
		value.value.sv_uint64 = vd->vdev_guid;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3407
		if (sysevent_add_attr(&attr, ZFS_EV_VDEV_GUID, &value,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3408
		    SE_SLEEP) != 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3409
			goto done;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3410
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3411
		if (vd->vdev_path) {
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3412
			value.value_type = SE_DATA_TYPE_STRING;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3413
			value.value.sv_string = vd->vdev_path;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3414
			if (sysevent_add_attr(&attr, ZFS_EV_VDEV_PATH,
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3415
			    &value, SE_SLEEP) != 0)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3416
				goto done;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3417
		}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3418
	}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3419
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3420
	(void) log_sysevent(ev, SE_SLEEP, &eid);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3421
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3422
done:
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3423
	if (attr)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3424
		sysevent_free_attr(attr);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3425
	sysevent_free(ev);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3426
#endif
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 4309
diff changeset
  3427
}