Deleted Added
full compact
3553d3552
< #if defined(sun)
3554a3554
> #if defined(sun)
3756c3756,3862
< #endif
---
> #else
>
> extern int
> vdev_geom_read_pool_label(const char *name, nvlist_t **config);
>
> static nvlist_t *
> spa_generate_rootconf(const char *name)
> {
> nvlist_t *config;
> nvlist_t *nvtop, *nvroot;
> uint64_t pgid;
>
> if (vdev_geom_read_pool_label(name, &config) != 0)
> return (NULL);
>
> /*
> * Add this top-level vdev to the child array.
> */
> VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
> &nvtop) == 0);
> VERIFY(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
> &pgid) == 0);
>
> /*
> * Put this pool's top-level vdevs into a root vdev.
> */
> VERIFY(nvlist_alloc(&nvroot, NV_UNIQUE_NAME, KM_SLEEP) == 0);
> VERIFY(nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
> VDEV_TYPE_ROOT) == 0);
> VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) == 0);
> VERIFY(nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, pgid) == 0);
> VERIFY(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
> &nvtop, 1) == 0);
>
> /*
> * Replace the existing vdev_tree with the new root vdev in
> * this pool's configuration (remove the old, add the new).
> */
> VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0);
> nvlist_free(nvroot);
> return (config);
> }
>
> int
> spa_import_rootpool(const char *name)
> {
> spa_t *spa;
> vdev_t *rvd, *bvd, *avd = NULL;
> nvlist_t *config, *nvtop;
> uint64_t txg;
> char *pname;
> int error;
>
> /*
> * Read the label from the boot device and generate a configuration.
> */
> config = spa_generate_rootconf(name);
> if (config == NULL) {
> cmn_err(CE_NOTE, "Cannot find the pool label for '%s'",
> name);
> return (EIO);
> }
>
> 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;
>
> /*
> * Build up a vdev tree based on the boot device's label config.
> */
> VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
> &nvtop) == 0);
> spa_config_enter(spa, SCL_ALL, FTAG, RW_WRITER);
> error = spa_config_parse(spa, &rvd, nvtop, NULL, 0,
> VDEV_ALLOC_ROOTPOOL);
> spa_config_exit(spa, SCL_ALL, FTAG);
> if (error) {
> mutex_exit(&spa_namespace_lock);
> nvlist_free(config);
> cmn_err(CE_NOTE, "Can not parse the config for pool '%s'",
> pname);
> 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);
> }
>
3757a3864
> #endif