spa_config.c revision fa9e4066f08beec538e775443c5be79dd423fcab
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 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>
/*
* Pool configuration repository.
*
* The configuration for all pools, in addition to being stored on disk, is
* stored in /kernel/drv/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.
*/
rootdir) != 0)
return;
/*
* Read the nvlist from the file.
*/
goto out;
goto out;
if (resid != 0)
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.
*/
/*
* 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 /kernel/drv/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 is any other non-zero value, update spa->spa_config_txg.
*/
if (txg == -1ULL)
UBERBLOCK_VERSION) == 0);
txg) == 0);
}
return (config);
}