diff options
author | smh <smh@FreeBSD.org> | 2015-02-01 12:39:40 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2015-02-01 12:39:40 +0000 |
commit | ee75a2f04f6b325aa725e77f7b9f0f006006cd87 (patch) | |
tree | 06bd1d947146f145e397c80a0a315038571437a4 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | |
parent | 9de77a522dbdc779b4a6390c0cf65cc0d76be26f (diff) | |
download | FreeBSD-src-ee75a2f04f6b325aa725e77f7b9f0f006006cd87.zip FreeBSD-src-ee75a2f04f6b325aa725e77f7b9f0f006006cd87.tar.gz |
MFC r276123:
Always sync the global ZFS config cache to reflect the new mosconfig
MFC r277351:
Clean ZFS spa config before syncing
Sponsored by: Multiplay
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index 2d0cf23..be1e528 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -140,6 +140,26 @@ out: kobj_close_file(file); } +static void +spa_config_clean(nvlist_t *nvl) +{ + nvlist_t **child; + nvlist_t *nvroot = NULL; + uint_t c, children; + + if (nvlist_lookup_nvlist_array(nvl, ZPOOL_CONFIG_CHILDREN, &child, + &children) == 0) { + for (c = 0; c < children; c++) + spa_config_clean(child[c]); + } + + if (nvlist_lookup_nvlist(nvl, ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0) + spa_config_clean(nvroot); + + nvlist_remove(nvl, ZPOOL_CONFIG_VDEV_STATS, DATA_TYPE_UINT64_ARRAY); + nvlist_remove(nvl, ZPOOL_CONFIG_SCAN_STATS, DATA_TYPE_UINT64_ARRAY); +} + static int spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl) { @@ -233,6 +253,7 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) */ nvl = NULL; while ((spa = spa_next(spa)) != NULL) { + nvlist_t *nvroot = NULL; /* * Skip over our own pool if we're about to remove * ourselves from the spa namespace or any pool that @@ -241,7 +262,8 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) * we don't allow them to be written to the cache file. */ if ((spa == target && removing) || - !spa_writeable(spa)) + (spa_state(spa) == POOL_STATE_ACTIVE && + !spa_writeable(spa))) continue; mutex_enter(&spa->spa_props_lock); @@ -260,6 +282,9 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent) VERIFY(nvlist_add_nvlist(nvl, spa->spa_name, spa->spa_config) == 0); mutex_exit(&spa->spa_props_lock); + + if (nvlist_lookup_nvlist(nvl, spa->spa_name, &nvroot) == 0) + spa_config_clean(nvroot); } error = spa_config_write(dp, nvl); @@ -536,8 +561,7 @@ spa_config_update(spa_t *spa, int what) /* * Update the global config cache to reflect the new mosconfig. */ - if (!spa->spa_is_root) - spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); + spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS); |