4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2012 by Delphix. All rights reserved.
32 * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
33 * single packed nvlist. While it would be nice to just read in this
34 * file from userland, this wouldn't work from a local zone. So we have to have
35 * a zpool ioctl to return the complete configuration for all pools. In the
36 * global zone, this will be identical to reading the file and unpacking it in
49 #include "libzfs_impl.h"
51 typedef struct config_node
{
59 config_node_compare(const void *a
, const void *b
, void *unused
)
63 const config_node_t
*ca
= (config_node_t
*)a
;
64 const config_node_t
*cb
= (config_node_t
*)b
;
66 ret
= strcmp(ca
->cn_name
, cb
->cn_name
);
77 namespace_clear(libzfs_handle_t
*hdl
)
79 if (hdl
->libzfs_ns_avl
) {
83 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
,
85 nvlist_free(cn
->cn_config
);
90 uu_avl_destroy(hdl
->libzfs_ns_avl
);
91 hdl
->libzfs_ns_avl
= NULL
;
94 if (hdl
->libzfs_ns_avlpool
) {
95 uu_avl_pool_destroy(hdl
->libzfs_ns_avlpool
);
96 hdl
->libzfs_ns_avlpool
= NULL
;
101 * Loads the pool namespace, or re-loads it if the cache has changed.
104 namespace_reload(libzfs_handle_t
*hdl
)
109 zfs_cmd_t zc
= {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
112 if (hdl
->libzfs_ns_gen
== 0) {
114 * This is the first time we've accessed the configuration
115 * cache. Initialize the AVL tree and then fall through to the
118 if ((hdl
->libzfs_ns_avlpool
= uu_avl_pool_create("config_pool",
119 sizeof (config_node_t
),
120 offsetof(config_node_t
, cn_avl
),
121 config_node_compare
, UU_DEFAULT
)) == NULL
)
122 return (no_memory(hdl
));
124 if ((hdl
->libzfs_ns_avl
= uu_avl_create(hdl
->libzfs_ns_avlpool
,
125 NULL
, UU_DEFAULT
)) == NULL
)
126 return (no_memory(hdl
));
129 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, 0) != 0)
133 zc
.zc_cookie
= hdl
->libzfs_ns_gen
;
134 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_POOL_CONFIGS
, &zc
) != 0) {
138 * The namespace hasn't changed.
140 zcmd_free_nvlists(&zc
);
144 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
145 zcmd_free_nvlists(&zc
);
151 zcmd_free_nvlists(&zc
);
152 return (zfs_standard_error(hdl
, errno
,
153 dgettext(TEXT_DOMAIN
, "failed to read "
154 "pool configuration")));
157 hdl
->libzfs_ns_gen
= zc
.zc_cookie
;
162 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
163 zcmd_free_nvlists(&zc
);
167 zcmd_free_nvlists(&zc
);
170 * Clear out any existing configuration information.
173 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
, &cookie
)) != NULL
) {
174 nvlist_free(cn
->cn_config
);
180 while ((elem
= nvlist_next_nvpair(config
, elem
)) != NULL
) {
182 uu_avl_index_t where
;
184 if ((cn
= zfs_alloc(hdl
, sizeof (config_node_t
))) == NULL
) {
189 if ((cn
->cn_name
= zfs_strdup(hdl
,
190 nvpair_name(elem
))) == NULL
) {
196 verify(nvpair_value_nvlist(elem
, &child
) == 0);
197 if (nvlist_dup(child
, &cn
->cn_config
, 0) != 0) {
201 return (no_memory(hdl
));
203 verify(uu_avl_find(hdl
->libzfs_ns_avl
, cn
, NULL
, &where
)
206 uu_avl_insert(hdl
->libzfs_ns_avl
, cn
, where
);
214 * Retrieve the configuration for the given pool. The configuration is a nvlist
215 * describing the vdevs, as well as the statistics associated with each one.
218 zpool_get_config(zpool_handle_t
*zhp
, nvlist_t
**oldconfig
)
221 *oldconfig
= zhp
->zpool_old_config
;
222 return (zhp
->zpool_config
);
226 * Retrieves a list of enabled features and their refcounts and caches it in
230 zpool_get_features(zpool_handle_t
*zhp
)
232 nvlist_t
*config
, *features
;
234 config
= zpool_get_config(zhp
, NULL
);
236 if (config
== NULL
|| !nvlist_exists(config
,
237 ZPOOL_CONFIG_FEATURE_STATS
)) {
239 boolean_t missing
= B_FALSE
;
241 error
= zpool_refresh_stats(zhp
, &missing
);
243 if (error
!= 0 || missing
)
246 config
= zpool_get_config(zhp
, NULL
);
249 verify(nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_FEATURE_STATS
,
256 * Refresh the vdev statistics associated with the given pool. This is used in
257 * iostat to show configuration changes and determine the delta from the last
258 * time the function was called. This function can fail, in case the pool has
262 zpool_refresh_stats(zpool_handle_t
*zhp
, boolean_t
*missing
)
264 zfs_cmd_t zc
= {"\0", 0, 0, 0, 0, 0, 0, 0, "\0", "\0", "\0"};
267 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
270 (void) strcpy(zc
.zc_name
, zhp
->zpool_name
);
272 if (zhp
->zpool_config_size
== 0)
273 zhp
->zpool_config_size
= 1 << 16;
275 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, zhp
->zpool_config_size
) != 0)
279 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_POOL_STATS
,
282 * The real error is returned in the zc_cookie field.
284 error
= zc
.zc_cookie
;
288 if (errno
== ENOMEM
) {
289 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
290 zcmd_free_nvlists(&zc
);
294 zcmd_free_nvlists(&zc
);
295 if (errno
== ENOENT
|| errno
== EINVAL
)
297 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
302 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
303 zcmd_free_nvlists(&zc
);
307 zcmd_free_nvlists(&zc
);
309 zhp
->zpool_config_size
= zc
.zc_nvlist_dst_size
;
311 if (zhp
->zpool_config
!= NULL
) {
312 uint64_t oldtxg
, newtxg
;
314 verify(nvlist_lookup_uint64(zhp
->zpool_config
,
315 ZPOOL_CONFIG_POOL_TXG
, &oldtxg
) == 0);
316 verify(nvlist_lookup_uint64(config
,
317 ZPOOL_CONFIG_POOL_TXG
, &newtxg
) == 0);
319 if (zhp
->zpool_old_config
!= NULL
)
320 nvlist_free(zhp
->zpool_old_config
);
322 if (oldtxg
!= newtxg
) {
323 nvlist_free(zhp
->zpool_config
);
324 zhp
->zpool_old_config
= NULL
;
326 zhp
->zpool_old_config
= zhp
->zpool_config
;
330 zhp
->zpool_config
= config
;
332 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
334 zhp
->zpool_state
= POOL_STATE_ACTIVE
;
340 * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over
343 * This is an undocumented feature for use during testing only.
345 * This function returns B_TRUE if the pool should be skipped
349 check_restricted(const char *poolname
)
351 static boolean_t initialized
= B_FALSE
;
352 static char *restricted
= NULL
;
354 const char *cur
, *end
;
358 initialized
= B_TRUE
;
359 restricted
= getenv("__ZFS_POOL_RESTRICT");
362 if (NULL
== restricted
)
366 namelen
= strlen(poolname
);
368 end
= strchr(cur
, ' ');
369 len
= (NULL
== end
) ? strlen(cur
) : (end
- cur
);
371 if (len
== namelen
&& 0 == strncmp(cur
, poolname
, len
)) {
376 } while (NULL
!= end
);
382 * Iterate over all pools in the system.
385 zpool_iter(libzfs_handle_t
*hdl
, zpool_iter_f func
, void *data
)
392 * If someone makes a recursive call to zpool_iter(), we want to avoid
393 * refreshing the namespace because that will invalidate the parent
394 * context. We allow recursive calls, but simply re-use the same
395 * namespace AVL tree.
397 if (!hdl
->libzfs_pool_iter
&& namespace_reload(hdl
) != 0)
400 hdl
->libzfs_pool_iter
++;
401 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
402 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
404 if (check_restricted(cn
->cn_name
))
407 if (zpool_open_silent(hdl
, cn
->cn_name
, &zhp
) != 0) {
408 hdl
->libzfs_pool_iter
--;
415 if ((ret
= func(zhp
, data
)) != 0) {
416 hdl
->libzfs_pool_iter
--;
420 hdl
->libzfs_pool_iter
--;
426 * Iterate over root datasets, calling the given function for each. The zfs
427 * handle passed each time must be explicitly closed by the callback.
430 zfs_iter_root(libzfs_handle_t
*hdl
, zfs_iter_f func
, void *data
)
436 if (namespace_reload(hdl
) != 0)
439 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
440 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
442 if (check_restricted(cn
->cn_name
))
445 if ((zhp
= make_dataset_handle(hdl
, cn
->cn_name
)) == NULL
)
448 if ((ret
= func(zhp
, data
)) != 0)