--- old/usr/src/uts/common/fs/zfs/spa_config.c	Mon Aug  5 17:26:54 2019
+++ new/usr/src/uts/common/fs/zfs/spa_config.c	Mon Aug  5 17:26:54 2019
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  * Copyright 2017 Joyent, Inc.
  */
@@ -56,7 +56,7 @@
  * configuration information.  When the module loads, we read this information
  * from /etc/zfs/zpool.cache and populate the SPA namespace.  This namespace is
  * maintained independently in spa.c.  Whenever the namespace is modified, or
- * the configuration of a pool is changed, we call spa_write_cachefile(), which
+ * the configuration of a pool is changed, we call spa_config_sync(), which
  * walks through all the active pools and writes the configuration to disk.
  */
 
@@ -122,13 +122,20 @@
 	mutex_enter(&spa_namespace_lock);
 	nvpair = NULL;
 	while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) {
+		uint64_t guid = 0;
+
 		if (nvpair_type(nvpair) != DATA_TYPE_NVLIST)
 			continue;
 
 		child = fnvpair_value_nvlist(nvpair);
+		/* a zero guid means we simply will ignore the check later */
+		(void) nvlist_lookup_uint64(child, ZPOOL_CONFIG_POOL_GUID,
+		    &guid);
 
-		if (spa_lookup(nvpair_name(nvpair)) != NULL)
+		if (spa_lookup(nvpair_name(nvpair)) != NULL ||
+		    spa_config_guid_exists(guid)) {
 			continue;
+		}
 		(void) spa_add(nvpair_name(nvpair), child, NULL);
 	}
 	mutex_exit(&spa_namespace_lock);
@@ -198,11 +205,11 @@
  * the configuration has been synced to the MOS. This exposes a window where
  * the MOS config will have been updated but the cache file has not. If
  * the system were to crash at that instant then the cached config may not
- * contain the correct information to open the pool and an explicit import
+ * contain the correct information to open the pool and an explicity import
  * would be required.
  */
 void
-spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent)
+spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
 {
 	spa_config_dirent_t *dp, *tdp;
 	nvlist_t *nvl;
@@ -339,8 +346,7 @@
 spa_config_set(spa_t *spa, nvlist_t *config)
 {
 	mutex_enter(&spa->spa_props_lock);
-	if (spa->spa_config != NULL && spa->spa_config != config)
-		nvlist_free(spa->spa_config);
+	nvlist_free(spa->spa_config);
 	spa->spa_config = config;
 	mutex_exit(&spa->spa_props_lock);
 }
@@ -387,8 +393,15 @@
 		    spa->spa_comment);
 	}
 
+#ifdef	_KERNEL
 	hostid = zone_get_hostid(NULL);
-
+#else	/* _KERNEL */
+	/*
+	 * We're emulating the system's hostid in userland, so we can't use
+	 * zone_get_hostid().
+	 */
+	(void) ddi_strtoul(hw_serial, NULL, 10, &hostid);
+#endif	/* _KERNEL */
 	if (hostid != 0) {
 		fnvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid);
 	}
@@ -404,6 +417,9 @@
 			fnvlist_add_uint64(config,
 			    ZPOOL_CONFIG_IS_SPARE, 1ULL);
 		}
+		if (vd->vdev_isspecial)
+			fnvlist_add_uint64(config,
+			    ZPOOL_CONFIG_IS_SPECIAL, 1ULL);
 		if (vd->vdev_islog) {
 			fnvlist_add_uint64(config,
 			    ZPOOL_CONFIG_IS_LOG, 1ULL);
@@ -443,6 +459,19 @@
 	fnvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot);
 	nvlist_free(nvroot);
 
+	/* If we're getting stats, calculate trim progress from leaf vdevs. */
+	if (getstats) {
+		uint64_t prog, rate, start_time, stop_time;
+
+		spa_get_trim_prog(spa, &prog, &rate, &start_time, &stop_time);
+		fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_PROG, prog);
+		fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_RATE, rate);
+		fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_START_TIME,
+		    start_time);
+		fnvlist_add_uint64(config, ZPOOL_CONFIG_TRIM_STOP_TIME,
+		    stop_time);
+	}
+
 	/*
 	 * Store what's necessary for reading the MOS in the label.
 	 */
@@ -525,10 +554,8 @@
 	/*
 	 * Update the global config cache to reflect the new mosconfig.
 	 */
-	if (!spa->spa_is_root) {
-		spa_write_cachefile(spa, B_FALSE,
-		    what != SPA_CONFIG_UPDATE_POOL);
-	}
+	if (!spa->spa_is_root)
+		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);
