2283 nvlist_t *unsup_feat, *enabled_feat;
2284
2285 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
2286 &spa->spa_feat_for_read_obj) != 0) {
2287 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2288 }
2289
2290 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_WRITE,
2291 &spa->spa_feat_for_write_obj) != 0) {
2292 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2293 }
2294
2295 if (spa_dir_prop(spa, DMU_POOL_FEATURE_DESCRIPTIONS,
2296 &spa->spa_feat_desc_obj) != 0) {
2297 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2298 }
2299
2300 enabled_feat = fnvlist_alloc();
2301 unsup_feat = fnvlist_alloc();
2302
2303 if (!feature_is_supported(spa->spa_meta_objset,
2304 spa->spa_feat_for_read_obj, spa->spa_feat_desc_obj,
2305 unsup_feat, enabled_feat))
2306 missing_feat_read = B_TRUE;
2307
2308 if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) {
2309 if (!feature_is_supported(spa->spa_meta_objset,
2310 spa->spa_feat_for_write_obj, spa->spa_feat_desc_obj,
2311 unsup_feat, enabled_feat)) {
2312 missing_feat_write = B_TRUE;
2313 }
2314 }
2315
2316 fnvlist_add_nvlist(spa->spa_load_info,
2317 ZPOOL_CONFIG_ENABLED_FEAT, enabled_feat);
2318
2319 if (!nvlist_empty(unsup_feat)) {
2320 fnvlist_add_nvlist(spa->spa_load_info,
2321 ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat);
2322 }
2323
2324 fnvlist_free(enabled_feat);
2325 fnvlist_free(unsup_feat);
2326
2327 if (!missing_feat_read) {
2328 fnvlist_add_boolean(spa->spa_load_info,
2329 ZPOOL_CONFIG_CAN_RDONLY);
2330 }
5897
5898 /*
5899 * Set zpool properties.
5900 */
5901 static void
5902 spa_sync_props(void *arg, dmu_tx_t *tx)
5903 {
5904 nvlist_t *nvp = arg;
5905 spa_t *spa = dmu_tx_pool(tx)->dp_spa;
5906 objset_t *mos = spa->spa_meta_objset;
5907 nvpair_t *elem = NULL;
5908
5909 mutex_enter(&spa->spa_props_lock);
5910
5911 while ((elem = nvlist_next_nvpair(nvp, elem))) {
5912 uint64_t intval;
5913 char *strval, *fname;
5914 zpool_prop_t prop;
5915 const char *propname;
5916 zprop_type_t proptype;
5917 zfeature_info_t *feature;
5918
5919 switch (prop = zpool_name_to_prop(nvpair_name(elem))) {
5920 case ZPROP_INVAL:
5921 /*
5922 * We checked this earlier in spa_prop_validate().
5923 */
5924 ASSERT(zpool_prop_feature(nvpair_name(elem)));
5925
5926 fname = strchr(nvpair_name(elem), '@') + 1;
5927 VERIFY0(zfeature_lookup_name(fname, &feature));
5928
5929 spa_feature_enable(spa, feature, tx);
5930 spa_history_log_internal(spa, "set", tx,
5931 "%s=enabled", nvpair_name(elem));
5932 break;
5933
5934 case ZPOOL_PROP_VERSION:
5935 intval = fnvpair_value_uint64(elem);
5936 /*
5937 * The version is synced seperatly before other
5938 * properties and should be correct by now.
5939 */
5940 ASSERT3U(spa_version(spa), >=, intval);
5941 break;
5942
5943 case ZPOOL_PROP_ALTROOT:
5944 /*
5945 * 'altroot' is a non-persistent property. It should
5946 * have been set temporarily at creation or import time.
5947 */
5948 ASSERT(spa->spa_root != NULL);
5949 break;
|
2283 nvlist_t *unsup_feat, *enabled_feat;
2284
2285 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_READ,
2286 &spa->spa_feat_for_read_obj) != 0) {
2287 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2288 }
2289
2290 if (spa_dir_prop(spa, DMU_POOL_FEATURES_FOR_WRITE,
2291 &spa->spa_feat_for_write_obj) != 0) {
2292 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2293 }
2294
2295 if (spa_dir_prop(spa, DMU_POOL_FEATURE_DESCRIPTIONS,
2296 &spa->spa_feat_desc_obj) != 0) {
2297 return (spa_vdev_err(rvd, VDEV_AUX_CORRUPT_DATA, EIO));
2298 }
2299
2300 enabled_feat = fnvlist_alloc();
2301 unsup_feat = fnvlist_alloc();
2302
2303 if (!spa_features_check(spa, B_FALSE,
2304 unsup_feat, enabled_feat))
2305 missing_feat_read = B_TRUE;
2306
2307 if (spa_writeable(spa) || state == SPA_LOAD_TRYIMPORT) {
2308 if (!spa_features_check(spa, B_TRUE,
2309 unsup_feat, enabled_feat)) {
2310 missing_feat_write = B_TRUE;
2311 }
2312 }
2313
2314 fnvlist_add_nvlist(spa->spa_load_info,
2315 ZPOOL_CONFIG_ENABLED_FEAT, enabled_feat);
2316
2317 if (!nvlist_empty(unsup_feat)) {
2318 fnvlist_add_nvlist(spa->spa_load_info,
2319 ZPOOL_CONFIG_UNSUP_FEAT, unsup_feat);
2320 }
2321
2322 fnvlist_free(enabled_feat);
2323 fnvlist_free(unsup_feat);
2324
2325 if (!missing_feat_read) {
2326 fnvlist_add_boolean(spa->spa_load_info,
2327 ZPOOL_CONFIG_CAN_RDONLY);
2328 }
5895
5896 /*
5897 * Set zpool properties.
5898 */
5899 static void
5900 spa_sync_props(void *arg, dmu_tx_t *tx)
5901 {
5902 nvlist_t *nvp = arg;
5903 spa_t *spa = dmu_tx_pool(tx)->dp_spa;
5904 objset_t *mos = spa->spa_meta_objset;
5905 nvpair_t *elem = NULL;
5906
5907 mutex_enter(&spa->spa_props_lock);
5908
5909 while ((elem = nvlist_next_nvpair(nvp, elem))) {
5910 uint64_t intval;
5911 char *strval, *fname;
5912 zpool_prop_t prop;
5913 const char *propname;
5914 zprop_type_t proptype;
5915 spa_feature_t fid;
5916
5917 switch (prop = zpool_name_to_prop(nvpair_name(elem))) {
5918 case ZPROP_INVAL:
5919 /*
5920 * We checked this earlier in spa_prop_validate().
5921 */
5922 ASSERT(zpool_prop_feature(nvpair_name(elem)));
5923
5924 fname = strchr(nvpair_name(elem), '@') + 1;
5925 VERIFY0(zfeature_lookup_name(fname, &fid));
5926
5927 spa_feature_enable(spa, fid, tx);
5928 spa_history_log_internal(spa, "set", tx,
5929 "%s=enabled", nvpair_name(elem));
5930 break;
5931
5932 case ZPOOL_PROP_VERSION:
5933 intval = fnvpair_value_uint64(elem);
5934 /*
5935 * The version is synced seperatly before other
5936 * properties and should be correct by now.
5937 */
5938 ASSERT3U(spa_version(spa), >=, intval);
5939 break;
5940
5941 case ZPOOL_PROP_ALTROOT:
5942 /*
5943 * 'altroot' is a non-persistent property. It should
5944 * have been set temporarily at creation or import time.
5945 */
5946 ASSERT(spa->spa_root != NULL);
5947 break;
|