usr/src/lib/libzfs/common/libzfs_config.c
author eschrock
Tue, 30 May 2006 15:47:16 -0700
changeset 2082 76b439ec3ac1
parent 1544 938876158511
child 2142 f6e0487aa9a3
permissions -rw-r--r--
PSARC 2006/223 ZFS Hot Spares PSARC 2006/303 ZFS Clone Promotion 6276916 support for "clone swap" 6288488 du reports misleading size on RAID-Z 6393490 libzfs should be a real library 6397148 fbufs debug code should be removed from buf_hash_insert() 6405966 Hot Spare support in ZFS 6409302 passing a non-root vdev via zpool_create() panics system 6415739 assertion failed: !(zio->io_flags & 0x00040) 6416759 ::dbufs does not find bonus buffers anymore 6417978 double parity RAID-Z a.k.a. RAID6 6424554 full block re-writes need not read data in 6425111 detaching an offline device can result in import confusion
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
 * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 * single packed nvlist.  While it would be nice to just read in this
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * file from userland, this wouldn't work from a local zone.  So we have to have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 * a zpool ioctl to return the complete configuration for all pools.  In the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 * global zone, this will be identical to reading the file and unpacking it in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 * userland.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <fcntl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <stddef.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <string.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
#include <unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
#include <libintl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <libuutil.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include "libzfs_impl.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
typedef struct config_node {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
	char		*cn_name;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	nvlist_t	*cn_config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
	uu_avl_node_t	cn_avl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
} config_node_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
config_node_compare(const void *a, const void *b, void *unused)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
	const config_node_t *ca = (config_node_t *)a;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
	const config_node_t *cb = (config_node_t *)b;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	ret = strcmp(ca->cn_name, cb->cn_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	if (ret < 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	else if (ret > 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    73
void
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    74
namespace_clear(libzfs_handle_t *hdl)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    75
{
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    76
	if (hdl->libzfs_ns_avl) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    77
		uu_avl_walk_t *walk;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    78
		config_node_t *cn;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    79
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    80
		if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    81
		    UU_WALK_ROBUST)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    82
			return;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    83
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    84
		while ((cn = uu_avl_walk_next(walk)) != NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    85
			uu_avl_remove(hdl->libzfs_ns_avl, cn);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    86
			nvlist_free(cn->cn_config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    87
			free(cn->cn_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    88
			free(cn);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    89
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    90
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    91
		uu_avl_walk_end(walk);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    92
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    93
		uu_avl_destroy(hdl->libzfs_ns_avl);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    94
		hdl->libzfs_ns_avl = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    95
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    96
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    97
	if (hdl->libzfs_ns_avlpool) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    98
		uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
    99
		hdl->libzfs_ns_avlpool = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   100
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   101
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   102
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
 * Loads the pool namespace, or re-loads it if the cache has changed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   106
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   107
namespace_reload(libzfs_handle_t *hdl)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
	config_node_t *cn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
	nvpair_t *elem;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
	uu_avl_walk_t *walk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   115
	if (hdl->libzfs_ns_gen == 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
		 * This is the first time we've accessed the configuration
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
		 * cache.  Initialize the AVL tree and then fall through to the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
		 * common code.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   121
		if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
		    sizeof (config_node_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
		    offsetof(config_node_t, cn_avl),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		    config_node_compare, UU_DEFAULT)) == NULL)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   125
			return (no_memory(hdl));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   127
		if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   128
		    NULL, UU_DEFAULT)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   129
			return (no_memory(hdl));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	 * Issue the ZFS_IOC_POOL_CONFIGS ioctl.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	 * This can fail for one of two reasons:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	 * 	EEXIST		The generation counts match, nothing to do.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	 * 	ENOMEM		The zc_config_dst buffer isn't large enough to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	 * 			hold the config; zc_config_dst_size will have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	 *			been modified to tell us how much to allocate.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	zc.zc_config_dst_size = 1024;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   142
	if ((zc.zc_config_dst = (uint64_t)(uintptr_t)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   143
	    zfs_alloc(hdl, zc.zc_config_dst_size)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   144
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
	for (;;) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   146
		zc.zc_cookie = hdl->libzfs_ns_gen;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   147
		if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CONFIGS, &zc) != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
			switch (errno) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
			case EEXIST:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
				 * The namespace hasn't changed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
				free((void *)(uintptr_t)zc.zc_config_dst);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   154
				return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
			case ENOMEM:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
				free((void *)(uintptr_t)zc.zc_config_dst);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   158
				if ((zc.zc_config_dst = (uint64_t)(uintptr_t)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   159
				    zfs_alloc(hdl, zc.zc_config_dst_size))
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   160
				    == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   161
					return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
				break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
			default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   165
				return (zfs_standard_error(hdl, errno,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   166
				    dgettext(TEXT_DOMAIN, "failed to read "
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   167
				    "pool configuration")));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
		} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   170
			hdl->libzfs_ns_gen = zc.zc_cookie;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   175
	if (nvlist_unpack((void *)(uintptr_t)zc.zc_config_dst,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   176
	    zc.zc_config_dst_size, &config, 0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   177
		return (no_memory(hdl));
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	free((void *)(uintptr_t)zc.zc_config_dst);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	 * Clear out any existing configuration information.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   184
	if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   185
	    UU_WALK_ROBUST)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   186
		nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   187
		return (no_memory(hdl));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   188
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	while ((cn = uu_avl_walk_next(walk)) != NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   191
		uu_avl_remove(hdl->libzfs_ns_avl, cn);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
		nvlist_free(cn->cn_config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
		free(cn->cn_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
		free(cn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   197
	uu_avl_walk_end(walk);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   198
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	elem = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
	while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
		nvlist_t *child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
		uu_avl_index_t where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   204
		if ((cn = zfs_alloc(hdl, sizeof (config_node_t))) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   205
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   206
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   207
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   208
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   209
		if ((cn->cn_name = zfs_strdup(hdl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   210
		    nvpair_name(elem))) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   211
			free(cn);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   212
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   213
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
		verify(nvpair_value_nvlist(elem, &child) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   216
		if (nvlist_dup(child, &cn->cn_config, 0) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   217
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   218
			return (no_memory(hdl));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   219
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   220
		verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   221
		    == NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   223
		uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	nvlist_free(config);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   227
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
 * Retrive the configuration for the given pool.  The configuration is a nvlist
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
 * describing the vdevs, as well as the statistics associated with each one.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
nvlist_t *
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   235
zpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
{
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   237
	if (oldconfig)
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   238
		*oldconfig = zhp->zpool_old_config;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	return (zhp->zpool_config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
 * Refresh the vdev statistics associated with the given pool.  This is used in
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
 * iostat to show configuration changes and determine the delta from the last
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
 * time the function was called.  This function can fail, in case the pool has
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
 * been destroyed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
int
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   249
zpool_refresh_stats(zpool_handle_t *zhp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	zfs_cmd_t zc = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	int error;
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   253
	nvlist_t *config;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	(void) strcpy(zc.zc_name, zhp->zpool_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	if (zhp->zpool_config_size == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
		zhp->zpool_config_size = 1 << 16;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	zc.zc_config_dst_size = zhp->zpool_config_size;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   261
	if ((zc.zc_config_dst = (uint64_t)(uintptr_t)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   262
	    zfs_alloc(zhp->zpool_hdl, zc.zc_config_dst_size)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   263
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   265
	for (;;) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   266
		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_STATS,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   267
		    &zc) == 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
			/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   269
			 * The real error is returned in the zc_cookie field.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   271
			error = errno = zc.zc_cookie;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   275
		if (errno == ENOMEM) {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   276
			free((void *)(uintptr_t)zc.zc_config_dst);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   277
			if ((zc.zc_config_dst = (uint64_t)(uintptr_t)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   278
			    zfs_alloc(zhp->zpool_hdl,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   279
			    zc.zc_config_dst_size)) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   280
				return (-1);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   281
		} else {
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 952
diff changeset
   282
			free((void *)(uintptr_t)zc.zc_config_dst);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   283
			return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   287
	if (nvlist_unpack((void *)(uintptr_t)zc.zc_config_dst,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   288
	    zc.zc_config_dst_size, &config, 0) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   289
		free((void *)(uintptr_t)zc.zc_config_dst);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   290
		return (no_memory(zhp->zpool_hdl));
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   291
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	zhp->zpool_config_size = zc.zc_config_dst_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
	free((void *)(uintptr_t)zc.zc_config_dst);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   296
	if (set_pool_health(config) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   297
		return (no_memory(zhp->zpool_hdl));
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   298
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   299
	if (zhp->zpool_config != NULL) {
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   300
		uint64_t oldtxg, newtxg;
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   301
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   302
		verify(nvlist_lookup_uint64(zhp->zpool_config,
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   303
		    ZPOOL_CONFIG_POOL_TXG, &oldtxg) == 0);
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   304
		verify(nvlist_lookup_uint64(config,
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   305
		    ZPOOL_CONFIG_POOL_TXG, &newtxg) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   307
		if (zhp->zpool_old_config != NULL)
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   308
			nvlist_free(zhp->zpool_old_config);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   310
		if (oldtxg != newtxg) {
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   311
			nvlist_free(zhp->zpool_config);
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   312
			zhp->zpool_old_config = NULL;
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   313
		} else {
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   314
			zhp->zpool_old_config = zhp->zpool_config;
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   315
		}
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   316
	}
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   317
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
   318
	zhp->zpool_config = config;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   320
	return (error ? -1 : 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
 * Iterate over all pools in the system.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   327
zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	config_node_t *cn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
	zpool_handle_t *zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   333
	if (namespace_reload(hdl) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   334
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   336
	for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   337
	    cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   339
		if ((zhp = zpool_open_silent(hdl, cn->cn_name)) == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		if ((ret = func(zhp, data)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
			return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
 * Iterate over root datasets, calling the given function for each.  The zfs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
 * handle passed each time must be explicitly closed by the callback.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   354
zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
	config_node_t *cn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	zfs_handle_t *zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   360
	if (namespace_reload(hdl) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   361
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   363
	for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   364
	    cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1544
diff changeset
   366
		if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
		if ((ret = func(zhp, data)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
			return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
}