111 { ZTI_FIX(100), ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
112 { ZTI_FIX(100), ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
112 { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
113 { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
113 { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
114 { ZTI_ONE, ZTI_NULL, ZTI_ONE, ZTI_NULL }, |
114 }; |
115 }; |
115 |
116 |
|
117 static dsl_syncfunc_t spa_sync_version; |
116 static dsl_syncfunc_t spa_sync_props; |
118 static dsl_syncfunc_t spa_sync_props; |
117 static boolean_t spa_has_active_shared_spare(spa_t *spa); |
119 static boolean_t spa_has_active_shared_spare(spa_t *spa); |
118 static int spa_load_impl(spa_t *spa, uint64_t, nvlist_t *config, |
120 static int spa_load_impl(spa_t *spa, uint64_t, nvlist_t *config, |
119 spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig, |
121 spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig, |
120 char **ereport); |
122 char **ereport); |
210 if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) |
213 if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION)) |
211 src = ZPROP_SRC_DEFAULT; |
214 src = ZPROP_SRC_DEFAULT; |
212 else |
215 else |
213 src = ZPROP_SRC_LOCAL; |
216 src = ZPROP_SRC_LOCAL; |
214 spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src); |
217 spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src); |
|
218 } |
|
219 |
|
220 if (pool != NULL) { |
|
221 dsl_dir_t *freedir = pool->dp_free_dir; |
|
222 |
|
223 /* |
|
224 * The $FREE directory was introduced in SPA_VERSION_DEADLISTS, |
|
225 * when opening pools before this version freedir will be NULL. |
|
226 */ |
|
227 if (freedir != NULL) { |
|
228 spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, NULL, |
|
229 freedir->dd_phys->dd_used_bytes, src); |
|
230 } else { |
|
231 spa_prop_add_list(*nvp, ZPOOL_PROP_FREEING, |
|
232 NULL, 0, src); |
|
233 } |
215 } |
234 } |
216 |
235 |
217 spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src); |
236 spa_prop_add_list(*nvp, ZPOOL_PROP_GUID, NULL, spa_guid(spa), src); |
218 |
237 |
219 if (spa->spa_comment != NULL) { |
238 if (spa->spa_comment != NULL) { |
351 spa_prop_validate(spa_t *spa, nvlist_t *props) |
370 spa_prop_validate(spa_t *spa, nvlist_t *props) |
352 { |
371 { |
353 nvpair_t *elem; |
372 nvpair_t *elem; |
354 int error = 0, reset_bootfs = 0; |
373 int error = 0, reset_bootfs = 0; |
355 uint64_t objnum; |
374 uint64_t objnum; |
|
375 boolean_t has_feature = B_FALSE; |
356 |
376 |
357 elem = NULL; |
377 elem = NULL; |
358 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { |
378 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { |
359 zpool_prop_t prop; |
|
360 char *propname, *strval; |
|
361 uint64_t intval; |
379 uint64_t intval; |
362 objset_t *os; |
380 char *strval, *slash, *check, *fname; |
363 char *slash, *check; |
381 const char *propname = nvpair_name(elem); |
364 |
382 zpool_prop_t prop = zpool_name_to_prop(propname); |
365 propname = nvpair_name(elem); |
|
366 |
|
367 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) |
|
368 return (EINVAL); |
|
369 |
383 |
370 switch (prop) { |
384 switch (prop) { |
|
385 case ZPROP_INVAL: |
|
386 if (!zpool_prop_feature(propname)) { |
|
387 error = EINVAL; |
|
388 break; |
|
389 } |
|
390 |
|
391 /* |
|
392 * Sanitize the input. |
|
393 */ |
|
394 if (nvpair_type(elem) != DATA_TYPE_UINT64) { |
|
395 error = EINVAL; |
|
396 break; |
|
397 } |
|
398 |
|
399 if (nvpair_value_uint64(elem, &intval) != 0) { |
|
400 error = EINVAL; |
|
401 break; |
|
402 } |
|
403 |
|
404 if (intval != 0) { |
|
405 error = EINVAL; |
|
406 break; |
|
407 } |
|
408 |
|
409 fname = strchr(propname, '@') + 1; |
|
410 if (zfeature_lookup_name(fname, NULL) != 0) { |
|
411 error = EINVAL; |
|
412 break; |
|
413 } |
|
414 |
|
415 has_feature = B_TRUE; |
|
416 break; |
|
417 |
371 case ZPOOL_PROP_VERSION: |
418 case ZPOOL_PROP_VERSION: |
372 error = nvpair_value_uint64(elem, &intval); |
419 error = nvpair_value_uint64(elem, &intval); |
373 if (!error && |
420 if (!error && |
374 (intval < spa_version(spa) || intval > SPA_VERSION)) |
421 (intval < spa_version(spa) || |
|
422 intval > SPA_VERSION_BEFORE_FEATURES || |
|
423 has_feature)) |
375 error = EINVAL; |
424 error = EINVAL; |
376 break; |
425 break; |
377 |
426 |
378 case ZPOOL_PROP_DELEGATION: |
427 case ZPOOL_PROP_DELEGATION: |
379 case ZPOOL_PROP_AUTOREPLACE: |
428 case ZPOOL_PROP_AUTOREPLACE: |
555 |
605 |
556 int |
606 int |
557 spa_prop_set(spa_t *spa, nvlist_t *nvp) |
607 spa_prop_set(spa_t *spa, nvlist_t *nvp) |
558 { |
608 { |
559 int error; |
609 int error; |
560 nvpair_t *elem; |
610 nvpair_t *elem = NULL; |
561 boolean_t need_sync = B_FALSE; |
611 boolean_t need_sync = B_FALSE; |
562 zpool_prop_t prop; |
|
563 |
612 |
564 if ((error = spa_prop_validate(spa, nvp)) != 0) |
613 if ((error = spa_prop_validate(spa, nvp)) != 0) |
565 return (error); |
614 return (error); |
566 |
615 |
567 elem = NULL; |
|
568 while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) { |
616 while ((elem = nvlist_next_nvpair(nvp, elem)) != NULL) { |
569 if ((prop = zpool_name_to_prop( |
617 zpool_prop_t prop = zpool_name_to_prop(nvpair_name(elem)); |
570 nvpair_name(elem))) == ZPROP_INVAL) |
|
571 return (EINVAL); |
|
572 |
618 |
573 if (prop == ZPOOL_PROP_CACHEFILE || |
619 if (prop == ZPOOL_PROP_CACHEFILE || |
574 prop == ZPOOL_PROP_ALTROOT || |
620 prop == ZPOOL_PROP_ALTROOT || |
575 prop == ZPOOL_PROP_READONLY) |
621 prop == ZPOOL_PROP_READONLY) |
576 continue; |
622 continue; |
577 |
623 |
|
624 if (prop == ZPOOL_PROP_VERSION || prop == ZPROP_INVAL) { |
|
625 uint64_t ver; |
|
626 |
|
627 if (prop == ZPOOL_PROP_VERSION) { |
|
628 VERIFY(nvpair_value_uint64(elem, &ver) == 0); |
|
629 } else { |
|
630 ASSERT(zpool_prop_feature(nvpair_name(elem))); |
|
631 ver = SPA_VERSION_FEATURES; |
|
632 need_sync = B_TRUE; |
|
633 } |
|
634 |
|
635 /* Save time if the version is already set. */ |
|
636 if (ver == spa_version(spa)) |
|
637 continue; |
|
638 |
|
639 /* |
|
640 * In addition to the pool directory object, we might |
|
641 * create the pool properties object, the features for |
|
642 * read object, the features for write object, or the |
|
643 * feature descriptions object. |
|
644 */ |
|
645 error = dsl_sync_task_do(spa_get_dsl(spa), NULL, |
|
646 spa_sync_version, spa, &ver, 6); |
|
647 if (error) |
|
648 return (error); |
|
649 continue; |
|
650 } |
|
651 |
578 need_sync = B_TRUE; |
652 need_sync = B_TRUE; |
579 break; |
653 break; |
580 } |
654 } |
581 |
655 |
582 if (need_sync) |
656 if (need_sync) { |
583 return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props, |
657 return (dsl_sync_task_do(spa_get_dsl(spa), NULL, spa_sync_props, |
584 spa, nvp, 3)); |
658 spa, nvp, 6)); |
585 else |
659 } |
586 return (0); |
660 |
|
661 return (0); |
587 } |
662 } |
588 |
663 |
589 /* |
664 /* |
590 * If the bootfs property value is dsobj, clear it. |
665 * If the bootfs property value is dsobj, clear it. |
591 */ |
666 */ |
1867 spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig, |
1945 spa_load_state_t state, spa_import_type_t type, boolean_t mosconfig, |
1868 char **ereport) |
1946 char **ereport) |
1869 { |
1947 { |
1870 int error = 0; |
1948 int error = 0; |
1871 nvlist_t *nvroot = NULL; |
1949 nvlist_t *nvroot = NULL; |
|
1950 nvlist_t *label; |
1872 vdev_t *rvd; |
1951 vdev_t *rvd; |
1873 uberblock_t *ub = &spa->spa_uberblock; |
1952 uberblock_t *ub = &spa->spa_uberblock; |
1874 uint64_t children, config_cache_txg = spa->spa_config_txg; |
1953 uint64_t children, config_cache_txg = spa->spa_config_txg; |
1875 int orig_mode = spa->spa_mode; |
1954 int orig_mode = spa->spa_mode; |
1876 int parse; |
1955 int parse; |
1877 uint64_t obj; |
1956 uint64_t obj; |
|
1957 boolean_t missing_feat_write = B_FALSE; |
1878 |
1958 |
1879 /* |
1959 /* |
1880 * If this is an untrusted config, access the pool in read-only mode. |
1960 * If this is an untrusted config, access the pool in read-only mode. |
1881 * This prevents things like resilvering recently removed devices. |
1961 * This prevents things like resilvering recently removed devices. |
1882 */ |
1962 */ |
1952 } |
2032 } |
1953 |
2033 |
1954 /* |
2034 /* |
1955 * Find the best uberblock. |
2035 * Find the best uberblock. |
1956 */ |
2036 */ |
1957 vdev_uberblock_load(NULL, rvd, ub); |
2037 vdev_uberblock_load(rvd, ub, &label); |
1958 |
2038 |
1959 /* |
2039 /* |
1960 * If we weren't able to find a single valid uberblock, return failure. |
2040 * If we weren't able to find a single valid uberblock, return failure. |
1961 */ |
2041 */ |
1962 if (ub->ub_txg == 0) |
2042 if (ub->ub_txg == 0) { |
|
2043 nvlist_free(label); |
1963 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, ENXIO)); |
2044 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, ENXIO)); |
1964 |
2045 } |
1965 /* |
2046 |
1966 * If the pool is newer than the code, we can't open it. |
2047 /* |
1967 */ |
2048 * If the pool has an unsupported version we can't open it. |
1968 if (ub->ub_version > SPA_VERSION) |
2049 */ |
|
2050 if (!SPA_VERSION_IS_SUPPORTED(ub->ub_version)) { |
|
2051 nvlist_free(label); |
1969 return (spa_vdev_err(rvd, VDEV_AUX_VERSION_NEWER, ENOTSUP)); |
2052 return (spa_vdev_err(rvd, VDEV_AUX_VERSION_NEWER, ENOTSUP)); |
|
2053 } |
|
2054 |
|
2055 if (ub->ub_version >= SPA_VERSION_FEATURES) { |
|
2056 nvlist_t *features; |
|
2057 |
|
2058 /* |
|
2059 * If we weren't able to find what's necessary for reading the |
|
2060 * MOS in the label, return failure. |
|
2061 */ |
|
2062 if (label == NULL || nvlist_lookup_nvlist(label, |
|
2063 ZPOOL_CONFIG_FEATURES_FOR_READ, &features) != 0) { |
|
2064 nvlist_free(label); |
|
2065 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, |
|
2066 ENXIO)); |
|
2067 } |
|
2068 |
|
2069 /* |
|
2070 * Update our in-core representation with the definitive values |
|
2071 * from the label. |
|
2072 */ |
|
2073 nvlist_free(spa->spa_label_features); |
|
2074 VERIFY(nvlist_dup(features, &spa->spa_label_features, 0) == 0); |
|
2075 } |
|
2076 |
|
2077 nvlist_free(label); |
|
2078 |
|
2079 /* |
|
2080 * Look through entries in the label nvlist's features_for_read. If |
|
2081 * there is a feature listed there which we don't understand then we |
|
2082 * cannot open a pool. |
|
2083 */ |
|
2084 if (ub->ub_version >= SPA_VERSION_FEATURES) { |
|
2085 nvlist_t *unsup_feat; |
|
2086 |
|
2087 VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) == |
|
2088 0); |
|
2089 |
|
2090 for (nvpair_t *nvp = nvlist_next_nvpair(spa->spa_label_features, |
|
2091 NULL); nvp != NULL; |
|
2092 nvp = nvlist_next_nvpair(spa->spa_label_features, nvp)) { |
|
2093 if (!zfeature_is_supported(nvpair_name(nvp))) { |
|
2094 VERIFY(nvlist_add_string(unsup_feat, |
|
2095 nvpair_name(nvp), "") == 0); |
|
2096 } |
|
2097 } |
|
2098 |
|
2099 if (!nvlist_empty(unsup_feat)) { |
|
2100 VERIFY(nvlist_add_nvlist(spa->spa_load_info, |
|
2101 ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0); |
|
2102 nvlist_free(unsup_feat); |
|
2103 return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT, |
|
2104 ENOTSUP)); |
|
2105 } |
|
2106 |
|
2107 nvlist_free(unsup_feat); |
|
2108 } |
1970 |
2109 |
1971 /* |
2110 /* |
1972 * If the vdev guid sum doesn't match the uberblock, we have an |
2111 * If the vdev guid sum doesn't match the uberblock, we have an |
1973 * incomplete configuration. We first check to see if the pool |
2112 * incomplete configuration. We first check to see if the pool |
1974 * is aware of the complete config (i.e ZPOOL_CONFIG_VDEV_CHILDREN). |
2113 * is aware of the complete config (i.e ZPOOL_CONFIG_VDEV_CHILDREN). |
1998 spa->spa_first_txg = spa->spa_last_ubsync_txg ? |
2137 spa->spa_first_txg = spa->spa_last_ubsync_txg ? |
1999 spa->spa_last_ubsync_txg : spa_last_synced_txg(spa) + 1; |
2138 spa->spa_last_ubsync_txg : spa_last_synced_txg(spa) + 1; |
2000 spa->spa_claim_max_txg = spa->spa_first_txg; |
2139 spa->spa_claim_max_txg = spa->spa_first_txg; |
2001 spa->spa_prev_software_version = ub->ub_software_version; |
2140 spa->spa_prev_software_version = ub->ub_software_version; |
2002 |
2141 |
2003 error = dsl_pool_open(spa, spa->spa_first_txg, &spa->spa_dsl_pool); |
2142 error = dsl_pool_init(spa, spa->spa_first_txg, &spa->spa_dsl_pool); |
2004 if (error) |
2143 if (error) |
2005 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
2144 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
2006 spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset; |
2145 spa->spa_meta_objset = spa->spa_dsl_pool->dp_meta_objset; |
2007 |
2146 |
2008 if (spa_dir_prop(spa, DMU_POOL_CONFIG, &spa->spa_config_object) != 0) |
2147 if (spa_dir_prop(spa, DMU_POOL_CONFIG, &spa->spa_config_object) != 0) |
|
2148 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
|
2149 |
|
2150 if (spa_version(spa) >= SPA_VERSION_FEATURES) { |
|
2151 boolean_t missing_feat_read = B_FALSE; |
|
2152 nvlist_t *unsup_feat; |
|
2153 |
|
2154 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ, |
|
2155 &spa->spa_feat_for_read_obj) != 0) { |
|
2156 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
|
2157 } |
|
2158 |
|
2159 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_WRITE, |
|
2160 &spa->spa_feat_for_write_obj) != 0) { |
|
2161 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
|
2162 } |
|
2163 |
|
2164 if (spa_dir_prop(spa, DMU_POOL_FEATURE_DESCRIPTIONS, |
|
2165 &spa->spa_feat_desc_obj) != 0) { |
|
2166 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
|
2167 } |
|
2168 |
|
2169 VERIFY(nvlist_alloc(&unsup_feat, NV_UNIQUE_NAME, KM_SLEEP) == |
|
2170 0); |
|
2171 |
|
2172 if (!feature_is_supported(spa->spa_meta_objset, |
|
2173 spa->spa_feat_for_read_obj, spa->spa_feat_desc_obj, |
|
2174 unsup_feat)) |
|
2175 missing_feat_read = B_TRUE; |
|
2176 |
|
2177 if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) { |
|
2178 if (!feature_is_supported(spa->spa_meta_objset, |
|
2179 spa->spa_feat_for_write_obj, spa->spa_feat_desc_obj, |
|
2180 unsup_feat)) |
|
2181 missing_feat_write = B_TRUE; |
|
2182 } |
|
2183 |
|
2184 if (!nvlist_empty(unsup_feat)) { |
|
2185 VERIFY(nvlist_add_nvlist(spa->spa_load_info, |
|
2186 ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat) == 0); |
|
2187 } |
|
2188 |
|
2189 nvlist_free(unsup_feat); |
|
2190 |
|
2191 if (!missing_feat_read) { |
|
2192 fnvlist_add_boolean(spa->spa_load_info, |
|
2193 ZPOOL_CONFIG_CAN_RDONLY); |
|
2194 } |
|
2195 |
|
2196 /* |
|
2197 * If the state is SPA_LOAD_TRYIMPORT, our objective is |
|
2198 * twofold: to determine whether the pool is available for |
|
2199 * import in read-write mode and (if it is not) whether the |
|
2200 * pool is available for import in read-only mode. If the pool |
|
2201 * is available for import in read-write mode, it is displayed |
|
2202 * as available in userland; if it is not available for import |
|
2203 * in read-only mode, it is displayed as unavailable in |
|
2204 * userland. If the pool is available for import in read-only |
|
2205 * mode but not read-write mode, it is displayed as unavailable |
|
2206 * in userland with a special note that the pool is actually |
|
2207 * available for open in read-only mode. |
|
2208 * |
|
2209 * As a result, if the state is SPA_LOAD_TRYIMPORT and we are |
|
2210 * missing a feature for write, we must first determine whether |
|
2211 * the pool can be opened read-only before returning to |
|
2212 * userland in order to know whether to display the |
|
2213 * abovementioned note. |
|
2214 */ |
|
2215 if (missing_feat_read || (missing_feat_write && |
|
2216 spa_writeable(spa))) { |
|
2217 return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT, |
|
2218 ENOTSUP)); |
|
2219 } |
|
2220 } |
|
2221 |
|
2222 spa->spa_is_initializing = B_TRUE; |
|
2223 error = dsl_pool_open(spa->spa_dsl_pool); |
|
2224 spa->spa_is_initializing = B_FALSE; |
|
2225 if (error != 0) |
2009 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
2226 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO)); |
2010 |
2227 |
2011 if (!mosconfig) { |
2228 if (!mosconfig) { |
2012 uint64_t hostid; |
2229 uint64_t hostid; |
2013 nvlist_t *policy = NULL, *nvconfig; |
2230 nvlist_t *policy = NULL, *nvconfig; |
2223 ENXIO)); |
2440 ENXIO)); |
2224 } |
2441 } |
2225 nvlist_free(nvconfig); |
2442 nvlist_free(nvconfig); |
2226 |
2443 |
2227 /* |
2444 /* |
2228 * Now that we've validate the config, check the state of the |
2445 * Now that we've validated the config, check the state of the |
2229 * root vdev. If it can't be opened, it indicates one or |
2446 * root vdev. If it can't be opened, it indicates one or |
2230 * more toplevel vdevs are faulted. |
2447 * more toplevel vdevs are faulted. |
2231 */ |
2448 */ |
2232 if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) |
2449 if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) |
2233 return (ENXIO); |
2450 return (ENXIO); |
2234 |
2451 |
2235 if (spa_check_logs(spa)) { |
2452 if (spa_check_logs(spa)) { |
2236 *ereport = FM_EREPORT_ZFS_LOG_REPLAY; |
2453 *ereport = FM_EREPORT_ZFS_LOG_REPLAY; |
2237 return (spa_vdev_err(rvd, VDEV_AUX_BAD_LOG, ENXIO)); |
2454 return (spa_vdev_err(rvd, VDEV_AUX_BAD_LOG, ENXIO)); |
2238 } |
2455 } |
|
2456 } |
|
2457 |
|
2458 if (missing_feat_write) { |
|
2459 ASSERT(state == SPA_LOAD_TRYIMPORT); |
|
2460 |
|
2461 /* |
|
2462 * At this point, we know that we can open the pool in |
|
2463 * read-only mode but not read-write mode. We now have enough |
|
2464 * information and can return to userland. |
|
2465 */ |
|
2466 return (spa_vdev_err(rvd, VDEV_AUX_UNSUP_FEAT, ENOTSUP)); |
2239 } |
2467 } |
2240 |
2468 |
2241 /* |
2469 /* |
2242 * We've successfully opened the pool, verify that we're ready |
2470 * We've successfully opened the pool, verify that we're ready |
2243 * to start pushing transactions. |
2471 * to start pushing transactions. |
2345 spa_async_suspend(spa); |
2573 spa_async_suspend(spa); |
2346 |
2574 |
2347 return (spa_load(spa, state, SPA_IMPORT_EXISTING, mosconfig)); |
2575 return (spa_load(spa, state, SPA_IMPORT_EXISTING, mosconfig)); |
2348 } |
2576 } |
2349 |
2577 |
|
2578 /* |
|
2579 * If spa_load() fails this function will try loading prior txg's. If |
|
2580 * 'state' is SPA_LOAD_RECOVER and one of these loads succeeds the pool |
|
2581 * will be rewound to that txg. If 'state' is not SPA_LOAD_RECOVER this |
|
2582 * function will not rewind the pool and will return the same error as |
|
2583 * spa_load(). |
|
2584 */ |
2350 static int |
2585 static int |
2351 spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig, |
2586 spa_load_best(spa_t *spa, spa_load_state_t state, int mosconfig, |
2352 uint64_t max_request, int rewind_flags) |
2587 uint64_t max_request, int rewind_flags) |
2353 { |
2588 { |
|
2589 nvlist_t *loadinfo = NULL; |
2354 nvlist_t *config = NULL; |
2590 nvlist_t *config = NULL; |
2355 int load_error, rewind_error; |
2591 int load_error, rewind_error; |
2356 uint64_t safe_rewind_txg; |
2592 uint64_t safe_rewind_txg; |
2357 uint64_t min_txg; |
2593 uint64_t min_txg; |
2358 |
2594 |
2377 if (rewind_flags & ZPOOL_NEVER_REWIND) { |
2613 if (rewind_flags & ZPOOL_NEVER_REWIND) { |
2378 nvlist_free(config); |
2614 nvlist_free(config); |
2379 return (load_error); |
2615 return (load_error); |
2380 } |
2616 } |
2381 |
2617 |
2382 /* Price of rolling back is discarding txgs, including log */ |
2618 if (state == SPA_LOAD_RECOVER) { |
2383 if (state == SPA_LOAD_RECOVER) |
2619 /* Price of rolling back is discarding txgs, including log */ |
2384 spa_set_log_state(spa, SPA_LOG_CLEAR); |
2620 spa_set_log_state(spa, SPA_LOG_CLEAR); |
|
2621 } else { |
|
2622 /* |
|
2623 * If we aren't rolling back save the load info from our first |
|
2624 * import attempt so that we can restore it after attempting |
|
2625 * to rewind. |
|
2626 */ |
|
2627 loadinfo = spa->spa_load_info; |
|
2628 spa->spa_load_info = fnvlist_alloc(); |
|
2629 } |
2385 |
2630 |
2386 spa->spa_load_max_txg = spa->spa_last_ubsync_txg; |
2631 spa->spa_load_max_txg = spa->spa_last_ubsync_txg; |
2387 safe_rewind_txg = spa->spa_last_ubsync_txg - TXG_DEFER_SIZE; |
2632 safe_rewind_txg = spa->spa_last_ubsync_txg - TXG_DEFER_SIZE; |
2388 min_txg = (rewind_flags & ZPOOL_EXTREME_REWIND) ? |
2633 min_txg = (rewind_flags & ZPOOL_EXTREME_REWIND) ? |
2389 TXG_INITIAL : safe_rewind_txg; |
2634 TXG_INITIAL : safe_rewind_txg; |
2673 vdev_get_stats(vd, vs); |
2931 vdev_get_stats(vd, vs); |
2674 } |
2932 } |
2675 } |
2933 } |
2676 } |
2934 } |
2677 |
2935 |
|
2936 static void |
|
2937 spa_add_feature_stats(spa_t *spa, nvlist_t *config) |
|
2938 { |
|
2939 nvlist_t *features; |
|
2940 zap_cursor_t zc; |
|
2941 zap_attribute_t za; |
|
2942 |
|
2943 ASSERT(spa_config_held(spa, SCL_CONFIG, RW_READER)); |
|
2944 VERIFY(nvlist_alloc(&features, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
|
2945 |
|
2946 if (spa->spa_feat_for_read_obj != 0) { |
|
2947 for (zap_cursor_init(&zc, spa->spa_meta_objset, |
|
2948 spa->spa_feat_for_read_obj); |
|
2949 zap_cursor_retrieve(&zc, &za) == 0; |
|
2950 zap_cursor_advance(&zc)) { |
|
2951 ASSERT(za.za_integer_length == sizeof (uint64_t) && |
|
2952 za.za_num_integers == 1); |
|
2953 VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name, |
|
2954 za.za_first_integer)); |
|
2955 } |
|
2956 zap_cursor_fini(&zc); |
|
2957 } |
|
2958 |
|
2959 if (spa->spa_feat_for_write_obj != 0) { |
|
2960 for (zap_cursor_init(&zc, spa->spa_meta_objset, |
|
2961 spa->spa_feat_for_write_obj); |
|
2962 zap_cursor_retrieve(&zc, &za) == 0; |
|
2963 zap_cursor_advance(&zc)) { |
|
2964 ASSERT(za.za_integer_length == sizeof (uint64_t) && |
|
2965 za.za_num_integers == 1); |
|
2966 VERIFY3U(0, ==, nvlist_add_uint64(features, za.za_name, |
|
2967 za.za_first_integer)); |
|
2968 } |
|
2969 zap_cursor_fini(&zc); |
|
2970 } |
|
2971 |
|
2972 VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS, |
|
2973 features) == 0); |
|
2974 nvlist_free(features); |
|
2975 } |
|
2976 |
2678 int |
2977 int |
2679 spa_get_stats(const char *name, nvlist_t **config, char *altroot, size_t buflen) |
2978 spa_get_stats(const char *name, nvlist_t **config, |
|
2979 char *altroot, size_t buflen) |
2680 { |
2980 { |
2681 int error; |
2981 int error; |
2682 spa_t *spa; |
2982 spa_t *spa; |
2683 |
2983 |
2684 *config = NULL; |
2984 *config = NULL; |
2954 spa_remove(spa); |
3256 spa_remove(spa); |
2955 mutex_exit(&spa_namespace_lock); |
3257 mutex_exit(&spa_namespace_lock); |
2956 return (error); |
3258 return (error); |
2957 } |
3259 } |
2958 |
3260 |
2959 if (nvlist_lookup_uint64(props, zpool_prop_to_name(ZPOOL_PROP_VERSION), |
3261 has_features = B_FALSE; |
2960 &version) != 0) |
3262 for (nvpair_t *elem = nvlist_next_nvpair(props, NULL); |
|
3263 elem != NULL; elem = nvlist_next_nvpair(props, elem)) { |
|
3264 if (zpool_prop_feature(nvpair_name(elem))) |
|
3265 has_features = B_TRUE; |
|
3266 } |
|
3267 |
|
3268 if (has_features || nvlist_lookup_uint64(props, |
|
3269 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version) != 0) { |
2961 version = SPA_VERSION; |
3270 version = SPA_VERSION; |
2962 ASSERT(version <= SPA_VERSION); |
3271 } |
|
3272 ASSERT(SPA_VERSION_IS_SUPPORTED(version)); |
2963 |
3273 |
2964 spa->spa_first_txg = txg; |
3274 spa->spa_first_txg = txg; |
2965 spa->spa_uberblock.ub_txg = txg - 1; |
3275 spa->spa_uberblock.ub_txg = txg - 1; |
2966 spa->spa_uberblock.ub_version = version; |
3276 spa->spa_uberblock.ub_version = version; |
2967 spa->spa_ubsync = spa->spa_uberblock; |
3277 spa->spa_ubsync = spa->spa_uberblock; |
3057 if (zap_add(spa->spa_meta_objset, |
3369 if (zap_add(spa->spa_meta_objset, |
3058 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG, |
3370 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CONFIG, |
3059 sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) { |
3371 sizeof (uint64_t), 1, &spa->spa_config_object, tx) != 0) { |
3060 cmn_err(CE_PANIC, "failed to add pool config"); |
3372 cmn_err(CE_PANIC, "failed to add pool config"); |
3061 } |
3373 } |
|
3374 |
|
3375 if (spa_version(spa) >= SPA_VERSION_FEATURES) |
|
3376 spa_feature_create_zap_objects(spa, tx); |
3062 |
3377 |
3063 if (zap_add(spa->spa_meta_objset, |
3378 if (zap_add(spa->spa_meta_objset, |
3064 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION, |
3379 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_CREATION_VERSION, |
3065 sizeof (uint64_t), 1, &version, tx) != 0) { |
3380 sizeof (uint64_t), 1, &version, tx) != 0) { |
3066 cmn_err(CE_PANIC, "failed to add pool version"); |
3381 cmn_err(CE_PANIC, "failed to add pool version"); |
5279 /* |
5596 /* |
5280 * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration |
5597 * Write full (SPA_CONFIG_BLOCKSIZE) blocks of configuration |
5281 * information. This avoids the dbuf_will_dirty() path and |
5598 * information. This avoids the dbuf_will_dirty() path and |
5282 * saves us a pre-read to get data we don't actually care about. |
5599 * saves us a pre-read to get data we don't actually care about. |
5283 */ |
5600 */ |
5284 bufsize = P2ROUNDUP(nvsize, SPA_CONFIG_BLOCKSIZE); |
5601 bufsize = P2ROUNDUP((uint64_t)nvsize, SPA_CONFIG_BLOCKSIZE); |
5285 packed = kmem_alloc(bufsize, KM_SLEEP); |
5602 packed = kmem_alloc(bufsize, KM_SLEEP); |
5286 |
5603 |
5287 VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR, |
5604 VERIFY(nvlist_pack(nv, &packed, &nvsize, NV_ENCODE_XDR, |
5288 KM_SLEEP) == 0); |
5605 KM_SLEEP) == 0); |
5289 bzero(packed + nvsize, bufsize - nvsize); |
5606 bzero(packed + nvsize, bufsize - nvsize); |
5364 spa->spa_config_syncing = config; |
5681 spa->spa_config_syncing = config; |
5365 |
5682 |
5366 spa_sync_nvlist(spa, spa->spa_config_object, config, tx); |
5683 spa_sync_nvlist(spa, spa->spa_config_object, config, tx); |
5367 } |
5684 } |
5368 |
5685 |
|
5686 static void |
|
5687 spa_sync_version(void *arg1, void *arg2, dmu_tx_t *tx) |
|
5688 { |
|
5689 spa_t *spa = arg1; |
|
5690 uint64_t version = *(uint64_t *)arg2; |
|
5691 |
|
5692 /* |
|
5693 * Setting the version is special cased when first creating the pool. |
|
5694 */ |
|
5695 ASSERT(tx->tx_txg != TXG_INITIAL); |
|
5696 |
|
5697 ASSERT(version <= SPA_VERSION); |
|
5698 ASSERT(version >= spa_version(spa)); |
|
5699 |
|
5700 spa->spa_uberblock.ub_version = version; |
|
5701 vdev_config_dirty(spa->spa_root_vdev); |
|
5702 } |
|
5703 |
5369 /* |
5704 /* |
5370 * Set zpool properties. |
5705 * Set zpool properties. |
5371 */ |
5706 */ |
5372 static void |
5707 static void |
5373 spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx) |
5708 spa_sync_props(void *arg1, void *arg2, dmu_tx_t *tx) |
5374 { |
5709 { |
5375 spa_t *spa = arg1; |
5710 spa_t *spa = arg1; |
5376 objset_t *mos = spa->spa_meta_objset; |
5711 objset_t *mos = spa->spa_meta_objset; |
5377 nvlist_t *nvp = arg2; |
5712 nvlist_t *nvp = arg2; |
5378 nvpair_t *elem; |
5713 nvpair_t *elem = NULL; |
5379 uint64_t intval; |
|
5380 char *strval; |
|
5381 zpool_prop_t prop; |
|
5382 const char *propname; |
|
5383 zprop_type_t proptype; |
|
5384 |
5714 |
5385 mutex_enter(&spa->spa_props_lock); |
5715 mutex_enter(&spa->spa_props_lock); |
5386 |
5716 |
5387 elem = NULL; |
|
5388 while ((elem = nvlist_next_nvpair(nvp, elem))) { |
5717 while ((elem = nvlist_next_nvpair(nvp, elem))) { |
|
5718 uint64_t intval; |
|
5719 char *strval, *fname; |
|
5720 zpool_prop_t prop; |
|
5721 const char *propname; |
|
5722 zprop_type_t proptype; |
|
5723 zfeature_info_t *feature; |
|
5724 |
5389 switch (prop = zpool_name_to_prop(nvpair_name(elem))) { |
5725 switch (prop = zpool_name_to_prop(nvpair_name(elem))) { |
|
5726 case ZPROP_INVAL: |
|
5727 /* |
|
5728 * We checked this earlier in spa_prop_validate(). |
|
5729 */ |
|
5730 ASSERT(zpool_prop_feature(nvpair_name(elem))); |
|
5731 |
|
5732 fname = strchr(nvpair_name(elem), '@') + 1; |
|
5733 VERIFY3U(0, ==, zfeature_lookup_name(fname, &feature)); |
|
5734 |
|
5735 spa_feature_enable(spa, feature, tx); |
|
5736 break; |
|
5737 |
5390 case ZPOOL_PROP_VERSION: |
5738 case ZPOOL_PROP_VERSION: |
|
5739 VERIFY(nvpair_value_uint64(elem, &intval) == 0); |
5391 /* |
5740 /* |
5392 * Only set version for non-zpool-creation cases |
5741 * The version is synced seperatly before other |
5393 * (set/import). spa_create() needs special care |
5742 * properties and should be correct by now. |
5394 * for version setting. |
|
5395 */ |
5743 */ |
5396 if (tx->tx_txg != TXG_INITIAL) { |
5744 ASSERT3U(spa_version(spa), >=, intval); |
5397 VERIFY(nvpair_value_uint64(elem, |
|
5398 &intval) == 0); |
|
5399 ASSERT(intval <= SPA_VERSION); |
|
5400 ASSERT(intval >= spa_version(spa)); |
|
5401 spa->spa_uberblock.ub_version = intval; |
|
5402 vdev_config_dirty(spa->spa_root_vdev); |
|
5403 } |
|
5404 break; |
5745 break; |
5405 |
5746 |
5406 case ZPOOL_PROP_ALTROOT: |
5747 case ZPOOL_PROP_ALTROOT: |
5407 /* |
5748 /* |
5408 * 'altroot' is a non-persistent property. It should |
5749 * 'altroot' is a non-persistent property. It should |
5435 default: |
5776 default: |
5436 /* |
5777 /* |
5437 * Set pool property values in the poolprops mos object. |
5778 * Set pool property values in the poolprops mos object. |
5438 */ |
5779 */ |
5439 if (spa->spa_pool_props_object == 0) { |
5780 if (spa->spa_pool_props_object == 0) { |
5440 VERIFY((spa->spa_pool_props_object = |
5781 spa->spa_pool_props_object = |
5441 zap_create(mos, DMU_OT_POOL_PROPS, |
5782 zap_create_link(mos, DMU_OT_POOL_PROPS, |
5442 DMU_OT_NONE, 0, tx)) > 0); |
|
5443 |
|
5444 VERIFY(zap_update(mos, |
|
5445 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS, |
5783 DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_PROPS, |
5446 8, 1, &spa->spa_pool_props_object, tx) |
5784 tx); |
5447 == 0); |
|
5448 } |
5785 } |
5449 |
5786 |
5450 /* normalize the property name */ |
5787 /* normalize the property name */ |
5451 propname = zpool_prop_to_name(prop); |
5788 propname = zpool_prop_to_name(prop); |
5452 proptype = zpool_prop_get_type(prop); |
5789 proptype = zpool_prop_get_type(prop); |