summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2012-11-18 11:47:25 +0000
committeravg <avg@FreeBSD.org>2012-11-18 11:47:25 +0000
commitc635b275d13c0e5c2e01c33eb5aba69efd28e9e8 (patch)
tree54d35d89a301da5e76777ec9dd4aa33245ebb6ef /sys/cddl
parenta65c6ba8dc4fe539c84c459e98c5c1ff37462b61 (diff)
downloadFreeBSD-src-c635b275d13c0e5c2e01c33eb5aba69efd28e9e8.zip
FreeBSD-src-c635b275d13c0e5c2e01c33eb5aba69efd28e9e8.tar.gz
spa_import_rootpool: fall back to use configuration from zpool.cache...
if we fail to generate a proper root pool configuration based on disk probing. Currently we can not properly generate the configuration for multi-vdev pools. Make that explicit. Reported by: madpilot, Bartosz Stec <bartosz.stec@it4pro.pl> Tested by: madpilot, Bartosz Stec <bartosz.stec@it4pro.pl> MFC after: 4 days
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index 7a2e657..94b25d4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -3763,12 +3763,23 @@ spa_generate_rootconf(const char *name)
{
nvlist_t *config;
nvlist_t *nvtop, *nvroot;
+ uint64_t nchildren;
uint64_t pgid;
if (vdev_geom_read_pool_label(name, &config) != 0)
return (NULL);
/*
+ * Multi-vdev root pool configuration discovery is not supported yet.
+ */
+ nchildren = 0;
+ nvlist_lookup_uint64(config, ZPOOL_CONFIG_VDEV_CHILDREN, &nchildren);
+ if (nchildren != 1) {
+ nvlist_free(config);
+ return (NULL);
+ }
+
+ /*
* Add this top-level vdev to the child array.
*/
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
@@ -3810,25 +3821,30 @@ spa_import_rootpool(const char *name)
* Read the label from the boot device and generate a configuration.
*/
config = spa_generate_rootconf(name);
- if (config == NULL) {
+
+ mutex_enter(&spa_namespace_lock);
+ if (config != NULL) {
+ VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
+ &pname) == 0 && strcmp(name, pname) == 0);
+ VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg)
+ == 0);
+
+ if ((spa = spa_lookup(pname)) != NULL) {
+ /*
+ * Remove the existing root pool from the namespace so
+ * that we can replace it with the correct config
+ * we just read in.
+ */
+ spa_remove(spa);
+ }
+ spa = spa_add(pname, config, NULL);
+ } else if ((spa = spa_lookup(name)) == NULL) {
cmn_err(CE_NOTE, "Cannot find the pool label for '%s'",
name);
return (EIO);
+ } else {
+ VERIFY(nvlist_dup(spa->spa_config, &config, KM_SLEEP) == 0);
}
-
- VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
- &pname) == 0 && strcmp(name, pname) == 0);
- VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) == 0);
-
- mutex_enter(&spa_namespace_lock);
- if ((spa = spa_lookup(pname)) != NULL) {
- /*
- * Remove the existing root pool from the namespace so that we
- * can replace it with the correct config we just read in.
- */
- spa_remove(spa);
- }
- spa = spa_add(pname, config, NULL);
spa->spa_is_root = B_TRUE;
spa->spa_import_flags = ZFS_IMPORT_VERBATIM;
@@ -3849,15 +3865,15 @@ spa_import_rootpool(const char *name)
return (error);
}
- error = 0;
spa_history_log_version(spa, LOG_POOL_IMPORT);
-out:
+
spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
vdev_free(rvd);
spa_config_exit(spa, SCL_ALL, FTAG);
mutex_exit(&spa_namespace_lock);
- return (error);
+ nvlist_free(config);
+ return (0);
}
#endif /* sun */
OpenPOWER on IntegriCloud