libzfs_config.c revision e9dbad6f263d5570ed7ff5443ec5b958af8c24d7
/*
* 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"
/*
* The pool configuration repository is stored in /etc/zfs/zpool.cache as a
* single packed nvlist. While it would be nice to just read in this
* file from userland, this wouldn't work from a local zone. So we have to have
* a zpool ioctl to return the complete configuration for all pools. In the
* global zone, this will be identical to reading the file and unpacking it in
* userland.
*/
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include <libuutil.h>
#include "libzfs_impl.h"
typedef struct config_node {
char *cn_name;
/* ARGSUSED */
static int
config_node_compare(const void *a, const void *b, void *unused)
{
int ret;
if (ret < 0)
return (-1);
else if (ret > 0)
return (1);
else
return (0);
}
void
{
if (hdl->libzfs_ns_avl) {
UU_WALK_ROBUST)) == NULL)
return;
}
}
if (hdl->libzfs_ns_avlpool) {
}
}
/*
* Loads the pool namespace, or re-loads it if the cache has changed.
*/
static int
{
if (hdl->libzfs_ns_gen == 0) {
/*
* This is the first time we've accessed the configuration
* cache. Initialize the AVL tree and then fall through to the
* common code.
*/
sizeof (config_node_t),
}
return (-1);
for (;;) {
switch (errno) {
case EEXIST:
/*
* The namespace hasn't changed.
*/
return (0);
case ENOMEM:
return (-1);
}
break;
default:
"pool configuration")));
}
} else {
break;
}
}
return (-1);
}
/*
* Clear out any existing configuration information.
*/
UU_WALK_ROBUST)) == NULL) {
}
}
return (-1);
}
return (-1);
}
}
== NULL);
}
return (0);
}
/*
* Retrive the configuration for the given pool. The configuration is a nvlist
* describing the vdevs, as well as the statistics associated with each one.
*/
nvlist_t *
{
if (oldconfig)
return (zhp->zpool_config);
}
/*
* Refresh the vdev statistics associated with the given pool. This is used in
* iostat to show configuration changes and determine the delta from the last
* time the function was called. This function can fail, in case the pool has
* been destroyed.
*/
int
{
int error;
if (zhp->zpool_config_size == 0)
return (-1);
for (;;) {
&zc) == 0) {
/*
* The real error is returned in the zc_cookie field.
*/
break;
}
return (-1);
}
} else {
return (0);
}
}
return (-1);
}
if (set_pool_health(config) != 0) {
}
ZPOOL_CONFIG_POOL_TXG, &oldtxg) == 0);
ZPOOL_CONFIG_POOL_TXG, &newtxg) == 0);
} else {
}
}
if (error)
else
return (0);
}
/*
* Iterate over all pools in the system.
*/
int
{
int ret;
if (namespace_reload(hdl) != 0)
return (-1);
return (-1);
continue;
return (ret);
}
return (0);
}
/*
* Iterate over root datasets, calling the given function for each. The zfs
* handle passed each time must be explicitly closed by the callback.
*/
int
{
int ret;
if (namespace_reload(hdl) != 0)
return (-1);
continue;
return (ret);
}
return (0);
}