Author: smh
Date: Sun Jan 18 23:15:49 2015
New Revision: 277351
URL: https://svnweb.freebsd.org/changeset/base/277351

Log:
  Clean ZFS spa config before syncing
  
  A number of entries that can be present in the spa config shouldn't be saved
  to disk so add a method to ensure this is case. Without this if the last
  caller to vdev_config_generate requested stats then we can end up in the
  cache file.
  
  Also only skip a none writable pool in the cache file generation if its
  active. This prevents unavailable pools incorrectly getting removed from
  cache file.
  
  Tested by:    delphij
  MFC after:    2 weeks
  Sponsored by: Multiplay

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c    Sun Jan 
18 22:00:39 2015        (r277350)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c    Sun Jan 
18 23:15:49 2015        (r277351)
@@ -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
                 */
                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
                         * 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
                        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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to