Mercurial > illumos > illumos-gate
annotate usr/src/uts/common/fs/zfs/spa.c @ 7046:361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
6343693 'zpool status' gives delayed start for 'zpool scrub'
6670746 scrub on degraded pool return the status of 'resilver completed'?
6675685 DTL entries are lost resulting in checksum errors
6706404 get_history_one() can dereference off end of hist_event_table[]
6715414 assertion failed: ds->ds_owner != tag in dsl_dataset_rele()
6716437 ztest gets SEGV in arc_released()
6722838 bfu does not update grub
author | ahrens |
---|---|
date | Mon, 07 Jul 2008 13:39:21 -0700 |
parents | 46fc4b6db23e |
children | 1e1d75c88283 |
rev | line source |
---|---|
789 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
1544 | 5 * Common Development and Distribution License (the "License"). |
6 * You may not use this file except in compliance with the License. | |
789 | 7 * |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
10 * See the License for the specific language governing permissions | |
11 * and limitations under the License. | |
12 * | |
13 * When distributing Covered Code, include this CDDL HEADER in each | |
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 * If applicable, add the following below this CDDL HEADER, with the | |
16 * fields enclosed by brackets "[]" replaced with your own identifying | |
17 * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
2082 | 21 |
789 | 22 /* |
5756
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
789 | 24 * Use is subject to license terms. |
25 */ | |
26 | |
27 #pragma ident "%Z%%M% %I% %E% SMI" | |
28 | |
29 /* | |
30 * This file contains all the routines used when modifying on-disk SPA state. | |
31 * This includes opening, importing, destroying, exporting a pool, and syncing a | |
32 * pool. | |
33 */ | |
34 | |
35 #include <sys/zfs_context.h> | |
1544 | 36 #include <sys/fm/fs/zfs.h> |
789 | 37 #include <sys/spa_impl.h> |
38 #include <sys/zio.h> | |
39 #include <sys/zio_checksum.h> | |
40 #include <sys/zio_compress.h> | |
41 #include <sys/dmu.h> | |
42 #include <sys/dmu_tx.h> | |
43 #include <sys/zap.h> | |
44 #include <sys/zil.h> | |
45 #include <sys/vdev_impl.h> | |
46 #include <sys/metaslab.h> | |
47 #include <sys/uberblock_impl.h> | |
48 #include <sys/txg.h> | |
49 #include <sys/avl.h> | |
50 #include <sys/dmu_traverse.h> | |
3912 | 51 #include <sys/dmu_objset.h> |
789 | 52 #include <sys/unique.h> |
53 #include <sys/dsl_pool.h> | |
3912 | 54 #include <sys/dsl_dataset.h> |
789 | 55 #include <sys/dsl_dir.h> |
56 #include <sys/dsl_prop.h> | |
3912 | 57 #include <sys/dsl_synctask.h> |
789 | 58 #include <sys/fs/zfs.h> |
5450 | 59 #include <sys/arc.h> |
789 | 60 #include <sys/callb.h> |
3975
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
61 #include <sys/systeminfo.h> |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
62 #include <sys/sunddi.h> |
6423 | 63 #include <sys/spa_boot.h> |
789 | 64 |
5094 | 65 #include "zfs_prop.h" |
5913
a77f8ad2ce63
6575965 panic/thread=2a1016b5ca0: BAD TRAP: type=9 rp=1858500 addr=0 mmu_fsr=0, really, truly out of space
perrin
parents:
5886
diff
changeset
|
66 #include "zfs_comutil.h" |
5094 | 67 |
2986 | 68 int zio_taskq_threads = 8; |
69 | |
5094 | 70 static void spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx); |
71 | |
72 /* | |
73 * ========================================================================== | |
74 * SPA properties routines | |
75 * ========================================================================== | |
76 */ | |
77 | |
78 /* | |
79 * Add a (source=src, propname=propval) list to an nvlist. | |
80 */ | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
81 static void |
5094 | 82 spa_prop_add_list(nvlist_t *nvl, zpool_prop_t prop, char *strval, |
83 uint64_t intval, zprop_source_t src) | |
84 { | |
85 const char *propname = zpool_prop_to_name(prop); | |
86 nvlist_t *propval; | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
87 |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
88 VERIFY(nvlist_alloc(&propval, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
89 VERIFY(nvlist_add_uint64(propval, ZPROP_SOURCE, src) == 0); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
90 |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
91 if (strval != NULL) |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
92 VERIFY(nvlist_add_string(propval, ZPROP_VALUE, strval) == 0); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
93 else |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
94 VERIFY(nvlist_add_uint64(propval, ZPROP_VALUE, intval) == 0); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
95 |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
96 VERIFY(nvlist_add_nvlist(nvl, propname, propval) == 0); |
5094 | 97 nvlist_free(propval); |
98 } | |
99 | |
100 /* | |
101 * Get property values from the spa configuration. | |
102 */ | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
103 static void |
5094 | 104 spa_prop_get_config(spa_t *spa, nvlist_t **nvp) |
105 { | |
106 uint64_t size = spa_get_space(spa); | |
107 uint64_t used = spa_get_alloc(spa); | |
108 uint64_t cap, version; | |
109 zprop_source_t src = ZPROP_SRC_NONE; | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
110 spa_config_dirent_t *dp; |
5094 | 111 |
112 /* | |
113 * readonly properties | |
114 */ | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
115 spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa->spa_name, 0, src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
116 spa_prop_add_list(*nvp, ZPOOL_PROP_SIZE, NULL, size, src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
117 spa_prop_add_list(*nvp, ZPOOL_PROP_USED, NULL, used, src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
118 spa_prop_add_list(*nvp, ZPOOL_PROP_AVAILABLE, NULL, size - used, src); |
5094 | 119 |
120 cap = (size == 0) ? 0 : (used * 100 / size); | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
121 spa_prop_add_list(*nvp, ZPOOL_PROP_CAPACITY, NULL, cap, src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
122 |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
123 spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
124 spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL, |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
125 spa->spa_root_vdev->vdev_state, src); |
5094 | 126 |
127 /* | |
128 * settable properties that are not stored in the pool property object. | |
129 */ | |
130 version = spa_version(spa); | |
131 if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) | |
132 src = ZPROP_SRC_DEFAULT; | |
133 else | |
134 src = ZPROP_SRC_LOCAL; | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
135 spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src); |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
136 |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
137 if (spa->spa_root != NULL) |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
138 spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root, |
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
139 0, ZPROP_SRC_LOCAL); |
5094 | 140 |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
141 if ((dp = list_head(&spa->spa_config_list)) != NULL) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
142 if (dp->scd_path == NULL) { |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
143 spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
144 "none", 0, ZPROP_SRC_LOCAL); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
145 } else if (strcmp(dp->scd_path, spa_config_path) != 0) { |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
146 spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
147 dp->scd_path, 0, ZPROP_SRC_LOCAL); |
5363 | 148 } |
149 } | |
5094 | 150 } |
151 | |
152 /* | |
153 * Get zpool property values. | |
154 */ | |
155 int | |
156 spa_prop_get(spa_t *spa, nvlist_t **nvp) | |
157 { | |
158 zap_cursor_t zc; | |
159 zap_attribute_t za; | |
160 objset_t *mos = spa->spa_meta_objset; | |
161 int err; | |
162 | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
163 VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
5094 | 164 |
165 /* | |
166 * Get properties from the spa config. | |
167 */ | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
168 spa_prop_get_config(spa, nvp); |
5094 | 169 |
170 mutex_enter(&spa->spa_props_lock); | |
171 /* If no pool property object, no more prop to get. */ | |
172 if (spa->spa_pool_props_object == 0) { | |
173 mutex_exit(&spa->spa_props_lock); | |
174 return (0); | |
175 } | |
176 | |
177 /* | |
178 * Get properties from the MOS pool property object. | |
179 */ | |
180 for (zap_cursor_init(&zc, mos, spa->spa_pool_props_object); | |
181 (err = zap_cursor_retrieve(&zc, &za)) == 0; | |
182 zap_cursor_advance(&zc)) { | |
183 uint64_t intval = 0; | |
184 char *strval = NULL; | |
185 zprop_source_t src = ZPROP_SRC_DEFAULT; | |
186 zpool_prop_t prop; | |
187 | |
188 if ((prop = zpool_name_to_prop(za.za_name)) == ZPROP_INVAL) | |
189 continue; | |
190 | |
191 switch (za.za_integer_length) { | |
192 case 8: | |
193 /* integer property */ | |
194 if (za.za_first_integer != | |
195 zpool_prop_default_numeric(prop)) | |
196 src = ZPROP_SRC_LOCAL; | |
197 | |
198 if (prop == ZPOOL_PROP_BOOTFS) { | |
199 dsl_pool_t *dp; | |
200 dsl_dataset_t *ds = NULL; | |
201 | |
202 dp = spa_get_dsl(spa); | |
203 rw_enter(&dp->dp_config_rwlock, RW_READER); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6673
diff
changeset
|
204 if (err = dsl_dataset_hold_obj(dp, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6673
diff
changeset
|
205 za.za_first_integer, FTAG, &ds)) { |
5094 | 206 rw_exit(&dp->dp_config_rwlock); |
207 break; | |
208 } | |
209 | |
210 strval = kmem_alloc( | |
211 MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, | |
212 KM_SLEEP); | |
213 dsl_dataset_name(ds, strval); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6673
diff
changeset
|
214 dsl_dataset_rele(ds, FTAG); |
5094 | 215 rw_exit(&dp->dp_config_rwlock); |
216 } else { | |
217 strval = NULL; | |
218 intval = za.za_first_integer; | |
219 } | |
220 | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
221 spa_prop_add_list(*nvp, prop, strval, intval, src); |
5094 | 222 |
223 if (strval != NULL) | |
224 kmem_free(strval, | |
225 MAXNAMELEN + strlen(MOS_DIR_NAME) + 1); | |
226 | |
227 break; | |
228 | |
229 case 1: | |
230 /* string property */ | |
231 strval = kmem_alloc(za.za_num_integers, KM_SLEEP); | |
232 err = zap_lookup(mos, spa->spa_pool_props_object, | |
233 za.za_name, 1, za.za_num_integers, strval); | |
234 if (err) { | |
235 kmem_free(strval, za.za_num_integers); | |
236 break; | |
237 } | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
238 spa_prop_add_list(*nvp, prop, strval, 0, src); |
5094 | 239 kmem_free(strval, za.za_num_integers); |
240 break; | |
241 | |
242 default: | |
243 break; | |
244 } | |
245 } | |
246 zap_cursor_fini(&zc); | |
247 mutex_exit(&spa->spa_props_lock); | |
248 out: | |
249 if (err && err != ENOENT) { | |
250 nvlist_free(*nvp); | |
5949
02e692d1cb28
6654224 zfs_ioc_pool_get_props() double-frees nvlist on error
lling
parents:
5913
diff
changeset
|
251 *nvp = NULL; |
5094 | 252 return (err); |
253 } | |
254 | |
255 return (0); | |
256 } | |
257 | |
258 /* | |
259 * Validate the given pool properties nvlist and modify the list | |
260 * for the property values to be set. | |
261 */ | |
262 static int | |
263 spa_prop_validate(spa_t *spa, nvlist_t *props) | |
264 { | |
265 nvpair_t *elem; | |
266 int error = 0, reset_bootfs = 0; | |
267 uint64_t objnum; | |
268 | |
269 elem = NULL; | |
270 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { | |
271 zpool_prop_t prop; | |
272 char *propname, *strval; | |
273 uint64_t intval; | |
274 objset_t *os; | |
5363 | 275 char *slash; |
5094 | 276 |
277 propname = nvpair_name(elem); | |
278 | |
279 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) | |
280 return (EINVAL); | |
281 | |
282 switch (prop) { | |
283 case ZPOOL_PROP_VERSION: | |
284 error = nvpair_value_uint64(elem, &intval); | |
285 if (!error && | |
286 (intval < spa_version(spa) || intval > SPA_VERSION)) | |
287 error = EINVAL; | |
288 break; | |
289 | |
290 case ZPOOL_PROP_DELEGATION: | |
291 case ZPOOL_PROP_AUTOREPLACE: | |
292 error = nvpair_value_uint64(elem, &intval); | |
293 if (!error && intval > 1) | |
294 error = EINVAL; | |
295 break; | |
296 | |
297 case ZPOOL_PROP_BOOTFS: | |
298 if (spa_version(spa) < SPA_VERSION_BOOTFS) { | |
299 error = ENOTSUP; | |
300 break; | |
301 } | |
302 | |
303 /* | |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
304 * Make sure the vdev config is bootable |
5094 | 305 */ |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
306 if (!vdev_is_bootable(spa->spa_root_vdev)) { |
5094 | 307 error = ENOTSUP; |
308 break; | |
309 } | |
310 | |
311 reset_bootfs = 1; | |
312 | |
313 error = nvpair_value_string(elem, &strval); | |
314 | |
315 if (!error) { | |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
316 uint64_t compress; |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
317 |
5094 | 318 if (strval == NULL || strval[0] == '\0') { |
319 objnum = zpool_prop_default_numeric( | |
320 ZPOOL_PROP_BOOTFS); | |
321 break; | |
322 } | |
323 | |
324 if (error = dmu_objset_open(strval, DMU_OST_ZFS, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6673
diff
changeset
|
325 DS_MODE_USER | DS_MODE_READONLY, &os)) |
5094 | 326 break; |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
327 |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
328 /* We don't support gzip bootable datasets */ |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
329 if ((error = dsl_prop_get_integer(strval, |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
330 zfs_prop_to_name(ZFS_PROP_COMPRESSION), |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
331 &compress, NULL)) == 0 && |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
332 !BOOTFS_COMPRESS_VALID(compress)) { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
333 error = ENOTSUP; |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
334 } else { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
335 objnum = dmu_objset_id(os); |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6995
diff
changeset
|
336 } |
5094 | 337 dmu_objset_close(os); |
338 } | |
339 break; | |
5329 | 340 case ZPOOL_PROP_FAILUREMODE: |
341 error = nvpair_value_uint64(elem, &intval); | |
342 if (!error && (intval < ZIO_FAILURE_MODE_WAIT || | |
343 intval > ZIO_FAILURE_MODE_PANIC)) | |
344 error = EINVAL; | |
345 | |
346 /* | |
347 * This is a special case which only occurs when | |
348 * the pool has completely failed. This allows | |
349 * the user to change the in-core failmode property | |
350 * without syncing it out to disk (I/Os might | |
351 * currently be blocked). We do this by returning | |
352 * EIO to the caller (spa_prop_set) to trick it | |
353 * into thinking we encountered a property validation | |
354 * error. | |
355 */ | |
356 if (!error && spa_state(spa) == POOL_STATE_IO_FAILURE) { | |
357 spa->spa_failmode = intval; | |
358 error = EIO; | |
359 } | |
360 break; | |
5363 | 361 |
362 case ZPOOL_PROP_CACHEFILE: | |
363 if ((error = nvpair_value_string(elem, &strval)) != 0) | |
364 break; | |
365 | |
366 if (strval[0] == '\0') | |
367 break; | |
368 | |
369 if (strcmp(strval, "none") == 0) | |
370 break; | |
371 | |
372 if (strval[0] != '/') { | |
373 error = EINVAL; | |
374 break; | |
375 } | |
376 | |
377 slash = strrchr(strval, '/'); | |
378 ASSERT(slash != NULL); | |
379 | |
380 if (slash[1] == '\0' || strcmp(slash, "/.") == 0 || | |
381 strcmp(slash, "/..") == 0) | |
382 error = EINVAL; | |
383 break; | |
5094 | 384 } |
385 | |
386 if (error) | |
387 break; | |
388 } | |
389 | |
390 if (!error && reset_bootfs) { | |
391 error = nvlist_remove(props, | |
392 zpool_prop_to_name(ZPOOL_PROP_BOOTFS), DATA_TYPE_STRING); | |
393 | |
394 if (!error) { | |
395 error = nvlist_add_uint64(props, | |
396 zpool_prop_to_name(ZPOOL_PROP_BOOTFS), objnum); | |
397 } | |
398 } | |
399 | |
400 return (error); | |
401 } | |
402 | |
403 int | |
404 spa_prop_set(spa_t *spa, nvlist_t *nvp) | |
405 { | |
406 int error; | |
407 | |
408 if ((error = spa_prop_validate(spa, nvp)) != 0) | |
409 return (error); | |
410 | |
411 return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props, | |
412 spa, nvp, 3)); | |
413 } | |
414 | |
415 /* | |
416 * If the bootfs property value is dsobj, clear it. | |
417 */ | |
418 void | |
419 spa_prop_clear_bootfs(spa_t *spa, uint64_t dsobj, dmu_tx_t *tx) | |
420 { | |
421 if (spa->spa_bootfs == dsobj && spa->spa_pool_props_object != 0) { | |
422 VERIFY(zap_remove(spa->spa_meta_objset, | |
423 spa->spa_pool_props_object, | |
424 zpool_prop_to_name(ZPOOL_PROP_BOOTFS), tx) == 0); | |
425 spa->spa_bootfs = 0; | |
426 } | |
427 } | |
428 | |
789 | 429 /* |
430 * ========================================================================== | |
431 * SPA state manipulation (open/create/destroy/import/export) | |
432 * ========================================================================== | |
433 */ | |
434 | |
1544 | 435 static int |
436 spa_error_entry_compare(const void *a, const void *b) | |
437 { | |
438 spa_error_entry_t *sa = (spa_error_entry_t *)a; | |
439 spa_error_entry_t *sb = (spa_error_entry_t *)b; | |
440 int ret; | |
441 | |
442 ret = bcmp(&sa->se_bookmark, &sb->se_bookmark, | |
443 sizeof (zbookmark_t)); | |
444 | |
445 if (ret < 0) | |
446 return (-1); | |
447 else if (ret > 0) | |
448 return (1); | |
449 else | |
450 return (0); | |
451 } | |
452 | |
453 /* | |
454 * Utility function which retrieves copies of the current logs and | |
455 * re-initializes them in the process. | |
456 */ | |
457 void | |
458 spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub) | |
459 { | |
460 ASSERT(MUTEX_HELD(&spa->spa_errlist_lock)); | |
461 | |
462 bcopy(&spa->spa_errlist_last, last, sizeof (avl_tree_t)); | |
463 bcopy(&spa->spa_errlist_scrub, scrub, sizeof (avl_tree_t)); | |
464 | |
465 avl_create(&spa->spa_errlist_scrub, | |
466 spa_error_entry_compare, sizeof (spa_error_entry_t), | |
467 offsetof(spa_error_entry_t, se_avl)); | |
468 avl_create(&spa->spa_errlist_last, | |
469 spa_error_entry_compare, sizeof (spa_error_entry_t), | |
470 offsetof(spa_error_entry_t, se_avl)); | |
471 } | |
472 | |
789 | 473 /* |
474 * Activate an uninitialized pool. | |
475 */ | |
476 static void | |
477 spa_activate(spa_t *spa) | |
478 { | |
479 int t; | |
480 | |
481 ASSERT(spa->spa_state == POOL_STATE_UNINITIALIZED); | |
482 | |
483 spa->spa_state = POOL_STATE_ACTIVE; | |
484 | |
485 spa->spa_normal_class = metaslab_class_create(); | |
4527 | 486 spa->spa_log_class = metaslab_class_create(); |
789 | 487 |
488 for (t = 0; t < ZIO_TYPES; t++) { | |
489 spa->spa_zio_issue_taskq[t] = taskq_create("spa_zio_issue", | |
2986 | 490 zio_taskq_threads, maxclsyspri, 50, INT_MAX, |
789 | 491 TASKQ_PREPOPULATE); |
492 spa->spa_zio_intr_taskq[t] = taskq_create("spa_zio_intr", | |
2986 | 493 zio_taskq_threads, maxclsyspri, 50, INT_MAX, |
789 | 494 TASKQ_PREPOPULATE); |
495 } | |
496 | |
497 list_create(&spa->spa_dirty_list, sizeof (vdev_t), | |
498 offsetof(vdev_t, vdev_dirty_node)); | |
5329 | 499 list_create(&spa->spa_zio_list, sizeof (zio_t), |
500 offsetof(zio_t, zio_link_node)); | |
789 | 501 |
502 txg_list_create(&spa->spa_vdev_txg_list, | |
503 offsetof(struct vdev, vdev_txg_node)); | |
1544 | 504 |
505 avl_create(&spa->spa_errlist_scrub, | |
506 spa_error_entry_compare, sizeof (spa_error_entry_t), | |
507 offsetof(spa_error_entry_t, se_avl)); | |
508 avl_create(&spa->spa_errlist_last, | |
509 spa_error_entry_compare, sizeof (spa_error_entry_t), | |
510 offsetof(spa_error_entry_t, se_avl)); | |
789 | 511 } |
512 | |
513 /* | |
514 * Opposite of spa_activate(). | |
515 */ | |
516 static void | |
517 spa_deactivate(spa_t *spa) | |
518 { | |
519 int t; | |
520 | |
521 ASSERT(spa->spa_sync_on == B_FALSE); | |
522 ASSERT(spa->spa_dsl_pool == NULL); | |
523 ASSERT(spa->spa_root_vdev == NULL); | |
524 | |
525 ASSERT(spa->spa_state != POOL_STATE_UNINITIALIZED); | |
526 | |
527 txg_list_destroy(&spa->spa_vdev_txg_list); | |
528 | |
529 list_destroy(&spa->spa_dirty_list); | |
5329 | 530 list_destroy(&spa->spa_zio_list); |
789 | 531 |
532 for (t = 0; t < ZIO_TYPES; t++) { | |
533 taskq_destroy(spa->spa_zio_issue_taskq[t]); | |
534 taskq_destroy(spa->spa_zio_intr_taskq[t]); | |
535 spa->spa_zio_issue_taskq[t] = NULL; | |
536 spa->spa_zio_intr_taskq[t] = NULL; | |
537 } | |
538 | |
539 metaslab_class_destroy(spa->spa_normal_class); | |
540 spa->spa_normal_class = NULL; | |
541 | |
4527 | 542 metaslab_class_destroy(spa->spa_log_class); |
543 spa->spa_log_class = NULL; | |
544 | |
1544 | 545 /* |
546 * If this was part of an import or the open otherwise failed, we may | |
547 * still have errors left in the queues. Empty them just in case. | |
548 */ | |
549 spa_errlog_drain(spa); | |
550 | |
551 avl_destroy(&spa->spa_errlist_scrub); | |
552 avl_destroy(&spa->spa_errlist_last); | |
553 | |
789 | 554 spa->spa_state = POOL_STATE_UNINITIALIZED; |
555 } | |
556 | |
557 /* | |
558 * Verify a pool configuration, and construct the vdev tree appropriately. This | |
559 * will create all the necessary vdevs in the appropriate layout, with each vdev | |
560 * in the CLOSED state. This will prep the pool before open/creation/import. | |
561 * All vdev validation is done by the vdev_alloc() routine. | |
562 */ | |
2082 | 563 static int |
564 spa_config_parse(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, | |
565 uint_t id, int atype) | |
789 | 566 { |
567 nvlist_t **child; | |
568 uint_t c, children; | |
2082 | 569 int error; |
570 | |
571 if ((error = vdev_alloc(spa, vdp, nv, parent, id, atype)) != 0) | |
572 return (error); | |
573 | |
574 if ((*vdp)->vdev_ops->vdev_op_leaf) | |
575 return (0); | |
789 | 576 |
577 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, | |
578 &child, &children) != 0) { | |
2082 | 579 vdev_free(*vdp); |
580 *vdp = NULL; | |
581 return (EINVAL); | |
789 | 582 } |
583 | |
584 for (c = 0; c < children; c++) { | |
2082 | 585 vdev_t *vd; |
586 if ((error = spa_config_parse(spa, &vd, child[c], *vdp, c, | |
587 atype)) != 0) { | |
588 vdev_free(*vdp); | |
589 *vdp = NULL; | |
590 return (error); | |
789 | 591 } |
592 } | |
593 | |
2082 | 594 ASSERT(*vdp != NULL); |
595 | |
596 return (0); | |
789 | 597 } |
598 | |
599 /* | |
600 * Opposite of spa_load(). | |
601 */ | |
602 static void | |
603 spa_unload(spa_t *spa) | |
604 { | |
2082 | 605 int i; |
606 | |
789 | 607 /* |
1544 | 608 * Stop async tasks. |
609 */ | |
610 spa_async_suspend(spa); | |
611 | |
612 /* | |
789 | 613 * Stop syncing. |
614 */ | |
615 if (spa->spa_sync_on) { | |
616 txg_sync_stop(spa->spa_dsl_pool); | |
617 spa->spa_sync_on = B_FALSE; | |
618 } | |
619 | |
620 /* | |
621 * Wait for any outstanding prefetch I/O to complete. | |
622 */ | |
1544 | 623 spa_config_enter(spa, RW_WRITER, FTAG); |
624 spa_config_exit(spa, FTAG); | |
789 | 625 |
626 /* | |
5450 | 627 * Drop and purge level 2 cache |
628 */ | |
629 spa_l2cache_drop(spa); | |
630 | |
631 /* | |
789 | 632 * Close the dsl pool. |
633 */ | |
634 if (spa->spa_dsl_pool) { | |
635 dsl_pool_close(spa->spa_dsl_pool); | |
636 spa->spa_dsl_pool = NULL; | |
637 } | |
638 | |
639 /* | |
640 * Close all vdevs. | |
641 */ | |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
642 if (spa->spa_root_vdev) |
789 | 643 vdev_free(spa->spa_root_vdev); |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
644 ASSERT(spa->spa_root_vdev == NULL); |
1544 | 645 |
5450 | 646 for (i = 0; i < spa->spa_spares.sav_count; i++) |
647 vdev_free(spa->spa_spares.sav_vdevs[i]); | |
648 if (spa->spa_spares.sav_vdevs) { | |
649 kmem_free(spa->spa_spares.sav_vdevs, | |
650 spa->spa_spares.sav_count * sizeof (void *)); | |
651 spa->spa_spares.sav_vdevs = NULL; | |
652 } | |
653 if (spa->spa_spares.sav_config) { | |
654 nvlist_free(spa->spa_spares.sav_config); | |
655 spa->spa_spares.sav_config = NULL; | |
2082 | 656 } |
5450 | 657 |
658 for (i = 0; i < spa->spa_l2cache.sav_count; i++) | |
659 vdev_free(spa->spa_l2cache.sav_vdevs[i]); | |
660 if (spa->spa_l2cache.sav_vdevs) { | |
661 kmem_free(spa->spa_l2cache.sav_vdevs, | |
662 spa->spa_l2cache.sav_count * sizeof (void *)); | |
663 spa->spa_l2cache.sav_vdevs = NULL; | |
664 } | |
665 if (spa->spa_l2cache.sav_config) { | |
666 nvlist_free(spa->spa_l2cache.sav_config); | |
667 spa->spa_l2cache.sav_config = NULL; | |
2082 | 668 } |
669 | |
1544 | 670 spa->spa_async_suspended = 0; |
789 | 671 } |
672 | |
673 /* | |
2082 | 674 * Load (or re-load) the current list of vdevs describing the active spares for |
675 * this pool. When this is called, we have some form of basic information in | |
5450 | 676 * 'spa_spares.sav_config'. We parse this into vdevs, try to open them, and |
677 * then re-generate a more complete list including status information. | |
2082 | 678 */ |
679 static void | |
680 spa_load_spares(spa_t *spa) | |
681 { | |
682 nvlist_t **spares; | |
683 uint_t nspares; | |
684 int i; | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
685 vdev_t *vd, *tvd; |
2082 | 686 |
687 /* | |
688 * First, close and free any existing spare vdevs. | |
689 */ | |
5450 | 690 for (i = 0; i < spa->spa_spares.sav_count; i++) { |
691 vd = spa->spa_spares.sav_vdevs[i]; | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
692 |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
693 /* Undo the call to spa_activate() below */ |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
694 if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
695 B_FALSE)) != NULL && tvd->vdev_isspare) |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
696 spa_spare_remove(tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
697 vdev_close(vd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
698 vdev_free(vd); |
2082 | 699 } |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
700 |
5450 | 701 if (spa->spa_spares.sav_vdevs) |
702 kmem_free(spa->spa_spares.sav_vdevs, | |
703 spa->spa_spares.sav_count * sizeof (void *)); | |
704 | |
705 if (spa->spa_spares.sav_config == NULL) | |
2082 | 706 nspares = 0; |
707 else | |
5450 | 708 VERIFY(nvlist_lookup_nvlist_array(spa->spa_spares.sav_config, |
2082 | 709 ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0); |
710 | |
5450 | 711 spa->spa_spares.sav_count = (int)nspares; |
712 spa->spa_spares.sav_vdevs = NULL; | |
2082 | 713 |
714 if (nspares == 0) | |
715 return; | |
716 | |
717 /* | |
718 * 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
|
719 * 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
|
720 * 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
|
721 * 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
|
722 * 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
|
723 * 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
|
724 * active configuration, then we also mark this vdev as an active spare. |
2082 | 725 */ |
5450 | 726 spa->spa_spares.sav_vdevs = kmem_alloc(nspares * sizeof (void *), |
727 KM_SLEEP); | |
728 for (i = 0; i < spa->spa_spares.sav_count; i++) { | |
2082 | 729 VERIFY(spa_config_parse(spa, &vd, spares[i], NULL, 0, |
730 VDEV_ALLOC_SPARE) == 0); | |
731 ASSERT(vd != NULL); | |
732 | |
5450 | 733 spa->spa_spares.sav_vdevs[i] = vd; |
2082 | 734 |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
735 if ((tvd = spa_lookup_by_guid(spa, vd->vdev_guid, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
736 B_FALSE)) != NULL) { |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
737 if (!tvd->vdev_isspare) |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
738 spa_spare_add(tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
739 |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
740 /* |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
741 * 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
|
742 * 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
|
743 * 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
|
744 * 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
|
745 * is actively in use. |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
746 * |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
747 * 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
|
748 * 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
|
749 * 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
|
750 * 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
|
751 * it adds, we ignore the possibility. |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
752 */ |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
753 if (!vdev_is_dead(tvd)) |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
754 spa_spare_activate(tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
755 } |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
756 |
2082 | 757 if (vdev_open(vd) != 0) |
758 continue; | |
759 | |
760 vd->vdev_top = vd; | |
5450 | 761 if (vdev_validate_aux(vd) == 0) |
762 spa_spare_add(vd); | |
2082 | 763 } |
764 | |
765 /* | |
766 * Recompute the stashed list of spares, with status information | |
767 * this time. | |
768 */ | |
5450 | 769 VERIFY(nvlist_remove(spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES, |
2082 | 770 DATA_TYPE_NVLIST_ARRAY) == 0); |
771 | |
5450 | 772 spares = kmem_alloc(spa->spa_spares.sav_count * sizeof (void *), |
773 KM_SLEEP); | |
774 for (i = 0; i < spa->spa_spares.sav_count; i++) | |
775 spares[i] = vdev_config_generate(spa, | |
776 spa->spa_spares.sav_vdevs[i], B_TRUE, B_TRUE, B_FALSE); | |
777 VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config, | |
778 ZPOOL_CONFIG_SPARES, spares, spa->spa_spares.sav_count) == 0); | |
779 for (i = 0; i < spa->spa_spares.sav_count; i++) | |
2082 | 780 nvlist_free(spares[i]); |
5450 | 781 kmem_free(spares, spa->spa_spares.sav_count * sizeof (void *)); |
782 } | |
783 | |
784 /* | |
785 * Load (or re-load) the current list of vdevs describing the active l2cache for | |
786 * this pool. When this is called, we have some form of basic information in | |
787 * 'spa_l2cache.sav_config'. We parse this into vdevs, try to open them, and | |
788 * then re-generate a more complete list including status information. | |
789 * Devices which are already active have their details maintained, and are | |
790 * not re-opened. | |
791 */ | |
792 static void | |
793 spa_load_l2cache(spa_t *spa) | |
794 { | |
795 nvlist_t **l2cache; | |
796 uint_t nl2cache; | |
797 int i, j, oldnvdevs; | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
798 uint64_t guid, size; |
5450 | 799 vdev_t *vd, **oldvdevs, **newvdevs; |
800 spa_aux_vdev_t *sav = &spa->spa_l2cache; | |
801 | |
802 if (sav->sav_config != NULL) { | |
803 VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, | |
804 ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0); | |
805 newvdevs = kmem_alloc(nl2cache * sizeof (void *), KM_SLEEP); | |
806 } else { | |
807 nl2cache = 0; | |
808 } | |
809 | |
810 oldvdevs = sav->sav_vdevs; | |
811 oldnvdevs = sav->sav_count; | |
812 sav->sav_vdevs = NULL; | |
813 sav->sav_count = 0; | |
814 | |
815 /* | |
816 * Process new nvlist of vdevs. | |
817 */ | |
818 for (i = 0; i < nl2cache; i++) { | |
819 VERIFY(nvlist_lookup_uint64(l2cache[i], ZPOOL_CONFIG_GUID, | |
820 &guid) == 0); | |
821 | |
822 newvdevs[i] = NULL; | |
823 for (j = 0; j < oldnvdevs; j++) { | |
824 vd = oldvdevs[j]; | |
825 if (vd != NULL && guid == vd->vdev_guid) { | |
826 /* | |
827 * Retain previous vdev for add/remove ops. | |
828 */ | |
829 newvdevs[i] = vd; | |
830 oldvdevs[j] = NULL; | |
831 break; | |
832 } | |
833 } | |
834 | |
835 if (newvdevs[i] == NULL) { | |
836 /* | |
837 * Create new vdev | |
838 */ | |
839 VERIFY(spa_config_parse(spa, &vd, l2cache[i], NULL, 0, | |
840 VDEV_ALLOC_L2CACHE) == 0); | |
841 ASSERT(vd != NULL); | |
842 newvdevs[i] = vd; | |
843 | |
844 /* | |
845 * Commit this vdev as an l2cache device, | |
846 * even if it fails to open. | |
847 */ | |
848 spa_l2cache_add(vd); | |
849 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
850 vd->vdev_top = vd; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
851 vd->vdev_aux = sav; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
852 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
853 spa_l2cache_activate(vd); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
854 |
5450 | 855 if (vdev_open(vd) != 0) |
856 continue; | |
857 | |
858 (void) vdev_validate_aux(vd); | |
859 | |
860 if (!vdev_is_dead(vd)) { | |
861 size = vdev_get_rsize(vd); | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
862 l2arc_add_vdev(spa, vd, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
863 VDEV_LABEL_START_SIZE, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
864 size - VDEV_LABEL_START_SIZE); |
5450 | 865 } |
866 } | |
867 } | |
868 | |
869 /* | |
870 * Purge vdevs that were dropped | |
871 */ | |
872 for (i = 0; i < oldnvdevs; i++) { | |
873 uint64_t pool; | |
874 | |
875 vd = oldvdevs[i]; | |
876 if (vd != NULL) { | |
877 if (spa_mode & FWRITE && | |
878 spa_l2cache_exists(vd->vdev_guid, &pool) && | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
879 pool != 0ULL && |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
880 l2arc_vdev_present(vd)) { |
5450 | 881 l2arc_remove_vdev(vd); |
882 } | |
883 (void) vdev_close(vd); | |
884 spa_l2cache_remove(vd); | |
885 } | |
886 } | |
887 | |
888 if (oldvdevs) | |
889 kmem_free(oldvdevs, oldnvdevs * sizeof (void *)); | |
890 | |
891 if (sav->sav_config == NULL) | |
892 goto out; | |
893 | |
894 sav->sav_vdevs = newvdevs; | |
895 sav->sav_count = (int)nl2cache; | |
896 | |
897 /* | |
898 * Recompute the stashed list of l2cache devices, with status | |
899 * information this time. | |
900 */ | |
901 VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE, | |
902 DATA_TYPE_NVLIST_ARRAY) == 0); | |
903 | |
904 l2cache = kmem_alloc(sav->sav_count * sizeof (void *), KM_SLEEP); | |
905 for (i = 0; i < sav->sav_count; i++) | |
906 l2cache[i] = vdev_config_generate(spa, | |
907 sav->sav_vdevs[i], B_TRUE, B_FALSE, B_TRUE); | |
908 VERIFY(nvlist_add_nvlist_array(sav->sav_config, | |
909 ZPOOL_CONFIG_L2CACHE, l2cache, sav->sav_count) == 0); | |
910 out: | |
911 for (i = 0; i < sav->sav_count; i++) | |
912 nvlist_free(l2cache[i]); | |
913 if (sav->sav_count) | |
914 kmem_free(l2cache, sav->sav_count * sizeof (void *)); | |
2082 | 915 } |
916 | |
917 static int | |
918 load_nvlist(spa_t *spa, uint64_t obj, nvlist_t **value) | |
919 { | |
920 dmu_buf_t *db; | |
921 char *packed = NULL; | |
922 size_t nvsize = 0; | |
923 int error; | |
924 *value = NULL; | |
925 | |
926 VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db)); | |
927 nvsize = *(uint64_t *)db->db_data; | |
928 dmu_buf_rele(db, FTAG); | |
929 | |
930 packed = kmem_alloc(nvsize, KM_SLEEP); | |
931 error = dmu_read(spa->spa_meta_objset, obj, 0, nvsize, packed); | |
932 if (error == 0) | |
933 error = nvlist_unpack(packed, nvsize, value, 0); | |
934 kmem_free(packed, nvsize); | |
935 | |
936 return (error); | |
937 } | |
938 | |
939 /* | |
4451 | 940 * Checks to see if the given vdev could not be opened, in which case we post a |
941 * sysevent to notify the autoreplace code that the device has been removed. | |
942 */ | |
943 static void | |
944 spa_check_removed(vdev_t *vd) | |
945 { | |
946 int c; | |
947 | |
948 for (c = 0; c < vd->vdev_children; c++) | |
949 spa_check_removed(vd->vdev_child[c]); | |
950 | |
951 if (vd->vdev_ops->vdev_op_leaf && vdev_is_dead(vd)) { | |
952 zfs_post_autoreplace(vd->vdev_spa, vd); | |
953 spa_event_notify(vd->vdev_spa, vd, ESC_ZFS_VDEV_CHECK); | |
954 } | |
955 } | |
956 | |
957 /* | |
789 | 958 * Load an existing storage pool, using the pool's builtin spa_config as a |
1544 | 959 * source of configuration information. |
789 | 960 */ |
961 static int | |
1544 | 962 spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) |
789 | 963 { |
964 int error = 0; | |
965 nvlist_t *nvroot = NULL; | |
966 vdev_t *rvd; | |
967 uberblock_t *ub = &spa->spa_uberblock; | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
968 uint64_t config_cache_txg = spa->spa_config_txg; |
789 | 969 uint64_t pool_guid; |
2082 | 970 uint64_t version; |
789 | 971 zio_t *zio; |
4451 | 972 uint64_t autoreplace = 0; |
789 | 973 |
1544 | 974 spa->spa_load_state = state; |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
975 |
789 | 976 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) || |
1733 | 977 nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid)) { |
1544 | 978 error = EINVAL; |
979 goto out; | |
980 } | |
789 | 981 |
2082 | 982 /* |
983 * Versioning wasn't explicitly added to the label until later, so if | |
984 * it's not present treat it as the initial version. | |
985 */ | |
986 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) != 0) | |
4577 | 987 version = SPA_VERSION_INITIAL; |
2082 | 988 |
1733 | 989 (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, |
990 &spa->spa_config_txg); | |
991 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
992 if ((state == SPA_LOAD_IMPORT || state == SPA_LOAD_TRYIMPORT) && |
1544 | 993 spa_guid_exists(pool_guid, 0)) { |
994 error = EEXIST; | |
995 goto out; | |
996 } | |
789 | 997 |
2174
73de7a781492
6433717 offline devices should not be marked persistently unavailble
eschrock
parents:
2082
diff
changeset
|
998 spa->spa_load_guid = pool_guid; |
73de7a781492
6433717 offline devices should not be marked persistently unavailble
eschrock
parents:
2082
diff
changeset
|
999 |
789 | 1000 /* |
2082 | 1001 * Parse the configuration into a vdev tree. We explicitly set the |
1002 * value that will be returned by spa_version() since parsing the | |
1003 * configuration requires knowing the version number. | |
789 | 1004 */ |
1544 | 1005 spa_config_enter(spa, RW_WRITER, FTAG); |
2082 | 1006 spa->spa_ubsync.ub_version = version; |
1007 error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_LOAD); | |
1544 | 1008 spa_config_exit(spa, FTAG); |
789 | 1009 |
2082 | 1010 if (error != 0) |
1544 | 1011 goto out; |
789 | 1012 |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
1013 ASSERT(spa->spa_root_vdev == rvd); |
789 | 1014 ASSERT(spa_guid(spa) == pool_guid); |
1015 | |
1016 /* | |
1017 * Try to open all vdevs, loading each label in the process. | |
1018 */ | |
4070
4390ea390a1e
6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents:
3975
diff
changeset
|
1019 error = vdev_open(rvd); |
4390ea390a1e
6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents:
3975
diff
changeset
|
1020 if (error != 0) |
1544 | 1021 goto out; |
789 | 1022 |
1023 /* | |
1986
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1024 * 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
|
1025 * 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
|
1026 * flag. |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1027 */ |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1028 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
|
1029 error = vdev_validate(rvd); |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1030 spa_config_exit(spa, FTAG); |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1031 |
4070
4390ea390a1e
6386594 zdb message should be clearer when failing for lack of permissions
mc142369
parents:
3975
diff
changeset
|
1032 if (error != 0) |
1986
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1033 goto out; |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1034 |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1035 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
|
1036 error = ENXIO; |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1037 goto out; |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1038 } |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1039 |
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1040 /* |
789 | 1041 * Find the best uberblock. |
1042 */ | |
1043 bzero(ub, sizeof (uberblock_t)); | |
1044 | |
1045 zio = zio_root(spa, NULL, NULL, | |
1046 ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE); | |
1047 vdev_uberblock_load(zio, rvd, ub); | |
1048 error = zio_wait(zio); | |
1049 | |
1050 /* | |
1051 * If we weren't able to find a single valid uberblock, return failure. | |
1052 */ | |
1053 if (ub->ub_txg == 0) { | |
1760 | 1054 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1055 VDEV_AUX_CORRUPT_DATA); | |
1544 | 1056 error = ENXIO; |
1057 goto out; | |
1058 } | |
1059 | |
1060 /* | |
1061 * If the pool is newer than the code, we can't open it. | |
1062 */ | |
4577 | 1063 if (ub->ub_version > SPA_VERSION) { |
1760 | 1064 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1065 VDEV_AUX_VERSION_NEWER); | |
1544 | 1066 error = ENOTSUP; |
1067 goto out; | |
789 | 1068 } |
1069 | |
1070 /* | |
1071 * If the vdev guid sum doesn't match the uberblock, we have an | |
1072 * incomplete configuration. | |
1073 */ | |
1732 | 1074 if (rvd->vdev_guid_sum != ub->ub_guid_sum && mosconfig) { |
1544 | 1075 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1076 VDEV_AUX_BAD_GUID_SUM); | |
1077 error = ENXIO; | |
1078 goto out; | |
789 | 1079 } |
1080 | |
1081 /* | |
1082 * Initialize internal SPA structures. | |
1083 */ | |
1084 spa->spa_state = POOL_STATE_ACTIVE; | |
1085 spa->spa_ubsync = spa->spa_uberblock; | |
1086 spa->spa_first_txg = spa_last_synced_txg(spa) + 1; | |
1544 | 1087 error = dsl_pool_open(spa, spa->spa_first_txg, &spa->spa_dsl_pool); |
1088 if (error) { | |
1089 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1090 VDEV_AUX_CORRUPT_DATA); | |
1091 goto out; | |
1092 } | |
789 | 1093 spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset; |
1094 | |
1544 | 1095 if (zap_lookup(spa->spa_meta_objset, |
789 | 1096 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG, |
1544 | 1097 sizeof (uint64_t), 1, &spa->spa_config_object) != 0) { |
1098 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1099 VDEV_AUX_CORRUPT_DATA); | |
1100 error = EIO; | |
1101 goto out; | |
1102 } | |
789 | 1103 |
1104 if (!mosconfig) { | |
2082 | 1105 nvlist_t *newconfig; |
3975
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1106 uint64_t hostid; |
2082 | 1107 |
1108 if (load_nvlist(spa, spa->spa_config_object, &newconfig) != 0) { | |
1544 | 1109 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1110 VDEV_AUX_CORRUPT_DATA); | |
1111 error = EIO; | |
1112 goto out; | |
1113 } | |
789 | 1114 |
3975
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1115 if (nvlist_lookup_uint64(newconfig, ZPOOL_CONFIG_HOSTID, |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1116 &hostid) == 0) { |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1117 char *hostname; |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1118 unsigned long myhostid = 0; |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1119 |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1120 VERIFY(nvlist_lookup_string(newconfig, |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1121 ZPOOL_CONFIG_HOSTNAME, &hostname) == 0); |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1122 |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1123 (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
|
1124 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
|
1125 (unsigned long)hostid != myhostid) { |
3975
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1126 cmn_err(CE_WARN, "pool '%s' could not be " |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1127 "loaded as it was last accessed by " |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1128 "another system (host: %s hostid: 0x%lx). " |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1129 "See: http://www.sun.com/msg/ZFS-8000-EY", |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1130 spa->spa_name, hostname, |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1131 (unsigned long)hostid); |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1132 error = EBADF; |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1133 goto out; |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1134 } |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1135 } |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
1136 |
789 | 1137 spa_config_set(spa, newconfig); |
1138 spa_unload(spa); | |
1139 spa_deactivate(spa); | |
1140 spa_activate(spa); | |
1141 | |
1544 | 1142 return (spa_load(spa, newconfig, state, B_TRUE)); |
1143 } | |
1144 | |
1145 if (zap_lookup(spa->spa_meta_objset, | |
1146 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPLIST, | |
1147 sizeof (uint64_t), 1, &spa->spa_sync_bplist_obj) != 0) { | |
1148 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1149 VDEV_AUX_CORRUPT_DATA); | |
1150 error = EIO; | |
1151 goto out; | |
789 | 1152 } |
1153 | |
1544 | 1154 /* |
2082 | 1155 * Load the bit that tells us to use the new accounting function |
1156 * (raid-z deflation). If we have an older pool, this will not | |
1157 * be present. | |
1158 */ | |
1159 error = zap_lookup(spa->spa_meta_objset, | |
1160 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE, | |
1161 sizeof (uint64_t), 1, &spa->spa_deflate); | |
1162 if (error != 0 && error != ENOENT) { | |
1163 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1164 VDEV_AUX_CORRUPT_DATA); | |
1165 error = EIO; | |
1166 goto out; | |
1167 } | |
1168 | |
1169 /* | |
1544 | 1170 * Load the persistent error log. If we have an older pool, this will |
1171 * not be present. | |
1172 */ | |
1173 error = zap_lookup(spa->spa_meta_objset, | |
1174 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_LAST, | |
1175 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
|
1176 if (error != 0 && error != ENOENT) { |
1544 | 1177 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1178 VDEV_AUX_CORRUPT_DATA); | |
1179 error = EIO; | |
1180 goto out; | |
1181 } | |
1182 | |
1183 error = zap_lookup(spa->spa_meta_objset, | |
1184 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_SCRUB, | |
1185 sizeof (uint64_t), 1, &spa->spa_errlog_scrub); | |
1186 if (error != 0 && error != ENOENT) { | |
1187 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1188 VDEV_AUX_CORRUPT_DATA); | |
1189 error = EIO; | |
1190 goto out; | |
1191 } | |
789 | 1192 |
1193 /* | |
2926 | 1194 * Load the history object. If we have an older pool, this |
1195 * will not be present. | |
1196 */ | |
1197 error = zap_lookup(spa->spa_meta_objset, | |
1198 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_HISTORY, | |
1199 sizeof (uint64_t), 1, &spa->spa_history); | |
1200 if (error != 0 && error != ENOENT) { | |
1201 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1202 VDEV_AUX_CORRUPT_DATA); | |
1203 error = EIO; | |
1204 goto out; | |
1205 } | |
1206 | |
1207 /* | |
2082 | 1208 * Load any hot spares for this pool. |
1209 */ | |
1210 error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, | |
5450 | 1211 DMU_POOL_SPARES, sizeof (uint64_t), 1, &spa->spa_spares.sav_object); |
2082 | 1212 if (error != 0 && error != ENOENT) { |
1213 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1214 VDEV_AUX_CORRUPT_DATA); | |
1215 error = EIO; | |
1216 goto out; | |
1217 } | |
1218 if (error == 0) { | |
4577 | 1219 ASSERT(spa_version(spa) >= SPA_VERSION_SPARES); |
5450 | 1220 if (load_nvlist(spa, spa->spa_spares.sav_object, |
1221 &spa->spa_spares.sav_config) != 0) { | |
2082 | 1222 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, |
1223 VDEV_AUX_CORRUPT_DATA); | |
1224 error = EIO; | |
1225 goto out; | |
1226 } | |
1227 | |
1228 spa_config_enter(spa, RW_WRITER, FTAG); | |
1229 spa_load_spares(spa); | |
1230 spa_config_exit(spa, FTAG); | |
1231 } | |
1232 | |
5450 | 1233 /* |
1234 * Load any level 2 ARC devices for this pool. | |
1235 */ | |
1236 error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, | |
1237 DMU_POOL_L2CACHE, sizeof (uint64_t), 1, | |
1238 &spa->spa_l2cache.sav_object); | |
1239 if (error != 0 && error != ENOENT) { | |
1240 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1241 VDEV_AUX_CORRUPT_DATA); | |
1242 error = EIO; | |
1243 goto out; | |
1244 } | |
1245 if (error == 0) { | |
1246 ASSERT(spa_version(spa) >= SPA_VERSION_L2CACHE); | |
1247 if (load_nvlist(spa, spa->spa_l2cache.sav_object, | |
1248 &spa->spa_l2cache.sav_config) != 0) { | |
1249 vdev_set_state(rvd, B_TRUE, | |
1250 VDEV_STATE_CANT_OPEN, | |
1251 VDEV_AUX_CORRUPT_DATA); | |
1252 error = EIO; | |
1253 goto out; | |
1254 } | |
1255 | |
1256 spa_config_enter(spa, RW_WRITER, FTAG); | |
1257 spa_load_l2cache(spa); | |
1258 spa_config_exit(spa, FTAG); | |
1259 } | |
1260 | |
5094 | 1261 spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION); |
4543 | 1262 |
3912 | 1263 error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT, |
1264 DMU_POOL_PROPS, sizeof (uint64_t), 1, &spa->spa_pool_props_object); | |
1265 | |
1266 if (error && error != ENOENT) { | |
1267 vdev_set_state(rvd, B_TRUE, VDEV_STATE_CANT_OPEN, | |
1268 VDEV_AUX_CORRUPT_DATA); | |
1269 error = EIO; | |
1270 goto out; | |
1271 } | |
1272 | |
1273 if (error == 0) { | |
1274 (void) zap_lookup(spa->spa_meta_objset, | |
1275 spa->spa_pool_props_object, | |
4451 | 1276 zpool_prop_to_name(ZPOOL_PROP_BOOTFS), |
3912 | 1277 sizeof (uint64_t), 1, &spa->spa_bootfs); |
4451 | 1278 (void) zap_lookup(spa->spa_meta_objset, |
1279 spa->spa_pool_props_object, | |
1280 zpool_prop_to_name(ZPOOL_PROP_AUTOREPLACE), | |
1281 sizeof (uint64_t), 1, &autoreplace); | |
4543 | 1282 (void) zap_lookup(spa->spa_meta_objset, |
1283 spa->spa_pool_props_object, | |
1284 zpool_prop_to_name(ZPOOL_PROP_DELEGATION), | |
1285 sizeof (uint64_t), 1, &spa->spa_delegation); | |
5329 | 1286 (void) zap_lookup(spa->spa_meta_objset, |
1287 spa->spa_pool_props_object, | |
1288 zpool_prop_to_name(ZPOOL_PROP_FAILUREMODE), | |
1289 sizeof (uint64_t), 1, &spa->spa_failmode); | |
3912 | 1290 } |
1291 | |
2082 | 1292 /* |
4451 | 1293 * If the 'autoreplace' property is set, then post a resource notifying |
1294 * the ZFS DE that it should not issue any faults for unopenable | |
1295 * devices. We also iterate over the vdevs, and post a sysevent for any | |
1296 * unopenable vdevs so that the normal autoreplace handler can take | |
1297 * over. | |
1298 */ | |
5756
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
1299 if (autoreplace && state != SPA_LOAD_TRYIMPORT) |
4451 | 1300 spa_check_removed(spa->spa_root_vdev); |
1301 | |
1302 /* | |
1986
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1303 * Load the vdev state for all toplevel vdevs. |
789 | 1304 */ |
1986
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1305 vdev_load(rvd); |
789 | 1306 |
1307 /* | |
1308 * Propagate the leaf DTLs we just loaded all the way up the tree. | |
1309 */ | |
1544 | 1310 spa_config_enter(spa, RW_WRITER, FTAG); |
789 | 1311 vdev_dtl_reassess(rvd, 0, 0, B_FALSE); |
1544 | 1312 spa_config_exit(spa, FTAG); |
789 | 1313 |
1314 /* | |
1315 * Check the state of the root vdev. If it can't be opened, it | |
1316 * indicates one or more toplevel vdevs are faulted. | |
1317 */ | |
1544 | 1318 if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) { |
1319 error = ENXIO; | |
1320 goto out; | |
1321 } | |
789 | 1322 |
1544 | 1323 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
|
1324 dmu_tx_t *tx; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1325 int need_update = B_FALSE; |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
1326 int c; |
1601
438b928f80c7
6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents:
1585
diff
changeset
|
1327 |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1328 /* |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1329 * 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
|
1330 * 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
|
1331 */ |
1601
438b928f80c7
6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents:
1585
diff
changeset
|
1332 tx = dmu_tx_create_assigned(spa_get_dsl(spa), |
789 | 1333 spa_first_txg(spa)); |
2417 | 1334 (void) dmu_objset_find(spa->spa_name, |
1335 zil_claim, tx, DS_FIND_CHILDREN); | |
789 | 1336 dmu_tx_commit(tx); |
1337 | |
1338 spa->spa_sync_on = B_TRUE; | |
1339 txg_sync_start(spa->spa_dsl_pool); | |
1340 | |
1341 /* | |
1342 * Wait for all claims to sync. | |
1343 */ | |
1344 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
|
1345 |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
1346 /* |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1347 * 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
|
1348 * 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
|
1349 */ |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1350 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
|
1351 state == SPA_LOAD_IMPORT) |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1352 need_update = B_TRUE; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1353 |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1354 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
|
1355 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
|
1356 need_update = B_TRUE; |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
1357 |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
1358 /* |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1359 * 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
|
1360 * 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
|
1361 */ |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1362 if (need_update) |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1363 spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE); |
789 | 1364 } |
1365 | |
1544 | 1366 error = 0; |
1367 out: | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
1368 spa->spa_minref = refcount_count(&spa->spa_refcount); |
2082 | 1369 if (error && error != EBADF) |
1544 | 1370 zfs_ereport_post(FM_EREPORT_ZFS_POOL, spa, NULL, NULL, 0, 0); |
1371 spa->spa_load_state = SPA_LOAD_NONE; | |
1372 spa->spa_ena = 0; | |
1373 | |
1374 return (error); | |
789 | 1375 } |
1376 | |
1377 /* | |
1378 * Pool Open/Import | |
1379 * | |
1380 * The import case is identical to an open except that the configuration is sent | |
1381 * down from userland, instead of grabbed from the configuration cache. For the | |
1382 * case of an open, the pool configuration will exist in the | |
4451 | 1383 * POOL_STATE_UNINITIALIZED state. |
789 | 1384 * |
1385 * The stats information (gen/count/ustats) is used to gather vdev statistics at | |
1386 * the same time open the pool, without having to keep around the spa_t in some | |
1387 * ambiguous state. | |
1388 */ | |
1389 static int | |
1390 spa_open_common(const char *pool, spa_t **spapp, void *tag, nvlist_t **config) | |
1391 { | |
1392 spa_t *spa; | |
1393 int error; | |
1394 int locked = B_FALSE; | |
1395 | |
1396 *spapp = NULL; | |
1397 | |
1398 /* | |
1399 * As disgusting as this is, we need to support recursive calls to this | |
1400 * function because dsl_dir_open() is called during spa_load(), and ends | |
1401 * up calling spa_open() again. The real fix is to figure out how to | |
1402 * avoid dsl_dir_open() calling this in the first place. | |
1403 */ | |
1404 if (mutex_owner(&spa_namespace_lock) != curthread) { | |
1405 mutex_enter(&spa_namespace_lock); | |
1406 locked = B_TRUE; | |
1407 } | |
1408 | |
1409 if ((spa = spa_lookup(pool)) == NULL) { | |
1410 if (locked) | |
1411 mutex_exit(&spa_namespace_lock); | |
1412 return (ENOENT); | |
1413 } | |
1414 if (spa->spa_state == POOL_STATE_UNINITIALIZED) { | |
1415 | |
1416 spa_activate(spa); | |
1417 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1418 error = spa_load(spa, spa->spa_config, SPA_LOAD_OPEN, B_FALSE); |
789 | 1419 |
1420 if (error == EBADF) { | |
1421 /* | |
1986
628267397204
6424405 zpool import destroyed_pool can damage existing pool using same devices
eschrock
parents:
1807
diff
changeset
|
1422 * 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
|
1423 * 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
|
1424 * 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
|
1425 * 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
|
1426 * we should remove the pool from the namespace. |
789 | 1427 */ |
1428 spa_unload(spa); | |
1429 spa_deactivate(spa); | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
1430 spa_config_sync(spa, B_TRUE, B_TRUE); |
789 | 1431 spa_remove(spa); |
1432 if (locked) | |
1433 mutex_exit(&spa_namespace_lock); | |
1434 return (ENOENT); | |
1544 | 1435 } |
1436 | |
1437 if (error) { | |
789 | 1438 /* |
1439 * We can't open the pool, but we still have useful | |
1440 * information: the state of each vdev after the | |
1441 * attempted vdev_open(). Return this to the user. | |
1442 */ | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1443 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
|
1444 spa_config_enter(spa, RW_READER, FTAG); |
789 | 1445 *config = spa_config_generate(spa, NULL, -1ULL, |
1446 B_TRUE); | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1447 spa_config_exit(spa, FTAG); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1448 } |
789 | 1449 spa_unload(spa); |
1450 spa_deactivate(spa); | |
1544 | 1451 spa->spa_last_open_failed = B_TRUE; |
789 | 1452 if (locked) |
1453 mutex_exit(&spa_namespace_lock); | |
1454 *spapp = NULL; | |
1455 return (error); | |
1544 | 1456 } else { |
1457 spa->spa_last_open_failed = B_FALSE; | |
789 | 1458 } |
1459 } | |
1460 | |
1461 spa_open_ref(spa, tag); | |
4451 | 1462 |
789 | 1463 if (locked) |
1464 mutex_exit(&spa_namespace_lock); | |
1465 | |
1466 *spapp = spa; | |
1467 | |
1468 if (config != NULL) { | |
1544 | 1469 spa_config_enter(spa, RW_READER, FTAG); |
789 | 1470 *config = spa_config_generate(spa, NULL, -1ULL, B_TRUE); |
1544 | 1471 spa_config_exit(spa, FTAG); |
789 | 1472 } |
1473 | |
1474 return (0); | |
1475 } | |
1476 | |
1477 int | |
1478 spa_open(const char *name, spa_t **spapp, void *tag) | |
1479 { | |
1480 return (spa_open_common(name, spapp, tag, NULL)); | |
1481 } | |
1482 | |
1544 | 1483 /* |
1484 * Lookup the given spa_t, incrementing the inject count in the process, | |
1485 * preventing it from being exported or destroyed. | |
1486 */ | |
1487 spa_t * | |
1488 spa_inject_addref(char *name) | |
1489 { | |
1490 spa_t *spa; | |
1491 | |
1492 mutex_enter(&spa_namespace_lock); | |
1493 if ((spa = spa_lookup(name)) == NULL) { | |
1494 mutex_exit(&spa_namespace_lock); | |
1495 return (NULL); | |
1496 } | |
1497 spa->spa_inject_ref++; | |
1498 mutex_exit(&spa_namespace_lock); | |
1499 | |
1500 return (spa); | |
1501 } | |
1502 | |
1503 void | |
1504 spa_inject_delref(spa_t *spa) | |
1505 { | |
1506 mutex_enter(&spa_namespace_lock); | |
1507 spa->spa_inject_ref--; | |
1508 mutex_exit(&spa_namespace_lock); | |
1509 } | |
1510 | |
5450 | 1511 /* |
1512 * Add spares device information to the nvlist. | |
1513 */ | |
2082 | 1514 static void |
1515 spa_add_spares(spa_t *spa, nvlist_t *config) | |
1516 { | |
1517 nvlist_t **spares; | |
1518 uint_t i, nspares; | |
1519 nvlist_t *nvroot; | |
1520 uint64_t guid; | |
1521 vdev_stat_t *vs; | |
1522 uint_t vsc; | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1523 uint64_t pool; |
2082 | 1524 |
5450 | 1525 if (spa->spa_spares.sav_count == 0) |
2082 | 1526 return; |
1527 | |
1528 VERIFY(nvlist_lookup_nvlist(config, | |
1529 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); | |
5450 | 1530 VERIFY(nvlist_lookup_nvlist_array(spa->spa_spares.sav_config, |
2082 | 1531 ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0); |
1532 if (nspares != 0) { | |
1533 VERIFY(nvlist_add_nvlist_array(nvroot, | |
1534 ZPOOL_CONFIG_SPARES, spares, nspares) == 0); | |
1535 VERIFY(nvlist_lookup_nvlist_array(nvroot, | |
1536 ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0); | |
1537 | |
1538 /* | |
1539 * Go through and find any spares which have since been | |
1540 * repurposed as an active spare. If this is the case, update | |
1541 * their status appropriately. | |
1542 */ | |
1543 for (i = 0; i < nspares; i++) { | |
1544 VERIFY(nvlist_lookup_uint64(spares[i], | |
1545 ZPOOL_CONFIG_GUID, &guid) == 0); | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1546 if (spa_spare_exists(guid, &pool) && pool != 0ULL) { |
2082 | 1547 VERIFY(nvlist_lookup_uint64_array( |
1548 spares[i], ZPOOL_CONFIG_STATS, | |
1549 (uint64_t **)&vs, &vsc) == 0); | |
1550 vs->vs_state = VDEV_STATE_CANT_OPEN; | |
1551 vs->vs_aux = VDEV_AUX_SPARED; | |
1552 } | |
1553 } | |
1554 } | |
1555 } | |
1556 | |
5450 | 1557 /* |
1558 * Add l2cache device information to the nvlist, including vdev stats. | |
1559 */ | |
1560 static void | |
1561 spa_add_l2cache(spa_t *spa, nvlist_t *config) | |
1562 { | |
1563 nvlist_t **l2cache; | |
1564 uint_t i, j, nl2cache; | |
1565 nvlist_t *nvroot; | |
1566 uint64_t guid; | |
1567 vdev_t *vd; | |
1568 vdev_stat_t *vs; | |
1569 uint_t vsc; | |
1570 | |
1571 if (spa->spa_l2cache.sav_count == 0) | |
1572 return; | |
1573 | |
1574 spa_config_enter(spa, RW_READER, FTAG); | |
1575 | |
1576 VERIFY(nvlist_lookup_nvlist(config, | |
1577 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0); | |
1578 VERIFY(nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config, | |
1579 ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0); | |
1580 if (nl2cache != 0) { | |
1581 VERIFY(nvlist_add_nvlist_array(nvroot, | |
1582 ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0); | |
1583 VERIFY(nvlist_lookup_nvlist_array(nvroot, | |
1584 ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0); | |
1585 | |
1586 /* | |
1587 * Update level 2 cache device stats. | |
1588 */ | |
1589 | |
1590 for (i = 0; i < nl2cache; i++) { | |
1591 VERIFY(nvlist_lookup_uint64(l2cache[i], | |
1592 ZPOOL_CONFIG_GUID, &guid) == 0); | |
1593 | |
1594 vd = NULL; | |
1595 for (j = 0; j < spa->spa_l2cache.sav_count; j++) { | |
1596 if (guid == | |
1597 spa->spa_l2cache.sav_vdevs[j]->vdev_guid) { | |
1598 vd = spa->spa_l2cache.sav_vdevs[j]; | |
1599 break; | |
1600 } | |
1601 } | |
1602 ASSERT(vd != NULL); | |
1603 | |
1604 VERIFY(nvlist_lookup_uint64_array(l2cache[i], | |
1605 ZPOOL_CONFIG_STATS, (uint64_t **)&vs, &vsc) == 0); | |
1606 vdev_get_stats(vd, vs); | |
1607 } | |
1608 } | |
1609 | |
1610 spa_config_exit(spa, FTAG); | |
1611 } | |
1612 | |
789 | 1613 int |
1544 | 1614 spa_get_stats(const char *name, nvlist_t **config, char *altroot, size_t buflen) |
789 | 1615 { |
1616 int error; | |
1617 spa_t *spa; | |
1618 | |
1619 *config = NULL; | |
1620 error = spa_open_common(name, &spa, FTAG, config); | |
1621 | |
2082 | 1622 if (spa && *config != NULL) { |
1544 | 1623 VERIFY(nvlist_add_uint64(*config, ZPOOL_CONFIG_ERRCOUNT, |
1624 spa_get_errlog_size(spa)) == 0); | |
1625 | |
2082 | 1626 spa_add_spares(spa, *config); |
5450 | 1627 spa_add_l2cache(spa, *config); |
2082 | 1628 } |
1629 | |
1544 | 1630 /* |
1631 * We want to get the alternate root even for faulted pools, so we cheat | |
1632 * and call spa_lookup() directly. | |
1633 */ | |
1634 if (altroot) { | |
1635 if (spa == NULL) { | |
1636 mutex_enter(&spa_namespace_lock); | |
1637 spa = spa_lookup(name); | |
1638 if (spa) | |
1639 spa_altroot(spa, altroot, buflen); | |
1640 else | |
1641 altroot[0] = '\0'; | |
1642 spa = NULL; | |
1643 mutex_exit(&spa_namespace_lock); | |
1644 } else { | |
1645 spa_altroot(spa, altroot, buflen); | |
1646 } | |
1647 } | |
1648 | |
789 | 1649 if (spa != NULL) |
1650 spa_close(spa, FTAG); | |
1651 | |
1652 return (error); | |
1653 } | |
1654 | |
1655 /* | |
5450 | 1656 * Validate that the auxiliary device array is well formed. We must have an |
1657 * array of nvlists, each which describes a valid leaf vdev. If this is an | |
1658 * import (mode is VDEV_ALLOC_SPARE), then we allow corrupted spares to be | |
1659 * specified, as long as they are well-formed. | |
2082 | 1660 */ |
1661 static int | |
5450 | 1662 spa_validate_aux_devs(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode, |
1663 spa_aux_vdev_t *sav, const char *config, uint64_t version, | |
1664 vdev_labeltype_t label) | |
2082 | 1665 { |
5450 | 1666 nvlist_t **dev; |
1667 uint_t i, ndev; | |
2082 | 1668 vdev_t *vd; |
1669 int error; | |
1670 | |
1671 /* | |
5450 | 1672 * It's acceptable to have no devs specified. |
2082 | 1673 */ |
5450 | 1674 if (nvlist_lookup_nvlist_array(nvroot, config, &dev, &ndev) != 0) |
2082 | 1675 return (0); |
1676 | |
5450 | 1677 if (ndev == 0) |
2082 | 1678 return (EINVAL); |
1679 | |
1680 /* | |
5450 | 1681 * Make sure the pool is formatted with a version that supports this |
1682 * device type. | |
2082 | 1683 */ |
5450 | 1684 if (spa_version(spa) < version) |
2082 | 1685 return (ENOTSUP); |
1686 | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1687 /* |
5450 | 1688 * Set the pending device list so we correctly handle device in-use |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1689 * checking. |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1690 */ |
5450 | 1691 sav->sav_pending = dev; |
1692 sav->sav_npending = ndev; | |
1693 | |
1694 for (i = 0; i < ndev; i++) { | |
1695 if ((error = spa_config_parse(spa, &vd, dev[i], NULL, 0, | |
2082 | 1696 mode)) != 0) |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1697 goto out; |
2082 | 1698 |
1699 if (!vd->vdev_ops->vdev_op_leaf) { | |
1700 vdev_free(vd); | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1701 error = EINVAL; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1702 goto out; |
2082 | 1703 } |
1704 | |
5450 | 1705 /* |
1706 * The L2ARC currently only supports disk devices. | |
1707 */ | |
1708 if ((strcmp(config, ZPOOL_CONFIG_L2CACHE) == 0) && | |
1709 strcmp(vd->vdev_ops->vdev_op_type, VDEV_TYPE_DISK) != 0) { | |
1710 error = ENOTBLK; | |
1711 goto out; | |
1712 } | |
1713 | |
2082 | 1714 vd->vdev_top = vd; |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1715 |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1716 if ((error = vdev_open(vd)) == 0 && |
5450 | 1717 (error = vdev_label_init(vd, crtxg, label)) == 0) { |
1718 VERIFY(nvlist_add_uint64(dev[i], ZPOOL_CONFIG_GUID, | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1719 vd->vdev_guid) == 0); |
2082 | 1720 } |
1721 | |
1722 vdev_free(vd); | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1723 |
5450 | 1724 if (error && |
1725 (mode != VDEV_ALLOC_SPARE && mode != VDEV_ALLOC_L2CACHE)) | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1726 goto out; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1727 else |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1728 error = 0; |
2082 | 1729 } |
1730 | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1731 out: |
5450 | 1732 sav->sav_pending = NULL; |
1733 sav->sav_npending = 0; | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
1734 return (error); |
2082 | 1735 } |
1736 | |
5450 | 1737 static int |
1738 spa_validate_aux(spa_t *spa, nvlist_t *nvroot, uint64_t crtxg, int mode) | |
1739 { | |
1740 int error; | |
1741 | |
1742 if ((error = spa_validate_aux_devs(spa, nvroot, crtxg, mode, | |
1743 &spa->spa_spares, ZPOOL_CONFIG_SPARES, SPA_VERSION_SPARES, | |
1744 VDEV_LABEL_SPARE)) != 0) { | |
1745 return (error); | |
1746 } | |
1747 | |
1748 return (spa_validate_aux_devs(spa, nvroot, crtxg, mode, | |
1749 &spa->spa_l2cache, ZPOOL_CONFIG_L2CACHE, SPA_VERSION_L2CACHE, | |
1750 VDEV_LABEL_L2CACHE)); | |
1751 } | |
1752 | |
1753 static void | |
1754 spa_set_aux_vdevs(spa_aux_vdev_t *sav, nvlist_t **devs, int ndevs, | |
1755 const char *config) | |
1756 { | |
1757 int i; | |
1758 | |
1759 if (sav->sav_config != NULL) { | |
1760 nvlist_t **olddevs; | |
1761 uint_t oldndevs; | |
1762 nvlist_t **newdevs; | |
1763 | |
1764 /* | |
1765 * Generate new dev list by concatentating with the | |
1766 * current dev list. | |
1767 */ | |
1768 VERIFY(nvlist_lookup_nvlist_array(sav->sav_config, config, | |
1769 &olddevs, &oldndevs) == 0); | |
1770 | |
1771 newdevs = kmem_alloc(sizeof (void *) * | |
1772 (ndevs + oldndevs), KM_SLEEP); | |
1773 for (i = 0; i < oldndevs; i++) | |
1774 VERIFY(nvlist_dup(olddevs[i], &newdevs[i], | |
1775 KM_SLEEP) == 0); | |
1776 for (i = 0; i < ndevs; i++) | |
1777 VERIFY(nvlist_dup(devs[i], &newdevs[i + oldndevs], | |
1778 KM_SLEEP) == 0); | |
1779 | |
1780 VERIFY(nvlist_remove(sav->sav_config, config, | |
1781 DATA_TYPE_NVLIST_ARRAY) == 0); | |
1782 | |
1783 VERIFY(nvlist_add_nvlist_array(sav->sav_config, | |
1784 config, newdevs, ndevs + oldndevs) == 0); | |
1785 for (i = 0; i < oldndevs + ndevs; i++) | |
1786 nvlist_free(newdevs[i]); | |
1787 kmem_free(newdevs, (oldndevs + ndevs) * sizeof (void *)); | |
1788 } else { | |
1789 /* | |
1790 * Generate a new dev list. | |
1791 */ | |
1792 VERIFY(nvlist_alloc(&sav->sav_config, NV_UNIQUE_NAME, | |
1793 KM_SLEEP) == 0); | |
1794 VERIFY(nvlist_add_nvlist_array(sav->sav_config, config, | |
1795 devs, ndevs) == 0); | |
1796 } | |
1797 } | |
1798 | |
1799 /* | |
1800 * Stop and drop level 2 ARC devices | |
1801 */ | |
1802 void | |
1803 spa_l2cache_drop(spa_t *spa) | |
1804 { | |
1805 vdev_t *vd; | |
1806 int i; | |
1807 spa_aux_vdev_t *sav = &spa->spa_l2cache; | |
1808 | |
1809 for (i = 0; i < sav->sav_count; i++) { | |
1810 uint64_t pool; | |
1811 | |
1812 vd = sav->sav_vdevs[i]; | |
1813 ASSERT(vd != NULL); | |
1814 | |
1815 if (spa_mode & FWRITE && | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
1816 spa_l2cache_exists(vd->vdev_guid, &pool) && pool != 0ULL && |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
1817 l2arc_vdev_present(vd)) { |
5450 | 1818 l2arc_remove_vdev(vd); |
1819 } | |
1820 if (vd->vdev_isl2cache) | |
1821 spa_l2cache_remove(vd); | |
1822 vdev_clear_stats(vd); | |
1823 (void) vdev_close(vd); | |
1824 } | |
1825 } | |
1826 | |
2082 | 1827 /* |
789 | 1828 * Pool Creation |
1829 */ | |
1830 int | |
5094 | 1831 spa_create(const char *pool, nvlist_t *nvroot, nvlist_t *props, |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4627
diff
changeset
|
1832 const char *history_str) |
789 | 1833 { |
1834 spa_t *spa; | |
5094 | 1835 char *altroot = NULL; |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1836 vdev_t *rvd; |
789 | 1837 dsl_pool_t *dp; |
1838 dmu_tx_t *tx; | |
2082 | 1839 int c, error = 0; |
789 | 1840 uint64_t txg = TXG_INITIAL; |
5450 | 1841 nvlist_t **spares, **l2cache; |
1842 uint_t nspares, nl2cache; | |
5094 | 1843 uint64_t version; |
789 | 1844 |
1845 /* | |
1846 * If this pool already exists, return failure. | |
1847 */ | |
1848 mutex_enter(&spa_namespace_lock); | |
1849 if (spa_lookup(pool) != NULL) { | |
1850 mutex_exit(&spa_namespace_lock); | |
1851 return (EEXIST); | |
1852 } | |
1853 | |
1854 /* | |
1855 * Allocate a new spa_t structure. | |
1856 */ | |
5094 | 1857 (void) nvlist_lookup_string(props, |
1858 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot); | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1859 spa = spa_add(pool, altroot); |
789 | 1860 spa_activate(spa); |
1861 | |
1862 spa->spa_uberblock.ub_txg = txg - 1; | |
5094 | 1863 |
1864 if (props && (error = spa_prop_validate(spa, props))) { | |
1865 spa_unload(spa); | |
1866 spa_deactivate(spa); | |
1867 spa_remove(spa); | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
1868 mutex_exit(&spa_namespace_lock); |
5094 | 1869 return (error); |
1870 } | |
1871 | |
1872 if (nvlist_lookup_uint64(props, zpool_prop_to_name(ZPOOL_PROP_VERSION), | |
1873 &version) != 0) | |
1874 version = SPA_VERSION; | |
1875 ASSERT(version <= SPA_VERSION); | |
1876 spa->spa_uberblock.ub_version = version; | |
789 | 1877 spa->spa_ubsync = spa->spa_uberblock; |
1878 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1879 /* |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1880 * Create the root vdev. |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1881 */ |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1882 spa_config_enter(spa, RW_WRITER, FTAG); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1883 |
2082 | 1884 error = spa_config_parse(spa, &rvd, nvroot, NULL, 0, VDEV_ALLOC_ADD); |
1885 | |
1886 ASSERT(error != 0 || rvd != NULL); | |
1887 ASSERT(error != 0 || spa->spa_root_vdev == rvd); | |
1888 | |
5913
a77f8ad2ce63
6575965 panic/thread=2a1016b5ca0: BAD TRAP: type=9 rp=1858500 addr=0 mmu_fsr=0, really, truly out of space
perrin
parents:
5886
diff
changeset
|
1889 if (error == 0 && !zfs_allocatable_devs(nvroot)) |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1890 error = EINVAL; |
2082 | 1891 |
1892 if (error == 0 && | |
1893 (error = vdev_create(rvd, txg, B_FALSE)) == 0 && | |
5450 | 1894 (error = spa_validate_aux(spa, nvroot, txg, |
2082 | 1895 VDEV_ALLOC_ADD)) == 0) { |
1896 for (c = 0; c < rvd->vdev_children; c++) | |
1897 vdev_init(rvd->vdev_child[c], txg); | |
1898 vdev_config_dirty(rvd); | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1899 } |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1900 |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
1901 spa_config_exit(spa, FTAG); |
789 | 1902 |
2082 | 1903 if (error != 0) { |
789 | 1904 spa_unload(spa); |
1905 spa_deactivate(spa); | |
1906 spa_remove(spa); | |
1907 mutex_exit(&spa_namespace_lock); | |
1908 return (error); | |
1909 } | |
1910 | |
2082 | 1911 /* |
1912 * Get the list of spares, if specified. | |
1913 */ | |
1914 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, | |
1915 &spares, &nspares) == 0) { | |
5450 | 1916 VERIFY(nvlist_alloc(&spa->spa_spares.sav_config, NV_UNIQUE_NAME, |
2082 | 1917 KM_SLEEP) == 0); |
5450 | 1918 VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config, |
2082 | 1919 ZPOOL_CONFIG_SPARES, spares, nspares) == 0); |
1920 spa_config_enter(spa, RW_WRITER, FTAG); | |
1921 spa_load_spares(spa); | |
1922 spa_config_exit(spa, FTAG); | |
5450 | 1923 spa->spa_spares.sav_sync = B_TRUE; |
1924 } | |
1925 | |
1926 /* | |
1927 * Get the list of level 2 cache devices, if specified. | |
1928 */ | |
1929 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, | |
1930 &l2cache, &nl2cache) == 0) { | |
1931 VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config, | |
1932 NV_UNIQUE_NAME, KM_SLEEP) == 0); | |
1933 VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config, | |
1934 ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0); | |
1935 spa_config_enter(spa, RW_WRITER, FTAG); | |
1936 spa_load_l2cache(spa); | |
1937 spa_config_exit(spa, FTAG); | |
1938 spa->spa_l2cache.sav_sync = B_TRUE; | |
2082 | 1939 } |
1940 | |
789 | 1941 spa->spa_dsl_pool = dp = dsl_pool_create(spa, txg); |
1942 spa->spa_meta_objset = dp->dp_meta_objset; | |
1943 | |
1944 tx = dmu_tx_create_assigned(dp, txg); | |
1945 | |
1946 /* | |
1947 * Create the pool config object. | |
1948 */ | |
1949 spa->spa_config_object = dmu_object_alloc(spa->spa_meta_objset, | |
1950 DMU_OT_PACKED_NVLIST, 1 << 14, | |
1951 DMU_OT_PACKED_NVLIST_SIZE, sizeof (uint64_t), tx); | |
1952 | |
1544 | 1953 if (zap_add(spa->spa_meta_objset, |
789 | 1954 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG, |
1544 | 1955 sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) { |
1956 cmn_err(CE_PANIC, "failed to add pool config"); | |
1957 } | |
789 | 1958 |
5094 | 1959 /* Newly created pools with the right version are always deflated. */ |
1960 if (version >= SPA_VERSION_RAIDZ_DEFLATE) { | |
1961 spa->spa_deflate = TRUE; | |
1962 if (zap_add(spa->spa_meta_objset, | |
1963 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE, | |
1964 sizeof (uint64_t), 1, &spa->spa_deflate, tx) != 0) { | |
1965 cmn_err(CE_PANIC, "failed to add deflate"); | |
1966 } | |
2082 | 1967 } |
1968 | |
789 | 1969 /* |
1970 * Create the deferred-free bplist object. Turn off compression | |
1971 * because sync-to-convergence takes longer if the blocksize | |
1972 * keeps changing. | |
1973 */ | |
1974 spa->spa_sync_bplist_obj = bplist_create(spa->spa_meta_objset, | |
1975 1 << 14, tx); | |
1976 dmu_object_set_compress(spa->spa_meta_objset, spa->spa_sync_bplist_obj, | |
1977 ZIO_COMPRESS_OFF, tx); | |
1978 | |
1544 | 1979 if (zap_add(spa->spa_meta_objset, |
789 | 1980 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_SYNC_BPLIST, |
1544 | 1981 sizeof (uint64_t), 1, &spa->spa_sync_bplist_obj, tx) != 0) { |
1982 cmn_err(CE_PANIC, "failed to add bplist"); | |
1983 } | |
789 | 1984 |
2926 | 1985 /* |
1986 * Create the pool's history object. | |
1987 */ | |
5094 | 1988 if (version >= SPA_VERSION_ZPOOL_HISTORY) |
1989 spa_history_create_obj(spa, tx); | |
1990 | |
1991 /* | |
1992 * Set pool properties. | |
1993 */ | |
1994 spa->spa_bootfs = zpool_prop_default_numeric(ZPOOL_PROP_BOOTFS); | |
1995 spa->spa_delegation = zpool_prop_default_numeric(ZPOOL_PROP_DELEGATION); | |
5329 | 1996 spa->spa_failmode = zpool_prop_default_numeric(ZPOOL_PROP_FAILUREMODE); |
5094 | 1997 if (props) |
1998 spa_sync_props(spa, props, CRED(), tx); | |
2926 | 1999 |
789 | 2000 dmu_tx_commit(tx); |
2001 | |
2002 spa->spa_sync_on = B_TRUE; | |
2003 txg_sync_start(spa->spa_dsl_pool); | |
2004 | |
2005 /* | |
2006 * We explicitly wait for the first transaction to complete so that our | |
2007 * bean counters are appropriately updated. | |
2008 */ | |
2009 txg_wait_synced(spa->spa_dsl_pool, txg); | |
2010 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2011 spa_config_sync(spa, B_FALSE, B_TRUE); |
789 | 2012 |
5094 | 2013 if (version >= SPA_VERSION_ZPOOL_HISTORY && history_str != NULL) |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4627
diff
changeset
|
2014 (void) spa_history_log(spa, history_str, LOG_CMD_POOL_CREATE); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4627
diff
changeset
|
2015 |
789 | 2016 mutex_exit(&spa_namespace_lock); |
2017 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2018 spa->spa_minref = refcount_count(&spa->spa_refcount); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2019 |
789 | 2020 return (0); |
2021 } | |
2022 | |
2023 /* | |
2024 * Import the given pool into the system. We set up the necessary spa_t and | |
2025 * then call spa_load() to do the dirty work. | |
2026 */ | |
6423 | 2027 static int |
2028 spa_import_common(const char *pool, nvlist_t *config, nvlist_t *props, | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2029 boolean_t isroot, boolean_t allowfaulted) |
789 | 2030 { |
2031 spa_t *spa; | |
5094 | 2032 char *altroot = NULL; |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2033 int error, loaderr; |
2082 | 2034 nvlist_t *nvroot; |
5450 | 2035 nvlist_t **spares, **l2cache; |
2036 uint_t nspares, nl2cache; | |
789 | 2037 |
2038 /* | |
2039 * If a pool with this name exists, return failure. | |
2040 */ | |
2041 mutex_enter(&spa_namespace_lock); | |
2042 if (spa_lookup(pool) != NULL) { | |
2043 mutex_exit(&spa_namespace_lock); | |
2044 return (EEXIST); | |
2045 } | |
2046 | |
2047 /* | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2048 * Create and initialize the spa structure. |
789 | 2049 */ |
5094 | 2050 (void) nvlist_lookup_string(props, |
2051 zpool_prop_to_name(ZPOOL_PROP_ALTROOT), &altroot); | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2052 spa = spa_add(pool, altroot); |
789 | 2053 spa_activate(spa); |
2054 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2055 if (allowfaulted) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2056 spa->spa_import_faulted = B_TRUE; |
6673
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2057 spa->spa_is_root = isroot; |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2058 |
789 | 2059 /* |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2060 * Pass off the heavy lifting to spa_load(). |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2061 * Pass TRUE for mosconfig (unless this is a root pool) because |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2062 * the user-supplied config is actually the one to trust when |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2063 * doing an import. |
1601
438b928f80c7
6397197 ADVANCE_ZIL should only visit claimed-but-not-yet-replayed logs
bonwick
parents:
1585
diff
changeset
|
2064 */ |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2065 loaderr = error = spa_load(spa, config, SPA_LOAD_IMPORT, !isroot); |
789 | 2066 |
2082 | 2067 spa_config_enter(spa, RW_WRITER, FTAG); |
2068 /* | |
2069 * Toss any existing sparelist, as it doesn't have any validity anymore, | |
2070 * and conflicts with spa_has_spare(). | |
2071 */ | |
6423 | 2072 if (!isroot && spa->spa_spares.sav_config) { |
5450 | 2073 nvlist_free(spa->spa_spares.sav_config); |
2074 spa->spa_spares.sav_config = NULL; | |
2082 | 2075 spa_load_spares(spa); |
2076 } | |
6423 | 2077 if (!isroot && spa->spa_l2cache.sav_config) { |
5450 | 2078 nvlist_free(spa->spa_l2cache.sav_config); |
2079 spa->spa_l2cache.sav_config = NULL; | |
2080 spa_load_l2cache(spa); | |
2081 } | |
2082 | 2082 |
2083 VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, | |
2084 &nvroot) == 0); | |
5450 | 2085 if (error == 0) |
2086 error = spa_validate_aux(spa, nvroot, -1ULL, VDEV_ALLOC_SPARE); | |
2087 if (error == 0) | |
2088 error = spa_validate_aux(spa, nvroot, -1ULL, | |
2089 VDEV_ALLOC_L2CACHE); | |
2082 | 2090 spa_config_exit(spa, FTAG); |
2091 | |
5094 | 2092 if (error != 0 || (props && (error = spa_prop_set(spa, props)))) { |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2093 if (loaderr != 0 && loaderr != EINVAL && allowfaulted) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2094 /* |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2095 * If we failed to load the pool, but 'allowfaulted' is |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2096 * set, then manually set the config as if the config |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2097 * passed in was specified in the cache file. |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2098 */ |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2099 error = 0; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2100 spa->spa_import_faulted = B_FALSE; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2101 if (spa->spa_config == NULL) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2102 spa_config_enter(spa, RW_READER, FTAG); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2103 spa->spa_config = spa_config_generate(spa, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2104 NULL, -1ULL, B_TRUE); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2105 spa_config_exit(spa, FTAG); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2106 } |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2107 spa_unload(spa); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2108 spa_deactivate(spa); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2109 spa_config_sync(spa, B_FALSE, B_TRUE); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2110 } else { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2111 spa_unload(spa); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2112 spa_deactivate(spa); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2113 spa_remove(spa); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2114 } |
789 | 2115 mutex_exit(&spa_namespace_lock); |
2116 return (error); | |
2117 } | |
2118 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2119 /* |
5450 | 2120 * Override any spares and level 2 cache devices as specified by |
2121 * the user, as these may have correct device names/devids, etc. | |
2082 | 2122 */ |
2123 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, | |
2124 &spares, &nspares) == 0) { | |
5450 | 2125 if (spa->spa_spares.sav_config) |
2126 VERIFY(nvlist_remove(spa->spa_spares.sav_config, | |
2082 | 2127 ZPOOL_CONFIG_SPARES, DATA_TYPE_NVLIST_ARRAY) == 0); |
2128 else | |
5450 | 2129 VERIFY(nvlist_alloc(&spa->spa_spares.sav_config, |
2082 | 2130 NV_UNIQUE_NAME, KM_SLEEP) == 0); |
5450 | 2131 VERIFY(nvlist_add_nvlist_array(spa->spa_spares.sav_config, |
2082 | 2132 ZPOOL_CONFIG_SPARES, spares, nspares) == 0); |
2133 spa_config_enter(spa, RW_WRITER, FTAG); | |
2134 spa_load_spares(spa); | |
2135 spa_config_exit(spa, FTAG); | |
5450 | 2136 spa->spa_spares.sav_sync = B_TRUE; |
2137 } | |
2138 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, | |
2139 &l2cache, &nl2cache) == 0) { | |
2140 if (spa->spa_l2cache.sav_config) | |
2141 VERIFY(nvlist_remove(spa->spa_l2cache.sav_config, | |
2142 ZPOOL_CONFIG_L2CACHE, DATA_TYPE_NVLIST_ARRAY) == 0); | |
2143 else | |
2144 VERIFY(nvlist_alloc(&spa->spa_l2cache.sav_config, | |
2145 NV_UNIQUE_NAME, KM_SLEEP) == 0); | |
2146 VERIFY(nvlist_add_nvlist_array(spa->spa_l2cache.sav_config, | |
2147 ZPOOL_CONFIG_L2CACHE, l2cache, nl2cache) == 0); | |
2148 spa_config_enter(spa, RW_WRITER, FTAG); | |
2149 spa_load_l2cache(spa); | |
2150 spa_config_exit(spa, FTAG); | |
2151 spa->spa_l2cache.sav_sync = B_TRUE; | |
2082 | 2152 } |
2153 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2154 if (spa_mode & FWRITE) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2155 /* |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2156 * Update the config cache to include the newly-imported pool. |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2157 */ |
6423 | 2158 spa_config_update_common(spa, SPA_CONFIG_UPDATE_POOL, isroot); |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2159 } |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2160 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2161 spa->spa_import_faulted = B_FALSE; |
4451 | 2162 mutex_exit(&spa_namespace_lock); |
2163 | |
789 | 2164 return (0); |
2165 } | |
2166 | |
6423 | 2167 #ifdef _KERNEL |
2168 /* | |
2169 * Build a "root" vdev for a top level vdev read in from a rootpool | |
2170 * device label. | |
2171 */ | |
2172 static void | |
2173 spa_build_rootpool_config(nvlist_t *config) | |
2174 { | |
2175 nvlist_t *nvtop, *nvroot; | |
2176 uint64_t pgid; | |
2177 | |
2178 /* | |
2179 * Add this top-level vdev to the child array. | |
2180 */ | |
2181 VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvtop) | |
2182 == 0); | |
2183 VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pgid) | |
2184 == 0); | |
2185 | |
2186 /* | |
2187 * Put this pool's top-level vdevs into a root vdev. | |
2188 */ | |
2189 VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0); | |
2190 VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, VDEV_TYPE_ROOT) | |
2191 == 0); | |
2192 VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0); | |
2193 VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0); | |
2194 VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, | |
2195 &nvtop, 1) == 0); | |
2196 | |
2197 /* | |
2198 * Replace the existing vdev_tree with the new root vdev in | |
2199 * this pool's configuration (remove the old, add the new). | |
2200 */ | |
2201 VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); | |
2202 nvlist_free(nvroot); | |
2203 } | |
2204 | |
2205 /* | |
2206 * Get the root pool information from the root disk, then import the root pool | |
2207 * during the system boot up time. | |
2208 */ | |
2209 extern nvlist_t *vdev_disk_read_rootlabel(char *); | |
2210 | |
2211 void | |
2212 spa_check_rootconf(char *devpath, char **bestdev, nvlist_t **bestconf, | |
2213 uint64_t *besttxg) | |
2214 { | |
2215 nvlist_t *config; | |
2216 uint64_t txg; | |
2217 | |
2218 if ((config = vdev_disk_read_rootlabel(devpath)) == NULL) | |
2219 return; | |
2220 | |
2221 VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0); | |
2222 | |
2223 if (txg > *besttxg) { | |
2224 *besttxg = txg; | |
2225 if (*bestconf != NULL) | |
2226 nvlist_free(*bestconf); | |
2227 *bestconf = config; | |
2228 *bestdev = devpath; | |
2229 } | |
2230 } | |
2231 | |
2232 boolean_t | |
2233 spa_rootdev_validate(nvlist_t *nv) | |
2234 { | |
2235 uint64_t ival; | |
2236 | |
2237 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_OFFLINE, &ival) == 0 || | |
2238 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_FAULTED, &ival) == 0 || | |
2239 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_DEGRADED, &ival) == 0 || | |
2240 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVED, &ival) == 0) | |
2241 return (B_FALSE); | |
2242 | |
2243 return (B_TRUE); | |
2244 } | |
2245 | |
2246 /* | |
2247 * Import a root pool. | |
2248 * | |
2249 * For x86. devpath_list will consist the physpath name of the vdev in a single | |
2250 * disk root pool or a list of physnames for the vdevs in a mirrored rootpool. | |
2251 * e.g. | |
2252 * "/pci@1f,0/ide@d/disk@0,0:a /pci@1f,o/ide@d/disk@2,0:a" | |
2253 * | |
2254 * For Sparc, devpath_list consists the physpath name of the booting device | |
2255 * no matter the rootpool is a single device pool or a mirrored pool. | |
2256 * e.g. | |
2257 * "/pci@1f,0/ide@d/disk@0,0:a" | |
2258 */ | |
2259 int | |
2260 spa_import_rootpool(char *devpath_list) | |
2261 { | |
2262 nvlist_t *conf = NULL; | |
2263 char *dev = NULL; | |
2264 char *pname; | |
2265 int error; | |
2266 | |
2267 /* | |
2268 * Get the vdev pathname and configuation from the most | |
2269 * recently updated vdev (highest txg). | |
2270 */ | |
2271 if (error = spa_get_rootconf(devpath_list, &dev, &conf)) | |
2272 goto msg_out; | |
2273 | |
2274 /* | |
2275 * Add type "root" vdev to the config. | |
2276 */ | |
2277 spa_build_rootpool_config(conf); | |
2278 | |
2279 VERIFY(nvlist_lookup_string(conf, ZPOOL_CONFIG_POOL_NAME, &pname) == 0); | |
2280 | |
6673
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2281 /* |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2282 * We specify 'allowfaulted' for this to be treated like spa_open() |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2283 * instead of spa_import(). This prevents us from marking vdevs as |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2284 * persistently unavailable, and generates FMA ereports as if it were a |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2285 * pool open, not import. |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2286 */ |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2287 error = spa_import_common(pname, conf, NULL, B_TRUE, B_TRUE); |
6423 | 2288 if (error == EEXIST) |
2289 error = 0; | |
2290 | |
2291 nvlist_free(conf); | |
2292 return (error); | |
2293 | |
2294 msg_out: | |
2295 cmn_err(CE_NOTE, "\n\n" | |
2296 " *************************************************** \n" | |
2297 " * This device is not bootable! * \n" | |
2298 " * It is either offlined or detached or faulted. * \n" | |
2299 " * Please try to boot from a different device. * \n" | |
2300 " *************************************************** \n\n"); | |
2301 | |
2302 return (error); | |
2303 } | |
2304 #endif | |
2305 | |
2306 /* | |
2307 * Import a non-root pool into the system. | |
2308 */ | |
2309 int | |
2310 spa_import(const char *pool, nvlist_t *config, nvlist_t *props) | |
2311 { | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2312 return (spa_import_common(pool, config, props, B_FALSE, B_FALSE)); |
6423 | 2313 } |
2314 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2315 int |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2316 spa_import_faulted(const char *pool, nvlist_t *config, nvlist_t *props) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2317 { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2318 return (spa_import_common(pool, config, props, B_FALSE, B_TRUE)); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2319 } |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2320 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2321 |
789 | 2322 /* |
2323 * This (illegal) pool name is used when temporarily importing a spa_t in order | |
2324 * to get the vdev stats associated with the imported devices. | |
2325 */ | |
2326 #define TRYIMPORT_NAME "$import" | |
2327 | |
2328 nvlist_t * | |
2329 spa_tryimport(nvlist_t *tryconfig) | |
2330 { | |
2331 nvlist_t *config = NULL; | |
2332 char *poolname; | |
2333 spa_t *spa; | |
2334 uint64_t state; | |
2335 | |
2336 if (nvlist_lookup_string(tryconfig, ZPOOL_CONFIG_POOL_NAME, &poolname)) | |
2337 return (NULL); | |
2338 | |
2339 if (nvlist_lookup_uint64(tryconfig, ZPOOL_CONFIG_POOL_STATE, &state)) | |
2340 return (NULL); | |
2341 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2342 /* |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2343 * Create and initialize the spa structure. |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2344 */ |
789 | 2345 mutex_enter(&spa_namespace_lock); |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2346 spa = spa_add(TRYIMPORT_NAME, NULL); |
789 | 2347 spa_activate(spa); |
2348 | |
2349 /* | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2350 * Pass off the heavy lifting to spa_load(). |
1732 | 2351 * Pass TRUE for mosconfig because the user-supplied config |
2352 * is actually the one to trust when doing an import. | |
789 | 2353 */ |
1732 | 2354 (void) spa_load(spa, tryconfig, SPA_LOAD_TRYIMPORT, B_TRUE); |
789 | 2355 |
2356 /* | |
2357 * If 'tryconfig' was at least parsable, return the current config. | |
2358 */ | |
2359 if (spa->spa_root_vdev != NULL) { | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2360 spa_config_enter(spa, RW_READER, FTAG); |
789 | 2361 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
|
2362 spa_config_exit(spa, FTAG); |
789 | 2363 VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, |
2364 poolname) == 0); | |
2365 VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, | |
2366 state) == 0); | |
3975
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
2367 VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TIMESTAMP, |
6674f5d79069
6282725 hostname/hostid should be stored in the label
ek110237
parents:
3912
diff
changeset
|
2368 spa->spa_uberblock.ub_timestamp) == 0); |
2082 | 2369 |
2370 /* | |
6423 | 2371 * If the bootfs property exists on this pool then we |
2372 * copy it out so that external consumers can tell which | |
2373 * pools are bootable. | |
2374 */ | |
2375 if (spa->spa_bootfs) { | |
2376 char *tmpname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | |
2377 | |
2378 /* | |
2379 * We have to play games with the name since the | |
2380 * pool was opened as TRYIMPORT_NAME. | |
2381 */ | |
2382 if (dsl_dsobj_to_dsname(spa->spa_name, | |
2383 spa->spa_bootfs, tmpname) == 0) { | |
2384 char *cp; | |
2385 char *dsname = kmem_alloc(MAXPATHLEN, KM_SLEEP); | |
2386 | |
2387 cp = strchr(tmpname, '/'); | |
2388 if (cp == NULL) { | |
2389 (void) strlcpy(dsname, tmpname, | |
2390 MAXPATHLEN); | |
2391 } else { | |
2392 (void) snprintf(dsname, MAXPATHLEN, | |
2393 "%s/%s", poolname, ++cp); | |
2394 } | |
2395 VERIFY(nvlist_add_string(config, | |
2396 ZPOOL_CONFIG_BOOTFS, dsname) == 0); | |
2397 kmem_free(dsname, MAXPATHLEN); | |
2398 } | |
2399 kmem_free(tmpname, MAXPATHLEN); | |
2400 } | |
2401 | |
2402 /* | |
5450 | 2403 * Add the list of hot spares and level 2 cache devices. |
2082 | 2404 */ |
2405 spa_add_spares(spa, config); | |
5450 | 2406 spa_add_l2cache(spa, config); |
789 | 2407 } |
2408 | |
2409 spa_unload(spa); | |
2410 spa_deactivate(spa); | |
2411 spa_remove(spa); | |
2412 mutex_exit(&spa_namespace_lock); | |
2413 | |
2414 return (config); | |
2415 } | |
2416 | |
2417 /* | |
2418 * Pool export/destroy | |
2419 * | |
2420 * The act of destroying or exporting a pool is very simple. We make sure there | |
2421 * is no more pending I/O and any references to the pool are gone. Then, we | |
2422 * update the pool state and sync all the labels to disk, removing the | |
2423 * configuration from the cache afterwards. | |
2424 */ | |
2425 static int | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2426 spa_export_common(char *pool, int new_state, nvlist_t **oldconfig) |
789 | 2427 { |
2428 spa_t *spa; | |
2429 | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2430 if (oldconfig) |
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2431 *oldconfig = NULL; |
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2432 |
789 | 2433 if (!(spa_mode & FWRITE)) |
2434 return (EROFS); | |
2435 | |
2436 mutex_enter(&spa_namespace_lock); | |
2437 if ((spa = spa_lookup(pool)) == NULL) { | |
2438 mutex_exit(&spa_namespace_lock); | |
2439 return (ENOENT); | |
2440 } | |
2441 | |
2442 /* | |
1544 | 2443 * Put a hold on the pool, drop the namespace lock, stop async tasks, |
2444 * reacquire the namespace lock, and see if we can export. | |
2445 */ | |
2446 spa_open_ref(spa, FTAG); | |
2447 mutex_exit(&spa_namespace_lock); | |
2448 spa_async_suspend(spa); | |
2449 mutex_enter(&spa_namespace_lock); | |
2450 spa_close(spa, FTAG); | |
2451 | |
2452 /* | |
789 | 2453 * The pool will be in core if it's openable, |
2454 * in which case we can modify its state. | |
2455 */ | |
2456 if (spa->spa_state != POOL_STATE_UNINITIALIZED && spa->spa_sync_on) { | |
2457 /* | |
2458 * Objsets may be open only because they're dirty, so we | |
2459 * have to force it to sync before checking spa_refcnt. | |
2460 */ | |
2461 txg_wait_synced(spa->spa_dsl_pool, 0); | |
2462 | |
1544 | 2463 /* |
2464 * A pool cannot be exported or destroyed if there are active | |
2465 * references. If we are resetting a pool, allow references by | |
2466 * fault injection handlers. | |
2467 */ | |
2468 if (!spa_refcount_zero(spa) || | |
2469 (spa->spa_inject_ref != 0 && | |
2470 new_state != POOL_STATE_UNINITIALIZED)) { | |
2471 spa_async_resume(spa); | |
789 | 2472 mutex_exit(&spa_namespace_lock); |
2473 return (EBUSY); | |
2474 } | |
2475 | |
2476 /* | |
2477 * We want this to be reflected on every label, | |
2478 * so mark them all dirty. spa_unload() will do the | |
2479 * final sync that pushes these changes out. | |
2480 */ | |
1544 | 2481 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
|
2482 spa_config_enter(spa, RW_WRITER, FTAG); |
1544 | 2483 spa->spa_state = new_state; |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2484 spa->spa_final_txg = spa_last_synced_txg(spa) + 1; |
1544 | 2485 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
|
2486 spa_config_exit(spa, FTAG); |
1544 | 2487 } |
789 | 2488 } |
2489 | |
4451 | 2490 spa_event_notify(spa, NULL, ESC_ZFS_POOL_DESTROY); |
2491 | |
789 | 2492 if (spa->spa_state != POOL_STATE_UNINITIALIZED) { |
2493 spa_unload(spa); | |
2494 spa_deactivate(spa); | |
2495 } | |
2496 | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2497 if (oldconfig && spa->spa_config) |
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2498 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
|
2499 |
1544 | 2500 if (new_state != POOL_STATE_UNINITIALIZED) { |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2501 spa_config_sync(spa, B_TRUE, B_TRUE); |
1544 | 2502 spa_remove(spa); |
2503 } | |
789 | 2504 mutex_exit(&spa_namespace_lock); |
2505 | |
2506 return (0); | |
2507 } | |
2508 | |
2509 /* | |
2510 * Destroy a storage pool. | |
2511 */ | |
2512 int | |
2513 spa_destroy(char *pool) | |
2514 { | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2515 return (spa_export_common(pool, POOL_STATE_DESTROYED, NULL)); |
789 | 2516 } |
2517 | |
2518 /* | |
2519 * Export a storage pool. | |
2520 */ | |
2521 int | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2522 spa_export(char *pool, nvlist_t **oldconfig) |
789 | 2523 { |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2524 return (spa_export_common(pool, POOL_STATE_EXPORTED, oldconfig)); |
789 | 2525 } |
2526 | |
2527 /* | |
1544 | 2528 * Similar to spa_export(), this unloads the spa_t without actually removing it |
2529 * from the namespace in any way. | |
2530 */ | |
2531 int | |
2532 spa_reset(char *pool) | |
2533 { | |
1775
e51e26b432c0
6410698 ZFS metadata needs to be more highly replicated (ditto blocks)
billm
parents:
1760
diff
changeset
|
2534 return (spa_export_common(pool, POOL_STATE_UNINITIALIZED, NULL)); |
1544 | 2535 } |
2536 | |
2537 /* | |
789 | 2538 * ========================================================================== |
2539 * Device manipulation | |
2540 * ========================================================================== | |
2541 */ | |
2542 | |
2543 /* | |
4527 | 2544 * Add a device to a storage pool. |
789 | 2545 */ |
2546 int | |
2547 spa_vdev_add(spa_t *spa, nvlist_t *nvroot) | |
2548 { | |
2549 uint64_t txg; | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2550 int c, error; |
789 | 2551 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
|
2552 vdev_t *vd, *tvd; |
5450 | 2553 nvlist_t **spares, **l2cache; |
2554 uint_t nspares, nl2cache; | |
789 | 2555 |
2556 txg = spa_vdev_enter(spa); | |
2557 | |
2082 | 2558 if ((error = spa_config_parse(spa, &vd, nvroot, NULL, 0, |
2559 VDEV_ALLOC_ADD)) != 0) | |
2560 return (spa_vdev_exit(spa, NULL, txg, error)); | |
2561 | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2562 spa->spa_pending_vdev = vd; |
789 | 2563 |
5450 | 2564 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, &spares, |
2565 &nspares) != 0) | |
2082 | 2566 nspares = 0; |
2567 | |
5450 | 2568 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, &l2cache, |
2569 &nl2cache) != 0) | |
2570 nl2cache = 0; | |
2571 | |
2572 if (vd->vdev_children == 0 && nspares == 0 && nl2cache == 0) { | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2573 spa->spa_pending_vdev = NULL; |
2082 | 2574 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
|
2575 } |
2082 | 2576 |
2577 if (vd->vdev_children != 0) { | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2578 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
|
2579 spa->spa_pending_vdev = NULL; |
2082 | 2580 return (spa_vdev_exit(spa, vd, txg, error)); |
2581 } | |
2582 } | |
2583 | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2584 /* |
5450 | 2585 * We must validate the spares and l2cache devices after checking the |
2586 * children. Otherwise, vdev_inuse() will blindly overwrite the spare. | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2587 */ |
5450 | 2588 if ((error = spa_validate_aux(spa, nvroot, txg, VDEV_ALLOC_ADD)) != 0) { |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2589 spa->spa_pending_vdev = NULL; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2590 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
|
2591 } |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2592 |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2593 spa->spa_pending_vdev = NULL; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2594 |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2595 /* |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2596 * 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
|
2597 */ |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2598 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
|
2599 tvd = vd->vdev_child[c]; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2600 vdev_remove_child(vd, tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2601 tvd->vdev_id = rvd->vdev_children; |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2602 vdev_add_child(rvd, tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2603 vdev_config_dirty(tvd); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2604 } |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2605 |
2082 | 2606 if (nspares != 0) { |
5450 | 2607 spa_set_aux_vdevs(&spa->spa_spares, spares, nspares, |
2608 ZPOOL_CONFIG_SPARES); | |
2082 | 2609 spa_load_spares(spa); |
5450 | 2610 spa->spa_spares.sav_sync = B_TRUE; |
2611 } | |
2612 | |
2613 if (nl2cache != 0) { | |
2614 spa_set_aux_vdevs(&spa->spa_l2cache, l2cache, nl2cache, | |
2615 ZPOOL_CONFIG_L2CACHE); | |
2616 spa_load_l2cache(spa); | |
2617 spa->spa_l2cache.sav_sync = B_TRUE; | |
789 | 2618 } |
2619 | |
2620 /* | |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2621 * 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
|
2622 * 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
|
2623 * 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
|
2624 * 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
|
2625 * 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
|
2626 * 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
|
2627 * 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
|
2628 * |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2629 * 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
|
2630 * 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
|
2631 * steps will be completed the next time we load the pool. |
789 | 2632 */ |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2633 (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
|
2634 |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2635 mutex_enter(&spa_namespace_lock); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2636 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
|
2637 mutex_exit(&spa_namespace_lock); |
789 | 2638 |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
2639 return (0); |
789 | 2640 } |
2641 | |
2642 /* | |
2643 * Attach a device to a mirror. The arguments are the path to any device | |
2644 * in the mirror, and the nvroot for the new device. If the path specifies | |
2645 * a device that is not mirrored, we automatically insert the mirror vdev. | |
2646 * | |
2647 * If 'replacing' is specified, the new device is intended to replace the | |
2648 * existing device; in this case the two devices are made into their own | |
4451 | 2649 * mirror using the 'replacing' vdev, which is functionally identical to |
789 | 2650 * the mirror vdev (it actually reuses all the same ops) but has a few |
2651 * extra rules: you can't attach to it after it's been created, and upon | |
2652 * completion of resilvering, the first disk (the one being replaced) | |
2653 * is automatically detached. | |
2654 */ | |
2655 int | |
1544 | 2656 spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing) |
789 | 2657 { |
2658 uint64_t txg, open_txg; | |
2659 int error; | |
2660 vdev_t *rvd = spa->spa_root_vdev; | |
2661 vdev_t *oldvd, *newvd, *newrootvd, *pvd, *tvd; | |
2082 | 2662 vdev_ops_t *pvops; |
4527 | 2663 int is_log; |
789 | 2664 |
2665 txg = spa_vdev_enter(spa); | |
2666 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2667 oldvd = spa_lookup_by_guid(spa, guid, B_FALSE); |
789 | 2668 |
2669 if (oldvd == NULL) | |
2670 return (spa_vdev_exit(spa, NULL, txg, ENODEV)); | |
2671 | |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2672 if (!oldvd->vdev_ops->vdev_op_leaf) |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2673 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
|
2674 |
789 | 2675 pvd = oldvd->vdev_parent; |
2676 | |
2082 | 2677 if ((error = spa_config_parse(spa, &newrootvd, nvroot, NULL, 0, |
4451 | 2678 VDEV_ALLOC_ADD)) != 0) |
2679 return (spa_vdev_exit(spa, NULL, txg, EINVAL)); | |
2680 | |
2681 if (newrootvd->vdev_children != 1) | |
789 | 2682 return (spa_vdev_exit(spa, newrootvd, txg, EINVAL)); |
2683 | |
2684 newvd = newrootvd->vdev_child[0]; | |
2685 | |
2686 if (!newvd->vdev_ops->vdev_op_leaf) | |
2687 return (spa_vdev_exit(spa, newrootvd, txg, EINVAL)); | |
2688 | |
2082 | 2689 if ((error = vdev_create(newrootvd, txg, replacing)) != 0) |
789 | 2690 return (spa_vdev_exit(spa, newrootvd, txg, error)); |
2691 | |
4527 | 2692 /* |
2693 * Spares can't replace logs | |
2694 */ | |
2695 is_log = oldvd->vdev_islog; | |
2696 if (is_log && newvd->vdev_isspare) | |
2697 return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP)); | |
2698 | |
2082 | 2699 if (!replacing) { |
2700 /* | |
2701 * For attach, the only allowable parent is a mirror or the root | |
2702 * vdev. | |
2703 */ | |
2704 if (pvd->vdev_ops != &vdev_mirror_ops && | |
2705 pvd->vdev_ops != &vdev_root_ops) | |
2706 return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP)); | |
2707 | |
2708 pvops = &vdev_mirror_ops; | |
2709 } else { | |
2710 /* | |
2711 * Active hot spares can only be replaced by inactive hot | |
2712 * spares. | |
2713 */ | |
2714 if (pvd->vdev_ops == &vdev_spare_ops && | |
2715 pvd->vdev_child[1] == oldvd && | |
2716 !spa_has_spare(spa, newvd->vdev_guid)) | |
2717 return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP)); | |
2718 | |
2719 /* | |
2720 * If the source is a hot spare, and the parent isn't already a | |
2721 * 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
|
2722 * 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
|
2723 * 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
|
2724 * 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
|
2725 * non-spare). |
2082 | 2726 */ |
2727 if (pvd->vdev_ops == &vdev_replacing_ops) | |
2728 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
|
2729 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
|
2730 newvd->vdev_isspare != oldvd->vdev_isspare) |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2731 return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP)); |
2082 | 2732 else if (pvd->vdev_ops != &vdev_spare_ops && |
2733 newvd->vdev_isspare) | |
2734 pvops = &vdev_spare_ops; | |
2735 else | |
2736 pvops = &vdev_replacing_ops; | |
2737 } | |
2738 | |
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
|
2739 /* |
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
|
2740 * 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
|
2741 * 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
|
2742 */ |
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
|
2743 if (newvd->vdev_psize < vdev_get_rsize(oldvd)) |
789 | 2744 return (spa_vdev_exit(spa, newrootvd, txg, EOVERFLOW)); |
2745 | |
1732 | 2746 /* |
2747 * The new device cannot have a higher alignment requirement | |
2748 * than the top-level vdev. | |
2749 */ | |
2750 if (newvd->vdev_ashift > oldvd->vdev_top->vdev_ashift) | |
789 | 2751 return (spa_vdev_exit(spa, newrootvd, txg, EDOM)); |
2752 | |
2753 /* | |
2754 * If this is an in-place replacement, update oldvd's path and devid | |
2755 * to make it distinguishable from newvd, and unopenable from now on. | |
2756 */ | |
2757 if (strcmp(oldvd->vdev_path, newvd->vdev_path) == 0) { | |
2758 spa_strfree(oldvd->vdev_path); | |
2759 oldvd->vdev_path = kmem_alloc(strlen(newvd->vdev_path) + 5, | |
2760 KM_SLEEP); | |
2761 (void) sprintf(oldvd->vdev_path, "%s/%s", | |
2762 newvd->vdev_path, "old"); | |
2763 if (oldvd->vdev_devid != NULL) { | |
2764 spa_strfree(oldvd->vdev_devid); | |
2765 oldvd->vdev_devid = NULL; | |
2766 } | |
2767 } | |
2768 | |
2769 /* | |
2082 | 2770 * If the parent is not a mirror, or if we're replacing, insert the new |
2771 * mirror/replacing/spare vdev above oldvd. | |
789 | 2772 */ |
2773 if (pvd->vdev_ops != pvops) | |
2774 pvd = vdev_add_parent(oldvd, pvops); | |
2775 | |
2776 ASSERT(pvd->vdev_top->vdev_parent == rvd); | |
2777 ASSERT(pvd->vdev_ops == pvops); | |
2778 ASSERT(oldvd->vdev_parent == pvd); | |
2779 | |
2780 /* | |
2781 * Extract the new device from its root and add it to pvd. | |
2782 */ | |
2783 vdev_remove_child(newrootvd, newvd); | |
2784 newvd->vdev_id = pvd->vdev_children; | |
2785 vdev_add_child(pvd, newvd); | |
2786 | |
1544 | 2787 /* |
2788 * If newvd is smaller than oldvd, but larger than its rsize, | |
2789 * the addition of newvd may have decreased our parent's asize. | |
2790 */ | |
2791 pvd->vdev_asize = MIN(pvd->vdev_asize, newvd->vdev_asize); | |
2792 | |
789 | 2793 tvd = newvd->vdev_top; |
2794 ASSERT(pvd->vdev_top == tvd); | |
2795 ASSERT(tvd->vdev_parent == rvd); | |
2796 | |
2797 vdev_config_dirty(tvd); | |
2798 | |
2799 /* | |
2800 * Set newvd's DTL to [TXG_INITIAL, open_txg]. It will propagate | |
2801 * upward when spa_vdev_exit() calls vdev_dtl_reassess(). | |
2802 */ | |
2803 open_txg = txg + TXG_CONCURRENT_STATES - 1; | |
2804 | |
2805 mutex_enter(&newvd->vdev_dtl_lock); | |
2806 space_map_add(&newvd->vdev_dtl_map, TXG_INITIAL, | |
2807 open_txg - TXG_INITIAL + 1); | |
2808 mutex_exit(&newvd->vdev_dtl_lock); | |
2809 | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2810 if (newvd->vdev_isspare) |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2811 spa_spare_activate(newvd); |
1544 | 2812 |
789 | 2813 /* |
2814 * Mark newvd's DTL dirty in this txg. | |
2815 */ | |
1732 | 2816 vdev_dirty(tvd, VDD_DTL, newvd, txg); |
789 | 2817 |
2818 (void) spa_vdev_exit(spa, newrootvd, open_txg, 0); | |
2819 | |
2820 /* | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2821 * Kick off a resilver to update newvd. |
789 | 2822 */ |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
2823 VERIFY3U(spa_scrub(spa, POOL_SCRUB_RESILVER), ==, 0); |
789 | 2824 |
2825 return (0); | |
2826 } | |
2827 | |
2828 /* | |
2829 * Detach a device from a mirror or replacing vdev. | |
2830 * If 'replace_done' is specified, only detach if the parent | |
2831 * is a replacing vdev. | |
2832 */ | |
2833 int | |
1544 | 2834 spa_vdev_detach(spa_t *spa, uint64_t guid, int replace_done) |
789 | 2835 { |
2836 uint64_t txg; | |
2837 int c, t, error; | |
2838 vdev_t *rvd = spa->spa_root_vdev; | |
2839 vdev_t *vd, *pvd, *cvd, *tvd; | |
2082 | 2840 boolean_t unspare = B_FALSE; |
2841 uint64_t unspare_guid; | |
6673
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2842 size_t len; |
789 | 2843 |
2844 txg = spa_vdev_enter(spa); | |
2845 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
2846 vd = spa_lookup_by_guid(spa, guid, B_FALSE); |
789 | 2847 |
2848 if (vd == NULL) | |
2849 return (spa_vdev_exit(spa, NULL, txg, ENODEV)); | |
2850 | |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2851 if (!vd->vdev_ops->vdev_op_leaf) |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
2852 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
|
2853 |
789 | 2854 pvd = vd->vdev_parent; |
2855 | |
2856 /* | |
2857 * If replace_done is specified, only remove this device if it's | |
2082 | 2858 * the first child of a replacing vdev. For the 'spare' vdev, either |
2859 * disk can be removed. | |
789 | 2860 */ |
2082 | 2861 if (replace_done) { |
2862 if (pvd->vdev_ops == &vdev_replacing_ops) { | |
2863 if (vd->vdev_id != 0) | |
2864 return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); | |
2865 } else if (pvd->vdev_ops != &vdev_spare_ops) { | |
2866 return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); | |
2867 } | |
2868 } | |
2869 | |
2870 ASSERT(pvd->vdev_ops != &vdev_spare_ops || | |
4577 | 2871 spa_version(spa) >= SPA_VERSION_SPARES); |
789 | 2872 |
2873 /* | |
2082 | 2874 * Only mirror, replacing, and spare vdevs support detach. |
789 | 2875 */ |
2876 if (pvd->vdev_ops != &vdev_replacing_ops && | |
2082 | 2877 pvd->vdev_ops != &vdev_mirror_ops && |
2878 pvd->vdev_ops != &vdev_spare_ops) | |
789 | 2879 return (spa_vdev_exit(spa, NULL, txg, ENOTSUP)); |
2880 | |
2881 /* | |
2882 * If there's only one replica, you can't detach it. | |
2883 */ | |
2884 if (pvd->vdev_children <= 1) | |
2885 return (spa_vdev_exit(spa, NULL, txg, EBUSY)); | |
2886 | |
2887 /* | |
2888 * If all siblings have non-empty DTLs, this device may have the only | |
2889 * valid copy of the data, which means we cannot safely detach it. | |
2890 * | |
2891 * XXX -- as in the vdev_offline() case, we really want a more | |
2892 * precise DTL check. | |
2893 */ | |
2894 for (c = 0; c < pvd->vdev_children; c++) { | |
2895 uint64_t dirty; | |
2896 | |
2897 cvd = pvd->vdev_child[c]; | |
2898 if (cvd == vd) | |
2899 continue; | |
2900 if (vdev_is_dead(cvd)) | |
2901 continue; | |
2902 mutex_enter(&cvd->vdev_dtl_lock); | |
2903 dirty = cvd->vdev_dtl_map.sm_space | | |
2904 cvd->vdev_dtl_scrub.sm_space; | |
2905 mutex_exit(&cvd->vdev_dtl_lock); | |
2906 if (!dirty) | |
2907 break; | |
2908 } | |
2082 | 2909 |
2910 /* | |
2911 * If we are a replacing or spare vdev, then we can always detach the | |
2912 * latter child, as that is how one cancels the operation. | |
2913 */ | |
2914 if ((pvd->vdev_ops == &vdev_mirror_ops || vd->vdev_id != 1) && | |
2915 c == pvd->vdev_children) | |
789 | 2916 return (spa_vdev_exit(spa, NULL, txg, EBUSY)); |
2917 | |
2918 /* | |
6673
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2919 * If we are detaching the second disk from a replacing vdev, then |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2920 * check to see if we changed the original vdev's path to have "/old" |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2921 * at the end in spa_vdev_attach(). If so, undo that change now. |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2922 */ |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2923 if (pvd->vdev_ops == &vdev_replacing_ops && vd->vdev_id == 1 && |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2924 pvd->vdev_child[0]->vdev_path != NULL && |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2925 pvd->vdev_child[1]->vdev_path != NULL) { |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2926 ASSERT(pvd->vdev_child[1] == vd); |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2927 cvd = pvd->vdev_child[0]; |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2928 len = strlen(vd->vdev_path); |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2929 if (strncmp(cvd->vdev_path, vd->vdev_path, len) == 0 && |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2930 strcmp(cvd->vdev_path + len, "/old") == 0) { |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2931 spa_strfree(cvd->vdev_path); |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2932 cvd->vdev_path = spa_strdup(vd->vdev_path); |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2933 } |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2934 } |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2935 |
be079d6124af
6697301 deadlock between ZFS and devfs can hang system
eschrock
parents:
6643
diff
changeset
|
2936 /* |
2082 | 2937 * If we are detaching the original disk from a spare, then it implies |
2938 * that the spare should become a real disk, and be removed from the | |
2939 * active spare list for the pool. | |
2940 */ | |
2941 if (pvd->vdev_ops == &vdev_spare_ops && | |
2942 vd->vdev_id == 0) | |
2943 unspare = B_TRUE; | |
2944 | |
2945 /* | |
789 | 2946 * Erase the disk labels so the disk can be used for other things. |
2947 * This must be done after all other error cases are handled, | |
2948 * but before we disembowel vd (so we can still do I/O to it). | |
2949 * But if we can't do it, don't treat the error as fatal -- | |
2950 * it may be that the unwritability of the disk is the reason | |
2951 * it's being detached! | |
2952 */ | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2953 error = vdev_label_init(vd, 0, VDEV_LABEL_REMOVE); |
789 | 2954 |
2955 /* | |
2956 * Remove vd from its parent and compact the parent's children. | |
2957 */ | |
2958 vdev_remove_child(pvd, vd); | |
2959 vdev_compact_children(pvd); | |
2960 | |
2961 /* | |
2962 * Remember one of the remaining children so we can get tvd below. | |
2963 */ | |
2964 cvd = pvd->vdev_child[0]; | |
2965 | |
2966 /* | |
2082 | 2967 * If we need to remove the remaining child from the list of hot spares, |
2968 * do it now, marking the vdev as no longer a spare in the process. We | |
2969 * must do this before vdev_remove_parent(), because that can change the | |
2970 * GUID if it creates a new toplevel GUID. | |
2971 */ | |
2972 if (unspare) { | |
2973 ASSERT(cvd->vdev_isspare); | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2974 spa_spare_remove(cvd); |
2082 | 2975 unspare_guid = cvd->vdev_guid; |
2976 } | |
2977 | |
2978 /* | |
789 | 2979 * If the parent mirror/replacing vdev only has one child, |
2980 * the parent is no longer needed. Remove it from the tree. | |
2981 */ | |
2982 if (pvd->vdev_children == 1) | |
2983 vdev_remove_parent(cvd); | |
2984 | |
2985 /* | |
2986 * We don't set tvd until now because the parent we just removed | |
2987 * may have been the previous top-level vdev. | |
2988 */ | |
2989 tvd = cvd->vdev_top; | |
2990 ASSERT(tvd->vdev_parent == rvd); | |
2991 | |
2992 /* | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2993 * Reevaluate the parent vdev state. |
789 | 2994 */ |
4451 | 2995 vdev_propagate_state(cvd); |
789 | 2996 |
2997 /* | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
2998 * 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
|
2999 * 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
|
3000 * 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
|
3001 * there's nothing to read from disk. |
789 | 3002 */ |
1732 | 3003 VERIFY(vdev_metaslab_init(tvd, txg) == 0); |
789 | 3004 |
3005 vdev_config_dirty(tvd); | |
3006 | |
3007 /* | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
3008 * 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
|
3009 * 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
|
3010 * 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
|
3011 * prevent vd from being accessed after it's freed. |
789 | 3012 */ |
3013 for (t = 0; t < TXG_SIZE; t++) | |
3014 (void) txg_list_remove_this(&tvd->vdev_dtl_list, vd, t); | |
1732 | 3015 vd->vdev_detached = B_TRUE; |
3016 vdev_dirty(tvd, VDD_DTL, vd, txg); | |
789 | 3017 |
4451 | 3018 spa_event_notify(spa, vd, ESC_ZFS_VDEV_REMOVE); |
3019 | |
2082 | 3020 error = spa_vdev_exit(spa, vd, txg, 0); |
3021 | |
3022 /* | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
3023 * 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
|
3024 * 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
|
3025 * list of every other pool. |
2082 | 3026 */ |
3027 if (unspare) { | |
3028 spa = NULL; | |
3029 mutex_enter(&spa_namespace_lock); | |
3030 while ((spa = spa_next(spa)) != NULL) { | |
3031 if (spa->spa_state != POOL_STATE_ACTIVE) | |
3032 continue; | |
3033 | |
3034 (void) spa_vdev_remove(spa, unspare_guid, B_TRUE); | |
3035 } | |
3036 mutex_exit(&spa_namespace_lock); | |
3037 } | |
3038 | |
3039 return (error); | |
3040 } | |
3041 | |
3042 /* | |
5450 | 3043 * Remove a spares vdev from the nvlist config. |
2082 | 3044 */ |
5450 | 3045 static int |
3046 spa_remove_spares(spa_aux_vdev_t *sav, uint64_t guid, boolean_t unspare, | |
3047 nvlist_t **spares, int nspares, vdev_t *vd) | |
2082 | 3048 { |
5450 | 3049 nvlist_t *nv, **newspares; |
3050 int i, j; | |
2082 | 3051 |
3052 nv = NULL; | |
5450 | 3053 for (i = 0; i < nspares; i++) { |
3054 uint64_t theguid; | |
3055 | |
3056 VERIFY(nvlist_lookup_uint64(spares[i], | |
3057 ZPOOL_CONFIG_GUID, &theguid) == 0); | |
3058 if (theguid == guid) { | |
3059 nv = spares[i]; | |
3060 break; | |
2082 | 3061 } |
3062 } | |
3063 | |
3064 /* | |
5450 | 3065 * Only remove the hot spare if it's not currently in use in this pool. |
2082 | 3066 */ |
5450 | 3067 if (nv == NULL && vd == NULL) |
3068 return (ENOENT); | |
3069 | |
3070 if (nv == NULL && vd != NULL) | |
3071 return (ENOTSUP); | |
3072 | |
3073 if (!unspare && nv != NULL && vd != NULL) | |
3074 return (EBUSY); | |
2082 | 3075 |
3076 if (nspares == 1) { | |
3077 newspares = NULL; | |
3078 } else { | |
3079 newspares = kmem_alloc((nspares - 1) * sizeof (void *), | |
3080 KM_SLEEP); | |
3081 for (i = 0, j = 0; i < nspares; i++) { | |
3082 if (spares[i] != nv) | |
3083 VERIFY(nvlist_dup(spares[i], | |
3084 &newspares[j++], KM_SLEEP) == 0); | |
3085 } | |
3086 } | |
3087 | |
5450 | 3088 VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_SPARES, |
2082 | 3089 DATA_TYPE_NVLIST_ARRAY) == 0); |
5450 | 3090 VERIFY(nvlist_add_nvlist_array(sav->sav_config, |
3091 ZPOOL_CONFIG_SPARES, newspares, nspares - 1) == 0); | |
2082 | 3092 for (i = 0; i < nspares - 1; i++) |
3093 nvlist_free(newspares[i]); | |
3094 kmem_free(newspares, (nspares - 1) * sizeof (void *)); | |
5450 | 3095 |
3096 return (0); | |
3097 } | |
3098 | |
3099 /* | |
3100 * Remove an l2cache vdev from the nvlist config. | |
3101 */ | |
3102 static int | |
3103 spa_remove_l2cache(spa_aux_vdev_t *sav, uint64_t guid, nvlist_t **l2cache, | |
3104 int nl2cache, vdev_t *vd) | |
3105 { | |
3106 nvlist_t *nv, **newl2cache; | |
3107 int i, j; | |
3108 | |
3109 nv = NULL; | |
3110 for (i = 0; i < nl2cache; i++) { | |
3111 uint64_t theguid; | |
3112 | |
3113 VERIFY(nvlist_lookup_uint64(l2cache[i], | |
3114 ZPOOL_CONFIG_GUID, &theguid) == 0); | |
3115 if (theguid == guid) { | |
3116 nv = l2cache[i]; | |
3117 break; | |
3118 } | |
3119 } | |
3120 | |
3121 if (vd == NULL) { | |
3122 for (i = 0; i < nl2cache; i++) { | |
3123 if (sav->sav_vdevs[i]->vdev_guid == guid) { | |
3124 vd = sav->sav_vdevs[i]; | |
3125 break; | |
3126 } | |
3127 } | |
3128 } | |
3129 | |
3130 if (nv == NULL && vd == NULL) | |
3131 return (ENOENT); | |
3132 | |
3133 if (nv == NULL && vd != NULL) | |
3134 return (ENOTSUP); | |
3135 | |
3136 if (nl2cache == 1) { | |
3137 newl2cache = NULL; | |
3138 } else { | |
3139 newl2cache = kmem_alloc((nl2cache - 1) * sizeof (void *), | |
3140 KM_SLEEP); | |
3141 for (i = 0, j = 0; i < nl2cache; i++) { | |
3142 if (l2cache[i] != nv) | |
3143 VERIFY(nvlist_dup(l2cache[i], | |
3144 &newl2cache[j++], KM_SLEEP) == 0); | |
3145 } | |
3146 } | |
3147 | |
3148 VERIFY(nvlist_remove(sav->sav_config, ZPOOL_CONFIG_L2CACHE, | |
3149 DATA_TYPE_NVLIST_ARRAY) == 0); | |
3150 VERIFY(nvlist_add_nvlist_array(sav->sav_config, | |
3151 ZPOOL_CONFIG_L2CACHE, newl2cache, nl2cache - 1) == 0); | |
3152 for (i = 0; i < nl2cache - 1; i++) | |
3153 nvlist_free(newl2cache[i]); | |
3154 kmem_free(newl2cache, (nl2cache - 1) * sizeof (void *)); | |
3155 | |
3156 return (0); | |
3157 } | |
3158 | |
3159 /* | |
3160 * Remove a device from the pool. Currently, this supports removing only hot | |
3161 * spares and level 2 ARC devices. | |
3162 */ | |
3163 int | |
3164 spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare) | |
3165 { | |
3166 vdev_t *vd; | |
3167 nvlist_t **spares, **l2cache; | |
3168 uint_t nspares, nl2cache; | |
3169 int error = 0; | |
3170 | |
3171 spa_config_enter(spa, RW_WRITER, FTAG); | |
3172 | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3173 vd = spa_lookup_by_guid(spa, guid, B_FALSE); |
5450 | 3174 |
3175 if (spa->spa_spares.sav_vdevs != NULL && | |
3176 nvlist_lookup_nvlist_array(spa->spa_spares.sav_config, | |
3177 ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) { | |
3178 if ((error = spa_remove_spares(&spa->spa_spares, guid, unspare, | |
3179 spares, nspares, vd)) != 0) | |
3180 goto out; | |
3181 spa_load_spares(spa); | |
3182 spa->spa_spares.sav_sync = B_TRUE; | |
3183 goto out; | |
3184 } | |
3185 | |
3186 if (spa->spa_l2cache.sav_vdevs != NULL && | |
3187 nvlist_lookup_nvlist_array(spa->spa_l2cache.sav_config, | |
3188 ZPOOL_CONFIG_L2CACHE, &l2cache, &nl2cache) == 0) { | |
3189 if ((error = spa_remove_l2cache(&spa->spa_l2cache, guid, | |
3190 l2cache, nl2cache, vd)) != 0) | |
3191 goto out; | |
3192 spa_load_l2cache(spa); | |
3193 spa->spa_l2cache.sav_sync = B_TRUE; | |
3194 } | |
2082 | 3195 |
3196 out: | |
3197 spa_config_exit(spa, FTAG); | |
5450 | 3198 return (error); |
789 | 3199 } |
3200 | |
3201 /* | |
4451 | 3202 * Find any device that's done replacing, or a vdev marked 'unspare' that's |
3203 * current spared, so we can detach it. | |
789 | 3204 */ |
1544 | 3205 static vdev_t * |
4451 | 3206 spa_vdev_resilver_done_hunt(vdev_t *vd) |
789 | 3207 { |
1544 | 3208 vdev_t *newvd, *oldvd; |
789 | 3209 int c; |
3210 | |
1544 | 3211 for (c = 0; c < vd->vdev_children; c++) { |
4451 | 3212 oldvd = spa_vdev_resilver_done_hunt(vd->vdev_child[c]); |
1544 | 3213 if (oldvd != NULL) |
3214 return (oldvd); | |
3215 } | |
789 | 3216 |
4451 | 3217 /* |
3218 * Check for a completed replacement. | |
3219 */ | |
789 | 3220 if (vd->vdev_ops == &vdev_replacing_ops && vd->vdev_children == 2) { |
1544 | 3221 oldvd = vd->vdev_child[0]; |
3222 newvd = vd->vdev_child[1]; | |
789 | 3223 |
1544 | 3224 mutex_enter(&newvd->vdev_dtl_lock); |
3225 if (newvd->vdev_dtl_map.sm_space == 0 && | |
3226 newvd->vdev_dtl_scrub.sm_space == 0) { | |
3227 mutex_exit(&newvd->vdev_dtl_lock); | |
3228 return (oldvd); | |
3229 } | |
3230 mutex_exit(&newvd->vdev_dtl_lock); | |
3231 } | |
789 | 3232 |
4451 | 3233 /* |
3234 * Check for a completed resilver with the 'unspare' flag set. | |
3235 */ | |
3236 if (vd->vdev_ops == &vdev_spare_ops && vd->vdev_children == 2) { | |
3237 newvd = vd->vdev_child[0]; | |
3238 oldvd = vd->vdev_child[1]; | |
3239 | |
3240 mutex_enter(&newvd->vdev_dtl_lock); | |
3241 if (newvd->vdev_unspare && | |
3242 newvd->vdev_dtl_map.sm_space == 0 && | |
3243 newvd->vdev_dtl_scrub.sm_space == 0) { | |
3244 newvd->vdev_unspare = 0; | |
3245 mutex_exit(&newvd->vdev_dtl_lock); | |
3246 return (oldvd); | |
3247 } | |
3248 mutex_exit(&newvd->vdev_dtl_lock); | |
3249 } | |
3250 | |
1544 | 3251 return (NULL); |
789 | 3252 } |
3253 | |
1544 | 3254 static void |
4451 | 3255 spa_vdev_resilver_done(spa_t *spa) |
789 | 3256 { |
1544 | 3257 vdev_t *vd; |
2082 | 3258 vdev_t *pvd; |
1544 | 3259 uint64_t guid; |
2082 | 3260 uint64_t pguid = 0; |
789 | 3261 |
1544 | 3262 spa_config_enter(spa, RW_READER, FTAG); |
789 | 3263 |
4451 | 3264 while ((vd = spa_vdev_resilver_done_hunt(spa->spa_root_vdev)) != NULL) { |
1544 | 3265 guid = vd->vdev_guid; |
2082 | 3266 /* |
3267 * If we have just finished replacing a hot spared device, then | |
3268 * we need to detach the parent's first child (the original hot | |
3269 * spare) as well. | |
3270 */ | |
3271 pvd = vd->vdev_parent; | |
3272 if (pvd->vdev_parent->vdev_ops == &vdev_spare_ops && | |
3273 pvd->vdev_id == 0) { | |
3274 ASSERT(pvd->vdev_ops == &vdev_replacing_ops); | |
3275 ASSERT(pvd->vdev_parent->vdev_children == 2); | |
3276 pguid = pvd->vdev_parent->vdev_child[1]->vdev_guid; | |
3277 } | |
1544 | 3278 spa_config_exit(spa, FTAG); |
3279 if (spa_vdev_detach(spa, guid, B_TRUE) != 0) | |
3280 return; | |
2082 | 3281 if (pguid != 0 && spa_vdev_detach(spa, pguid, B_TRUE) != 0) |
3282 return; | |
1544 | 3283 spa_config_enter(spa, RW_READER, FTAG); |
789 | 3284 } |
3285 | |
1544 | 3286 spa_config_exit(spa, FTAG); |
789 | 3287 } |
3288 | |
3289 /* | |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3290 * 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
|
3291 * on spa_vdev_enter/exit() to synchronize the labels and cache. |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3292 */ |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3293 int |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3294 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
|
3295 { |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3296 vdev_t *vd; |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3297 uint64_t txg; |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3298 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3299 txg = spa_vdev_enter(spa); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3300 |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3301 if ((vd = spa_lookup_by_guid(spa, guid, B_TRUE)) == NULL) { |
2082 | 3302 /* |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3303 * Determine if this is a reference to a hot spare device. If |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3304 * it is, update the path manually as there is no associated |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3305 * vdev_t that can be synced to disk. |
2082 | 3306 */ |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3307 nvlist_t **spares; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3308 uint_t i, nspares; |
5450 | 3309 |
3310 if (spa->spa_spares.sav_config != NULL) { | |
3311 VERIFY(nvlist_lookup_nvlist_array( | |
3312 spa->spa_spares.sav_config, ZPOOL_CONFIG_SPARES, | |
3313 &spares, &nspares) == 0); | |
2082 | 3314 for (i = 0; i < nspares; i++) { |
3315 uint64_t theguid; | |
3316 VERIFY(nvlist_lookup_uint64(spares[i], | |
3317 ZPOOL_CONFIG_GUID, &theguid) == 0); | |
5450 | 3318 if (theguid == guid) { |
3319 VERIFY(nvlist_add_string(spares[i], | |
3320 ZPOOL_CONFIG_PATH, newpath) == 0); | |
3321 spa_load_spares(spa); | |
3322 spa->spa_spares.sav_sync = B_TRUE; | |
3323 return (spa_vdev_exit(spa, NULL, txg, | |
3324 0)); | |
3325 } | |
2082 | 3326 } |
3327 } | |
5450 | 3328 |
3329 return (spa_vdev_exit(spa, NULL, txg, ENOENT)); | |
2082 | 3330 } |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3331 |
1585
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
3332 if (!vd->vdev_ops->vdev_op_leaf) |
4ad213e858a9
6395480 ztest ASSERT: rbt.bt_objset == wbt.bt_objset, line 2041
bonwick
parents:
1544
diff
changeset
|
3333 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
|
3334 |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3335 spa_strfree(vd->vdev_path); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3336 vd->vdev_path = spa_strdup(newpath); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3337 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3338 vdev_config_dirty(vd->vdev_top); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3339 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3340 return (spa_vdev_exit(spa, NULL, txg, 0)); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3341 } |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3342 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1175
diff
changeset
|
3343 /* |
789 | 3344 * ========================================================================== |
3345 * SPA Scrubbing | |
3346 * ========================================================================== | |
3347 */ | |
3348 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3349 int |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3350 spa_scrub(spa_t *spa, pool_scrub_type_t type) |
789 | 3351 { |
4808 | 3352 ASSERT(!spa_config_held(spa, RW_WRITER)); |
3353 | |
789 | 3354 if ((uint_t)type >= POOL_SCRUB_TYPES) |
3355 return (ENOTSUP); | |
3356 | |
3357 /* | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3358 * If a resilver was requested, but there is no DTL on a |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3359 * writeable leaf device, we have nothing to do. |
789 | 3360 */ |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3361 if (type == POOL_SCRUB_RESILVER && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3362 !vdev_resilver_needed(spa->spa_root_vdev, NULL, NULL)) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3363 spa_async_request(spa, SPA_ASYNC_RESILVER_DONE); |
1544 | 3364 return (0); |
3365 } | |
789 | 3366 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3367 if (type == POOL_SCRUB_EVERYTHING && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3368 spa->spa_dsl_pool->dp_scrub_func != SCRUB_FUNC_NONE && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3369 spa->spa_dsl_pool->dp_scrub_isresilver) |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3370 return (EBUSY); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3371 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3372 if (type == POOL_SCRUB_EVERYTHING || type == POOL_SCRUB_RESILVER) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3373 return (dsl_pool_scrub_clean(spa->spa_dsl_pool)); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3374 } else if (type == POOL_SCRUB_NONE) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3375 return (dsl_pool_scrub_cancel(spa->spa_dsl_pool)); |
1544 | 3376 } else { |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3377 return (EINVAL); |
1544 | 3378 } |
789 | 3379 } |
3380 | |
1544 | 3381 /* |
3382 * ========================================================================== | |
3383 * SPA async task processing | |
3384 * ========================================================================== | |
3385 */ | |
3386 | |
3387 static void | |
4451 | 3388 spa_async_remove(spa_t *spa, vdev_t *vd) |
789 | 3389 { |
1544 | 3390 vdev_t *tvd; |
3391 int c; | |
3392 | |
4451 | 3393 for (c = 0; c < vd->vdev_children; c++) { |
3394 tvd = vd->vdev_child[c]; | |
3395 if (tvd->vdev_remove_wanted) { | |
3396 tvd->vdev_remove_wanted = 0; | |
3397 vdev_set_state(tvd, B_FALSE, VDEV_STATE_REMOVED, | |
3398 VDEV_AUX_NONE); | |
5329 | 3399 vdev_clear(spa, tvd, B_TRUE); |
4451 | 3400 vdev_config_dirty(tvd->vdev_top); |
1544 | 3401 } |
4451 | 3402 spa_async_remove(spa, tvd); |
1544 | 3403 } |
3404 } | |
3405 | |
3406 static void | |
3407 spa_async_thread(spa_t *spa) | |
3408 { | |
3409 int tasks; | |
4451 | 3410 uint64_t txg; |
1544 | 3411 |
3412 ASSERT(spa->spa_sync_on); | |
789 | 3413 |
1544 | 3414 mutex_enter(&spa->spa_async_lock); |
3415 tasks = spa->spa_async_tasks; | |
3416 spa->spa_async_tasks = 0; | |
3417 mutex_exit(&spa->spa_async_lock); | |
3418 | |
3419 /* | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3420 * 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
|
3421 */ |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3422 if (tasks & SPA_ASYNC_CONFIG_UPDATE) { |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3423 mutex_enter(&spa_namespace_lock); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3424 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
|
3425 mutex_exit(&spa_namespace_lock); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3426 } |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3427 |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3428 /* |
4451 | 3429 * See if any devices need to be marked REMOVED. |
5329 | 3430 * |
3431 * XXX - We avoid doing this when we are in | |
3432 * I/O failure state since spa_vdev_enter() grabs | |
3433 * the namespace lock and would not be able to obtain | |
3434 * the writer config lock. | |
1544 | 3435 */ |
5329 | 3436 if (tasks & SPA_ASYNC_REMOVE && |
3437 spa_state(spa) != POOL_STATE_IO_FAILURE) { | |
4451 | 3438 txg = spa_vdev_enter(spa); |
3439 spa_async_remove(spa, spa->spa_root_vdev); | |
3440 (void) spa_vdev_exit(spa, NULL, txg, 0); | |
3441 } | |
1544 | 3442 |
3443 /* | |
3444 * If any devices are done replacing, detach them. | |
3445 */ | |
4451 | 3446 if (tasks & SPA_ASYNC_RESILVER_DONE) |
3447 spa_vdev_resilver_done(spa); | |
789 | 3448 |
1544 | 3449 /* |
3450 * Kick off a resilver. | |
3451 */ | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3452 if (tasks & SPA_ASYNC_RESILVER) |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3453 VERIFY(spa_scrub(spa, POOL_SCRUB_RESILVER) == 0); |
1544 | 3454 |
3455 /* | |
3456 * Let the world know that we're done. | |
3457 */ | |
3458 mutex_enter(&spa->spa_async_lock); | |
3459 spa->spa_async_thread = NULL; | |
3460 cv_broadcast(&spa->spa_async_cv); | |
3461 mutex_exit(&spa->spa_async_lock); | |
3462 thread_exit(); | |
3463 } | |
3464 | |
3465 void | |
3466 spa_async_suspend(spa_t *spa) | |
3467 { | |
3468 mutex_enter(&spa->spa_async_lock); | |
3469 spa->spa_async_suspended++; | |
3470 while (spa->spa_async_thread != NULL) | |
3471 cv_wait(&spa->spa_async_cv, &spa->spa_async_lock); | |
3472 mutex_exit(&spa->spa_async_lock); | |
3473 } | |
3474 | |
3475 void | |
3476 spa_async_resume(spa_t *spa) | |
3477 { | |
3478 mutex_enter(&spa->spa_async_lock); | |
3479 ASSERT(spa->spa_async_suspended != 0); | |
3480 spa->spa_async_suspended--; | |
3481 mutex_exit(&spa->spa_async_lock); | |
3482 } | |
3483 | |
3484 static void | |
3485 spa_async_dispatch(spa_t *spa) | |
3486 { | |
3487 mutex_enter(&spa->spa_async_lock); | |
3488 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
|
3489 spa->spa_async_thread == NULL && |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3490 rootdir != NULL && !vn_is_readonly(rootdir)) |
1544 | 3491 spa->spa_async_thread = thread_create(NULL, 0, |
3492 spa_async_thread, spa, 0, &p0, TS_RUN, maxclsyspri); | |
3493 mutex_exit(&spa->spa_async_lock); | |
3494 } | |
3495 | |
3496 void | |
3497 spa_async_request(spa_t *spa, int task) | |
3498 { | |
3499 mutex_enter(&spa->spa_async_lock); | |
3500 spa->spa_async_tasks |= task; | |
3501 mutex_exit(&spa->spa_async_lock); | |
789 | 3502 } |
3503 | |
3504 /* | |
3505 * ========================================================================== | |
3506 * SPA syncing routines | |
3507 * ========================================================================== | |
3508 */ | |
3509 | |
3510 static void | |
3511 spa_sync_deferred_frees(spa_t *spa, uint64_t txg) | |
3512 { | |
3513 bplist_t *bpl = &spa->spa_sync_bplist; | |
3514 dmu_tx_t *tx; | |
3515 blkptr_t blk; | |
3516 uint64_t itor = 0; | |
3517 zio_t *zio; | |
3518 int error; | |
3519 uint8_t c = 1; | |
3520 | |
3521 zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CONFIG_HELD); | |
3522 | |
3523 while (bplist_iterate(bpl, &itor, &blk) == 0) | |
3524 zio_nowait(zio_free(zio, spa, txg, &blk, NULL, NULL)); | |
3525 | |
3526 error = zio_wait(zio); | |
3527 ASSERT3U(error, ==, 0); | |
3528 | |
3529 tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg); | |
3530 bplist_vacate(bpl, tx); | |
3531 | |
3532 /* | |
3533 * Pre-dirty the first block so we sync to convergence faster. | |
3534 * (Usually only the first block is needed.) | |
3535 */ | |
3536 dmu_write(spa->spa_meta_objset, spa->spa_sync_bplist_obj, 0, 1, &c, tx); | |
3537 dmu_tx_commit(tx); | |
3538 } | |
3539 | |
3540 static void | |
2082 | 3541 spa_sync_nvlist(spa_t *spa, uint64_t obj, nvlist_t *nv, dmu_tx_t *tx) |
3542 { | |
3543 char *packed = NULL; | |
3544 size_t nvsize = 0; | |
3545 dmu_buf_t *db; | |
3546 | |
3547 VERIFY(nvlist_size(nv, &nvsize, NV_ENCODE_XDR) == 0); | |
3548 | |
3549 packed = kmem_alloc(nvsize, KM_SLEEP); | |
3550 | |
3551 VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR, | |
3552 KM_SLEEP) == 0); | |
3553 | |
3554 dmu_write(spa->spa_meta_objset, obj, 0, nvsize, packed, tx); | |
3555 | |
3556 kmem_free(packed, nvsize); | |
3557 | |
3558 VERIFY(0 == dmu_bonus_hold(spa->spa_meta_objset, obj, FTAG, &db)); | |
3559 dmu_buf_will_dirty(db, tx); | |
3560 *(uint64_t *)db->db_data = nvsize; | |
3561 dmu_buf_rele(db, FTAG); | |
3562 } | |
3563 | |
3564 static void | |
5450 | 3565 spa_sync_aux_dev(spa_t *spa, spa_aux_vdev_t *sav, dmu_tx_t *tx, |
3566 const char *config, const char *entry) | |
2082 | 3567 { |
3568 nvlist_t *nvroot; | |
5450 | 3569 nvlist_t **list; |
2082 | 3570 int i; |
3571 | |
5450 | 3572 if (!sav->sav_sync) |
2082 | 3573 return; |
3574 | |
3575 /* | |
5450 | 3576 * Update the MOS nvlist describing the list of available devices. |
3577 * spa_validate_aux() will have already made sure this nvlist is | |
4451 | 3578 * valid and the vdevs are labeled appropriately. |
2082 | 3579 */ |
5450 | 3580 if (sav->sav_object == 0) { |
3581 sav->sav_object = dmu_object_alloc(spa->spa_meta_objset, | |
3582 DMU_OT_PACKED_NVLIST, 1 << 14, DMU_OT_PACKED_NVLIST_SIZE, | |
3583 sizeof (uint64_t), tx); | |
2082 | 3584 VERIFY(zap_update(spa->spa_meta_objset, |
5450 | 3585 DMU_POOL_DIRECTORY_OBJECT, entry, sizeof (uint64_t), 1, |
3586 &sav->sav_object, tx) == 0); | |
2082 | 3587 } |
3588 | |
3589 VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0); | |
5450 | 3590 if (sav->sav_count == 0) { |
3591 VERIFY(nvlist_add_nvlist_array(nvroot, config, NULL, 0) == 0); | |
2082 | 3592 } else { |
5450 | 3593 list = kmem_alloc(sav->sav_count * sizeof (void *), KM_SLEEP); |
3594 for (i = 0; i < sav->sav_count; i++) | |
3595 list[i] = vdev_config_generate(spa, sav->sav_vdevs[i], | |
3596 B_FALSE, B_FALSE, B_TRUE); | |
3597 VERIFY(nvlist_add_nvlist_array(nvroot, config, list, | |
3598 sav->sav_count) == 0); | |
3599 for (i = 0; i < sav->sav_count; i++) | |
3600 nvlist_free(list[i]); | |
3601 kmem_free(list, sav->sav_count * sizeof (void *)); | |
2082 | 3602 } |
3603 | |
5450 | 3604 spa_sync_nvlist(spa, sav->sav_object, nvroot, tx); |
2926 | 3605 nvlist_free(nvroot); |
2082 | 3606 |
5450 | 3607 sav->sav_sync = B_FALSE; |
2082 | 3608 } |
3609 | |
3610 static void | |
789 | 3611 spa_sync_config_object(spa_t *spa, dmu_tx_t *tx) |
3612 { | |
3613 nvlist_t *config; | |
3614 | |
3615 if (list_is_empty(&spa->spa_dirty_list)) | |
3616 return; | |
3617 | |
3618 config = spa_config_generate(spa, NULL, dmu_tx_get_txg(tx), B_FALSE); | |
3619 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3620 if (spa->spa_config_syncing) |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3621 nvlist_free(spa->spa_config_syncing); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3622 spa->spa_config_syncing = config; |
789 | 3623 |
2082 | 3624 spa_sync_nvlist(spa, spa->spa_config_object, config, tx); |
789 | 3625 } |
3626 | |
5094 | 3627 /* |
3628 * Set zpool properties. | |
3629 */ | |
3912 | 3630 static void |
4543 | 3631 spa_sync_props(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx) |
3912 | 3632 { |
3633 spa_t *spa = arg1; | |
5094 | 3634 objset_t *mos = spa->spa_meta_objset; |
3912 | 3635 nvlist_t *nvp = arg2; |
5094 | 3636 nvpair_t *elem; |
4451 | 3637 uint64_t intval; |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3638 char *strval; |
5094 | 3639 zpool_prop_t prop; |
3640 const char *propname; | |
3641 zprop_type_t proptype; | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3642 spa_config_dirent_t *dp; |
5094 | 3643 |
3644 elem = NULL; | |
3645 while ((elem = nvlist_next_nvpair(nvp, elem))) { | |
3646 switch (prop = zpool_name_to_prop(nvpair_name(elem))) { | |
3647 case ZPOOL_PROP_VERSION: | |
3648 /* | |
3649 * Only set version for non-zpool-creation cases | |
3650 * (set/import). spa_create() needs special care | |
3651 * for version setting. | |
3652 */ | |
3653 if (tx->tx_txg != TXG_INITIAL) { | |
3654 VERIFY(nvpair_value_uint64(elem, | |
3655 &intval) == 0); | |
3656 ASSERT(intval <= SPA_VERSION); | |
3657 ASSERT(intval >= spa_version(spa)); | |
3658 spa->spa_uberblock.ub_version = intval; | |
3659 vdev_config_dirty(spa->spa_root_vdev); | |
3660 } | |
3661 break; | |
3662 | |
3663 case ZPOOL_PROP_ALTROOT: | |
3664 /* | |
3665 * 'altroot' is a non-persistent property. It should | |
3666 * have been set temporarily at creation or import time. | |
3667 */ | |
3668 ASSERT(spa->spa_root != NULL); | |
3669 break; | |
3670 | |
5363 | 3671 case ZPOOL_PROP_CACHEFILE: |
5094 | 3672 /* |
5363 | 3673 * 'cachefile' is a non-persistent property, but note |
3674 * an async request that the config cache needs to be | |
3675 * udpated. | |
5094 | 3676 */ |
5363 | 3677 VERIFY(nvpair_value_string(elem, &strval) == 0); |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3678 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3679 dp = kmem_alloc(sizeof (spa_config_dirent_t), |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3680 KM_SLEEP); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3681 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3682 if (strval[0] == '\0') |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3683 dp->scd_path = spa_strdup(spa_config_path); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3684 else if (strcmp(strval, "none") == 0) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3685 dp->scd_path = NULL; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3686 else |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3687 dp->scd_path = spa_strdup(strval); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3688 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
3689 list_insert_head(&spa->spa_config_list, dp); |
5363 | 3690 spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE); |
4543 | 3691 break; |
5094 | 3692 default: |
3693 /* | |
3694 * Set pool property values in the poolprops mos object. | |
3695 */ | |
3696 mutex_enter(&spa->spa_props_lock); | |
3697 if (spa->spa_pool_props_object == 0) { | |
3698 objset_t *mos = spa->spa_meta_objset; | |
3699 | |
3700 VERIFY((spa->spa_pool_props_object = | |
3701 zap_create(mos, DMU_OT_POOL_PROPS, | |
3702 DMU_OT_NONE, 0, tx)) > 0); | |
3703 | |
3704 VERIFY(zap_update(mos, | |
3705 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS, | |
3706 8, 1, &spa->spa_pool_props_object, tx) | |
3707 == 0); | |
3708 } | |
3709 mutex_exit(&spa->spa_props_lock); | |
3710 | |
3711 /* normalize the property name */ | |
3712 propname = zpool_prop_to_name(prop); | |
3713 proptype = zpool_prop_get_type(prop); | |
3714 | |
3715 if (nvpair_type(elem) == DATA_TYPE_STRING) { | |
3716 ASSERT(proptype == PROP_TYPE_STRING); | |
3717 VERIFY(nvpair_value_string(elem, &strval) == 0); | |
3718 VERIFY(zap_update(mos, | |
3719 spa->spa_pool_props_object, propname, | |
3720 1, strlen(strval) + 1, strval, tx) == 0); | |
3721 | |
3722 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) { | |
3723 VERIFY(nvpair_value_uint64(elem, &intval) == 0); | |
3724 | |
3725 if (proptype == PROP_TYPE_INDEX) { | |
3726 const char *unused; | |
3727 VERIFY(zpool_prop_index_to_string( | |
3728 prop, intval, &unused) == 0); | |
3729 } | |
3730 VERIFY(zap_update(mos, | |
3731 spa->spa_pool_props_object, propname, | |
3732 8, 1, &intval, tx) == 0); | |
3733 } else { | |
3734 ASSERT(0); /* not allowed */ | |
3735 } | |
3736 | |
5329 | 3737 switch (prop) { |
3738 case ZPOOL_PROP_DELEGATION: | |
5094 | 3739 spa->spa_delegation = intval; |
5329 | 3740 break; |
3741 case ZPOOL_PROP_BOOTFS: | |
5094 | 3742 spa->spa_bootfs = intval; |
5329 | 3743 break; |
3744 case ZPOOL_PROP_FAILUREMODE: | |
3745 spa->spa_failmode = intval; | |
3746 break; | |
3747 default: | |
3748 break; | |
3749 } | |
3912 | 3750 } |
5094 | 3751 |
3752 /* log internal history if this is not a zpool create */ | |
3753 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY && | |
3754 tx->tx_txg != TXG_INITIAL) { | |
3755 spa_history_internal_log(LOG_POOL_PROPSET, | |
3756 spa, tx, cr, "%s %lld %s", | |
3757 nvpair_name(elem), intval, spa->spa_name); | |
3758 } | |
3912 | 3759 } |
3760 } | |
3761 | |
789 | 3762 /* |
3763 * Sync the specified transaction group. New blocks may be dirtied as | |
3764 * part of the process, so we iterate until it converges. | |
3765 */ | |
3766 void | |
3767 spa_sync(spa_t *spa, uint64_t txg) | |
3768 { | |
3769 dsl_pool_t *dp = spa->spa_dsl_pool; | |
3770 objset_t *mos = spa->spa_meta_objset; | |
3771 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
|
3772 vdev_t *rvd = spa->spa_root_vdev; |
789 | 3773 vdev_t *vd; |
3774 dmu_tx_t *tx; | |
3775 int dirty_vdevs; | |
3776 | |
3777 /* | |
3778 * Lock out configuration changes. | |
3779 */ | |
1544 | 3780 spa_config_enter(spa, RW_READER, FTAG); |
789 | 3781 |
3782 spa->spa_syncing_txg = txg; | |
3783 spa->spa_sync_pass = 0; | |
3784 | |
1544 | 3785 VERIFY(0 == bplist_open(bpl, mos, spa->spa_sync_bplist_obj)); |
789 | 3786 |
2082 | 3787 tx = dmu_tx_create_assigned(dp, txg); |
3788 | |
3789 /* | |
4577 | 3790 * If we are upgrading to SPA_VERSION_RAIDZ_DEFLATE this txg, |
2082 | 3791 * set spa_deflate if we have no raid-z vdevs. |
3792 */ | |
4577 | 3793 if (spa->spa_ubsync.ub_version < SPA_VERSION_RAIDZ_DEFLATE && |
3794 spa->spa_uberblock.ub_version >= SPA_VERSION_RAIDZ_DEFLATE) { | |
2082 | 3795 int i; |
3796 | |
3797 for (i = 0; i < rvd->vdev_children; i++) { | |
3798 vd = rvd->vdev_child[i]; | |
3799 if (vd->vdev_deflate_ratio != SPA_MINBLOCKSIZE) | |
3800 break; | |
3801 } | |
3802 if (i == rvd->vdev_children) { | |
3803 spa->spa_deflate = TRUE; | |
3804 VERIFY(0 == zap_add(spa->spa_meta_objset, | |
3805 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_DEFLATE, | |
3806 sizeof (uint64_t), 1, &spa->spa_deflate, tx)); | |
3807 } | |
3808 } | |
3809 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3810 if (spa->spa_ubsync.ub_version < SPA_VERSION_ORIGIN && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3811 spa->spa_uberblock.ub_version >= SPA_VERSION_ORIGIN) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3812 dsl_pool_create_origin(dp, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3813 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3814 /* Keeping the origin open increases spa_minref */ |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3815 spa->spa_minref += 3; |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3816 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3817 |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3818 if (spa->spa_ubsync.ub_version < SPA_VERSION_NEXT_CLONES && |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3819 spa->spa_uberblock.ub_version >= SPA_VERSION_NEXT_CLONES) { |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3820 dsl_pool_upgrade_clones(dp, tx); |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3821 } |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3822 |
789 | 3823 /* |
3824 * If anything has changed in this txg, push the deferred frees | |
3825 * from the previous txg. If not, leave them alone so that we | |
3826 * don't generate work on an otherwise idle system. | |
3827 */ | |
3828 if (!txg_list_empty(&dp->dp_dirty_datasets, txg) || | |
2329
e640bebc73b3
6446569 deferred list is hooked on flintstone vitamins
ek110237
parents:
2199
diff
changeset
|
3829 !txg_list_empty(&dp->dp_dirty_dirs, txg) || |
e640bebc73b3
6446569 deferred list is hooked on flintstone vitamins
ek110237
parents:
2199
diff
changeset
|
3830 !txg_list_empty(&dp->dp_sync_tasks, txg)) |
789 | 3831 spa_sync_deferred_frees(spa, txg); |
3832 | |
3833 /* | |
3834 * Iterate to convergence. | |
3835 */ | |
3836 do { | |
3837 spa->spa_sync_pass++; | |
3838 | |
3839 spa_sync_config_object(spa, tx); | |
5450 | 3840 spa_sync_aux_dev(spa, &spa->spa_spares, tx, |
3841 ZPOOL_CONFIG_SPARES, DMU_POOL_SPARES); | |
3842 spa_sync_aux_dev(spa, &spa->spa_l2cache, tx, | |
3843 ZPOOL_CONFIG_L2CACHE, DMU_POOL_L2CACHE); | |
1544 | 3844 spa_errlog_sync(spa, txg); |
789 | 3845 dsl_pool_sync(dp, txg); |
3846 | |
3847 dirty_vdevs = 0; | |
3848 while (vd = txg_list_remove(&spa->spa_vdev_txg_list, txg)) { | |
3849 vdev_sync(vd, txg); | |
3850 dirty_vdevs++; | |
3851 } | |
3852 | |
3853 bplist_sync(bpl, tx); | |
3854 } while (dirty_vdevs); | |
3855 | |
3856 bplist_close(bpl); | |
3857 | |
3858 dprintf("txg %llu passes %d\n", txg, spa->spa_sync_pass); | |
3859 | |
3860 /* | |
3861 * Rewrite the vdev configuration (which includes the uberblock) | |
3862 * to commit the transaction group. | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3863 * |
5688
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3864 * If there are no dirty vdevs, we sync the uberblock to a few |
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3865 * random top-level vdevs that are known to be visible in the |
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3866 * config cache (see spa_vdev_add() for details). If there *are* |
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3867 * dirty vdevs -- or if the sync to our random subset fails -- |
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3868 * then sync the uberblock to all vdevs. |
789 | 3869 */ |
5688
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3870 if (list_is_empty(&spa->spa_dirty_list)) { |
6615
333cfc13ec55
6616599 vdev_config_sync(rvd, txg) == 0, file: ../../common/fs/zfs/spa .c, line: 3537
gw25295
parents:
6423
diff
changeset
|
3871 vdev_t *svd[SPA_DVAS_PER_BP]; |
333cfc13ec55
6616599 vdev_config_sync(rvd, txg) == 0, file: ../../common/fs/zfs/spa .c, line: 3537
gw25295
parents:
6423
diff
changeset
|
3872 int svdcount = 0; |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3873 int children = rvd->vdev_children; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3874 int c0 = spa_get_random(children); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3875 int c; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3876 |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3877 for (c = 0; c < children; c++) { |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3878 vd = rvd->vdev_child[(c0 + c) % children]; |
5688
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3879 if (vd->vdev_ms_array == 0 || vd->vdev_islog) |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3880 continue; |
5688
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3881 svd[svdcount++] = vd; |
c0b02c8fd2c0
6640580 spa_get_random() is insanely slow in userland
bonwick
parents:
5621
diff
changeset
|
3882 if (svdcount == SPA_DVAS_PER_BP) |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3883 break; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3884 } |
6615
333cfc13ec55
6616599 vdev_config_sync(rvd, txg) == 0, file: ../../common/fs/zfs/spa .c, line: 3537
gw25295
parents:
6423
diff
changeset
|
3885 vdev_config_sync(svd, svdcount, txg); |
333cfc13ec55
6616599 vdev_config_sync(rvd, txg) == 0, file: ../../common/fs/zfs/spa .c, line: 3537
gw25295
parents:
6423
diff
changeset
|
3886 } else { |
333cfc13ec55
6616599 vdev_config_sync(rvd, txg) == 0, file: ../../common/fs/zfs/spa .c, line: 3537
gw25295
parents:
6423
diff
changeset
|
3887 vdev_config_sync(rvd->vdev_child, rvd->vdev_children, txg); |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3888 } |
2082 | 3889 dmu_tx_commit(tx); |
3890 | |
1635
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3891 /* |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3892 * Clear the dirty config list. |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3893 */ |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3894 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
|
3895 vdev_config_clean(vd); |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3896 |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3897 /* |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3898 * 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
|
3899 * 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
|
3900 */ |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3901 if (spa->spa_config_syncing != NULL) { |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3902 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
|
3903 spa->spa_config_txg = txg; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3904 spa->spa_config_syncing = NULL; |
0ab1193d47cb
6398664 zpool detach: missing argument to error message causes core dump
bonwick
parents:
1601
diff
changeset
|
3905 } |
789 | 3906 |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3907 spa->spa_traverse_wanted = B_TRUE; |
789 | 3908 rw_enter(&spa->spa_traverse_lock, RW_WRITER); |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
3909 spa->spa_traverse_wanted = B_FALSE; |
789 | 3910 spa->spa_ubsync = spa->spa_uberblock; |
3911 rw_exit(&spa->spa_traverse_lock); | |
3912 | |
3913 /* | |
3914 * Clean up the ZIL records for the synced txg. | |
3915 */ | |
3916 dsl_pool_zil_clean(dp); | |
3917 | |
3918 /* | |
3919 * Update usable space statistics. | |
3920 */ | |
3921 while (vd = txg_list_remove(&spa->spa_vdev_txg_list, TXG_CLEAN(txg))) | |
3922 vdev_sync_done(vd, txg); | |
3923 | |
3924 /* | |
3925 * It had better be the case that we didn't dirty anything | |
2082 | 3926 * since vdev_config_sync(). |
789 | 3927 */ |
3928 ASSERT(txg_list_empty(&dp->dp_dirty_datasets, txg)); | |
3929 ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg)); | |
3930 ASSERT(txg_list_empty(&spa->spa_vdev_txg_list, txg)); | |
3931 ASSERT(bpl->bpl_queue == NULL); | |
3932 | |
1544 | 3933 spa_config_exit(spa, FTAG); |
3934 | |
3935 /* | |
3936 * If any async tasks have been requested, kick them off. | |
3937 */ | |
3938 spa_async_dispatch(spa); | |
789 | 3939 } |
3940 | |
3941 /* | |
3942 * Sync all pools. We don't want to hold the namespace lock across these | |
3943 * operations, so we take a reference on the spa_t and drop the lock during the | |
3944 * sync. | |
3945 */ | |
3946 void | |
3947 spa_sync_allpools(void) | |
3948 { | |
3949 spa_t *spa = NULL; | |
3950 mutex_enter(&spa_namespace_lock); | |
3951 while ((spa = spa_next(spa)) != NULL) { | |
3952 if (spa_state(spa) != POOL_STATE_ACTIVE) | |
3953 continue; | |
3954 spa_open_ref(spa, FTAG); | |
3955 mutex_exit(&spa_namespace_lock); | |
3956 txg_wait_synced(spa_get_dsl(spa), 0); | |
3957 mutex_enter(&spa_namespace_lock); | |
3958 spa_close(spa, FTAG); | |
3959 } | |
3960 mutex_exit(&spa_namespace_lock); | |
3961 } | |
3962 | |
3963 /* | |
3964 * ========================================================================== | |
3965 * Miscellaneous routines | |
3966 * ========================================================================== | |
3967 */ | |
3968 | |
3969 /* | |
3970 * Remove all pools in the system. | |
3971 */ | |
3972 void | |
3973 spa_evict_all(void) | |
3974 { | |
3975 spa_t *spa; | |
3976 | |
3977 /* | |
3978 * Remove all cached state. All pools should be closed now, | |
3979 * so every spa in the AVL tree should be unreferenced. | |
3980 */ | |
3981 mutex_enter(&spa_namespace_lock); | |
3982 while ((spa = spa_next(NULL)) != NULL) { | |
3983 /* | |
1544 | 3984 * Stop async tasks. The async thread may need to detach |
3985 * a device that's been replaced, which requires grabbing | |
3986 * spa_namespace_lock, so we must drop it here. | |
789 | 3987 */ |
3988 spa_open_ref(spa, FTAG); | |
3989 mutex_exit(&spa_namespace_lock); | |
1544 | 3990 spa_async_suspend(spa); |
4808 | 3991 mutex_enter(&spa_namespace_lock); |
789 | 3992 spa_close(spa, FTAG); |
3993 | |
3994 if (spa->spa_state != POOL_STATE_UNINITIALIZED) { | |
3995 spa_unload(spa); | |
3996 spa_deactivate(spa); | |
3997 } | |
3998 spa_remove(spa); | |
3999 } | |
4000 mutex_exit(&spa_namespace_lock); | |
4001 } | |
1544 | 4002 |
4003 vdev_t * | |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4004 spa_lookup_by_guid(spa_t *spa, uint64_t guid, boolean_t l2cache) |
1544 | 4005 { |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4006 vdev_t *vd; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4007 int i; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4008 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4009 if ((vd = vdev_lookup_by_guid(spa->spa_root_vdev, guid)) != NULL) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4010 return (vd); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4011 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4012 if (l2cache) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4013 for (i = 0; i < spa->spa_l2cache.sav_count; i++) { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4014 vd = spa->spa_l2cache.sav_vdevs[i]; |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4015 if (vd->vdev_guid == guid) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4016 return (vd); |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4017 } |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4018 } |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4019 |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6615
diff
changeset
|
4020 return (NULL); |
1544 | 4021 } |
1760 | 4022 |
4023 void | |
5094 | 4024 spa_upgrade(spa_t *spa, uint64_t version) |
1760 | 4025 { |
4026 spa_config_enter(spa, RW_WRITER, FTAG); | |
4027 | |
4028 /* | |
4029 * This should only be called for a non-faulted pool, and since a | |
4030 * future version would result in an unopenable pool, this shouldn't be | |
4031 * possible. | |
4032 */ | |
4577 | 4033 ASSERT(spa->spa_uberblock.ub_version <= SPA_VERSION); |
5094 | 4034 ASSERT(version >= spa->spa_uberblock.ub_version); |
4035 | |
4036 spa->spa_uberblock.ub_version = version; | |
1760 | 4037 vdev_config_dirty(spa->spa_root_vdev); |
4038 | |
4039 spa_config_exit(spa, FTAG); | |
2082 | 4040 |
4041 txg_wait_synced(spa_get_dsl(spa), 0); | |
1760 | 4042 } |
2082 | 4043 |
4044 boolean_t | |
4045 spa_has_spare(spa_t *spa, uint64_t guid) | |
4046 { | |
4047 int i; | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
4048 uint64_t spareguid; |
5450 | 4049 spa_aux_vdev_t *sav = &spa->spa_spares; |
4050 | |
4051 for (i = 0; i < sav->sav_count; i++) | |
4052 if (sav->sav_vdevs[i]->vdev_guid == guid) | |
2082 | 4053 return (B_TRUE); |
4054 | |
5450 | 4055 for (i = 0; i < sav->sav_npending; i++) { |
4056 if (nvlist_lookup_uint64(sav->sav_pending[i], ZPOOL_CONFIG_GUID, | |
4057 &spareguid) == 0 && spareguid == guid) | |
3377
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
4058 return (B_TRUE); |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
4059 } |
a2fa338530c1
6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents:
3290
diff
changeset
|
4060 |
2082 | 4061 return (B_FALSE); |
4062 } | |
3912 | 4063 |
4451 | 4064 /* |
4065 * Post a sysevent corresponding to the given event. The 'name' must be one of | |
4066 * the event definitions in sys/sysevent/eventdefs.h. The payload will be | |
4067 * filled in from the spa and (optionally) the vdev. This doesn't do anything | |
4068 * in the userland libzpool, as we don't want consumers to misinterpret ztest | |
4069 * or zdb as real changes. | |
4070 */ | |
4071 void | |
4072 spa_event_notify(spa_t *spa, vdev_t *vd, const char *name) | |
4073 { | |
4074 #ifdef _KERNEL | |
4075 sysevent_t *ev; | |
4076 sysevent_attr_list_t *attr = NULL; | |
4077 sysevent_value_t value; | |
4078 sysevent_id_t eid; | |
4079 | |
4080 ev = sysevent_alloc(EC_ZFS, (char *)name, SUNW_KERN_PUB "zfs", | |
4081 SE_SLEEP); | |
4082 | |
4083 value.value_type = SE_DATA_TYPE_STRING; | |
4084 value.value.sv_string = spa_name(spa); | |
4085 if (sysevent_add_attr(&attr, ZFS_EV_POOL_NAME, &value, SE_SLEEP) != 0) | |
4086 goto done; | |
4087 | |
4088 value.value_type = SE_DATA_TYPE_UINT64; | |
4089 value.value.sv_uint64 = spa_guid(spa); | |
4090 if (sysevent_add_attr(&attr, ZFS_EV_POOL_GUID, &value, SE_SLEEP) != 0) | |
4091 goto done; | |
4092 | |
4093 if (vd) { | |
4094 value.value_type = SE_DATA_TYPE_UINT64; | |
4095 value.value.sv_uint64 = vd->vdev_guid; | |
4096 if (sysevent_add_attr(&attr, ZFS_EV_VDEV_GUID, &value, | |
4097 SE_SLEEP) != 0) | |
4098 goto done; | |
4099 | |
4100 if (vd->vdev_path) { | |
4101 value.value_type = SE_DATA_TYPE_STRING; | |
4102 value.value.sv_string = vd->vdev_path; | |
4103 if (sysevent_add_attr(&attr, ZFS_EV_VDEV_PATH, | |
4104 &value, SE_SLEEP) != 0) | |
4105 goto done; | |
4106 } | |
4107 } | |
4108 | |
5756
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
4109 if (sysevent_attach_attributes(ev, attr) != 0) |
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
4110 goto done; |
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
4111 attr = NULL; |
05eb4c1ff492
6585441 spa_event_notify() doesn't pass its attributes
eschrock
parents:
5688
diff
changeset
|
4112 |
4451 | 4113 (void) log_sysevent(ev, SE_SLEEP, &eid); |
4114 | |
4115 done: | |
4116 if (attr) | |
4117 sysevent_free_attr(attr); | |
4118 sysevent_free(ev); | |
4119 #endif | |
4120 } |