spa_config.c revision eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/spa_impl.h>
#include <sys/vdev_impl.h>
#include <sys/zfs_ioctl.h>
#ifdef _KERNEL
#endif
/*
* Pool configuration repository.
*
* The configuration for all pools, in addition to being stored on disk, is
* stored in /etc/zfs/zpool.cache as a packed nvlist. The kernel maintains
* this list as pools are created, destroyed, or modified.
*
* We have a single nvlist which holds all the configuration information. When
* the module loads, we read this information from the 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_config_sync(), which walks through all the active pools
* and writes the configuration to disk.
*/
/*
* This can be overridden in userland to preserve an alternate namespace for
* userland pools when doing testing.
*/
const char *spa_config_dir = ZPOOL_CACHE_DIR;
/*
* Called when the module is first loaded, this routine loads the configuration
* file into the SPA namespace. It does not actually open or load the pools; it
* only populates the namespace.
*/
void
spa_config_load(void)
{
char pathname[128];
/*
* Open the configuration file.
*/
return;
goto out;
/*
* Read the nvlist from the file.
*/
goto out;
/*
* Unpack the nvlist.
*/
goto out;
/*
* Iterate over all elements in the nvlist, creating a new spa_t for
* each one with the specified configuration.
*/
continue;
continue;
/*
* We blindly duplicate the configuration here. If it's
* invalid, we will catch it when the pool is first opened.
*/
}
out:
}
/*
* Synchronize all pools to disk. This must be called with the namespace lock
* held.
*/
void
spa_config_sync(void)
{
char *buf;
char pathname[128];
char pathname2[128];
/*
* Add all known pools to the configuration list, ignoring those with
* alternate root paths.
*/
spa->spa_config) == 0);
}
/*
* Pack the configuration into a buffer.
*/
KM_SLEEP) == 0);
/*
* Write the configuration to disk. We need to do the traditional
* 'write to temporary file, sync, move over original' to make sure we
* always have a consistent view of the data.
*/
goto out;
}
out:
}
/*
* Sigh. Inside a local zone, we don't have access to /etc/zfs/zpool.cache,
* and we don't want to allow the local zone to see all the pools anyway.
* So we have to invent the ZFS_IOC_CONFIG ioctl to grab the configuration
* information for all pool visible within the zone.
*/
nvlist_t *
{
if (*generation == spa_config_generation)
return (NULL);
if (INGLOBALZONE(curproc) ||
spa->spa_config) == 0);
}
}
return (pools);
}
void
{
}
/*
* Generate the pool's configuration based on the current in-core state.
* We infer whether to generate a complete config or just one top-level config
* based on whether vd is the root vdev.
*/
nvlist_t *
{
/*
* If txg is -1, report the current value of spa->spa_config_txg.
*/
if (txg == -1ULL)
txg) == 0);
}
return (config);
}
/*
* Update all disk labels, generate a fresh config based on the current
* in-core state, and sync the global config cache.
*/
void
{
int c;
if (what == SPA_CONFIG_UPDATE_POOL) {
} else {
/*
* If we have top-level vdevs that were added but have
* not yet been prepared for allocation, do that now.
* (It's safe now because the config cache is up to date,
* so it will be able to translate the new DVAs.)
* See comments in spa_vdev_add() for full details.
*/
for (c = 0; c < rvd->vdev_children; c++) {
if (tvd->vdev_ms_array == 0) {
}
}
}
/*
* Wait for the mosconfig to be regenerated and synced.
*/
/*
* Update the global config cache to reflect the new mosconfig.
*/
if (what == SPA_CONFIG_UPDATE_POOL)
}