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.
29 * Copyright (c) 2015 by Syneto S.R.L. All rights reserved.
30 * Copyright 2016 Nexenta Systems, Inc.
34 * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
35 * single packed nvlist. While it would be nice to just read in this
36 * file from userland, this wouldn't work from a local zone. So we have to have
37 * a zpool ioctl to return the complete configuration for all pools. In the
38 * global zone, this will be identical to reading the file and unpacking it in
51 #include "libzfs_impl.h"
53 typedef struct config_node
{
61 config_node_compare(const void *a
, const void *b
, void *unused
)
65 const config_node_t
*ca
= (config_node_t
*)a
;
66 const config_node_t
*cb
= (config_node_t
*)b
;
68 ret
= strcmp(ca
->cn_name
, cb
->cn_name
);
79 namespace_clear(libzfs_handle_t
*hdl
)
81 if (hdl
->libzfs_ns_avl
) {
85 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
,
87 nvlist_free(cn
->cn_config
);
92 uu_avl_destroy(hdl
->libzfs_ns_avl
);
93 hdl
->libzfs_ns_avl
= NULL
;
96 if (hdl
->libzfs_ns_avlpool
) {
97 uu_avl_pool_destroy(hdl
->libzfs_ns_avlpool
);
98 hdl
->libzfs_ns_avlpool
= NULL
;
103 * Loads the pool namespace, or re-loads it if the cache has changed.
106 namespace_reload(libzfs_handle_t
*hdl
)
111 zfs_cmd_t zc
= { 0 };
114 if (hdl
->libzfs_ns_gen
== 0) {
116 * This is the first time we've accessed the configuration
117 * cache. Initialize the AVL tree and then fall through to the
120 if ((hdl
->libzfs_ns_avlpool
= uu_avl_pool_create("config_pool",
121 sizeof (config_node_t
),
122 offsetof(config_node_t
, cn_avl
),
123 config_node_compare
, UU_DEFAULT
)) == NULL
)
124 return (no_memory(hdl
));
126 if ((hdl
->libzfs_ns_avl
= uu_avl_create(hdl
->libzfs_ns_avlpool
,
127 NULL
, UU_DEFAULT
)) == NULL
)
128 return (no_memory(hdl
));
131 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, 0) != 0)
135 zc
.zc_cookie
= hdl
->libzfs_ns_gen
;
136 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_POOL_CONFIGS
, &zc
) != 0) {
140 * The namespace hasn't changed.
142 zcmd_free_nvlists(&zc
);
146 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
147 zcmd_free_nvlists(&zc
);
153 zcmd_free_nvlists(&zc
);
154 return (zfs_standard_error(hdl
, errno
,
155 dgettext(TEXT_DOMAIN
, "failed to read "
156 "pool configuration")));
159 hdl
->libzfs_ns_gen
= zc
.zc_cookie
;
164 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
165 zcmd_free_nvlists(&zc
);
169 zcmd_free_nvlists(&zc
);
172 * Clear out any existing configuration information.
175 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
, &cookie
)) != NULL
) {
176 nvlist_free(cn
->cn_config
);
182 while ((elem
= nvlist_next_nvpair(config
, elem
)) != NULL
) {
184 uu_avl_index_t where
;
186 if ((cn
= zfs_alloc(hdl
, sizeof (config_node_t
))) == NULL
) {
191 if ((cn
->cn_name
= zfs_strdup(hdl
,
192 nvpair_name(elem
))) == NULL
) {
198 verify(nvpair_value_nvlist(elem
, &child
) == 0);
199 if (nvlist_dup(child
, &cn
->cn_config
, 0) != 0) {
203 return (no_memory(hdl
));
205 verify(uu_avl_find(hdl
->libzfs_ns_avl
, cn
, NULL
, &where
)
208 uu_avl_insert(hdl
->libzfs_ns_avl
, cn
, where
);
216 * Retrieve the configuration for the given pool. The configuration is a nvlist
217 * describing the vdevs, as well as the statistics associated with each one.
220 zpool_get_config(zpool_handle_t
*zhp
, nvlist_t
**oldconfig
)
223 *oldconfig
= zhp
->zpool_old_config
;
224 return (zhp
->zpool_config
);
228 * Retrieves a list of enabled features and their refcounts and caches it in
232 zpool_get_features(zpool_handle_t
*zhp
)
234 nvlist_t
*config
, *features
;
236 config
= zpool_get_config(zhp
, NULL
);
238 if (config
== NULL
|| !nvlist_exists(config
,
239 ZPOOL_CONFIG_FEATURE_STATS
)) {
241 boolean_t missing
= B_FALSE
;
243 error
= zpool_refresh_stats(zhp
, &missing
);
245 if (error
!= 0 || missing
)
248 config
= zpool_get_config(zhp
, NULL
);
251 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_FEATURE_STATS
,
259 * Refresh the vdev statistics associated with the given pool. This is used in
260 * iostat to show configuration changes and determine the delta from the last
261 * time the function was called. This function can fail, in case the pool has
265 zpool_refresh_stats(zpool_handle_t
*zhp
, boolean_t
*missing
)
267 zfs_cmd_t zc
= { 0 };
270 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
273 (void) strcpy(zc
.zc_name
, zhp
->zpool_name
);
275 if (zhp
->zpool_config_size
== 0)
276 zhp
->zpool_config_size
= 1 << 16;
278 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, zhp
->zpool_config_size
) != 0)
282 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_POOL_STATS
,
285 * The real error is returned in the zc_cookie field.
287 error
= zc
.zc_cookie
;
291 if (errno
== ENOMEM
) {
292 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
293 zcmd_free_nvlists(&zc
);
297 zcmd_free_nvlists(&zc
);
298 if (errno
== ENOENT
|| errno
== EINVAL
)
300 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
305 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
306 zcmd_free_nvlists(&zc
);
310 zcmd_free_nvlists(&zc
);
312 zhp
->zpool_config_size
= zc
.zc_nvlist_dst_size
;
314 if (zhp
->zpool_config
!= NULL
) {
315 uint64_t oldtxg
, newtxg
;
317 verify(nvlist_lookup_uint64(zhp
->zpool_config
,
318 ZPOOL_CONFIG_POOL_TXG
, &oldtxg
) == 0);
319 verify(nvlist_lookup_uint64(config
,
320 ZPOOL_CONFIG_POOL_TXG
, &newtxg
) == 0);
322 nvlist_free(zhp
->zpool_old_config
);
324 if (oldtxg
!= newtxg
) {
325 nvlist_free(zhp
->zpool_config
);
326 zhp
->zpool_old_config
= NULL
;
328 zhp
->zpool_old_config
= zhp
->zpool_config
;
332 zhp
->zpool_config
= config
;
334 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
336 zhp
->zpool_state
= POOL_STATE_ACTIVE
;
342 * The following environment variables are undocumented
343 * and should be used for testing purposes only:
345 * __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists
346 * __ZFS_POOL_RESTRICT - iterate only over the pools it lists
348 * This function returns B_TRUE if the pool should be skipped
352 zpool_skip_pool(const char *poolname
)
354 static boolean_t initialized
= B_FALSE
;
355 static const char *exclude
= NULL
;
356 static const char *restricted
= NULL
;
358 const char *cur
, *end
;
360 int namelen
= strlen(poolname
);
363 initialized
= B_TRUE
;
364 exclude
= getenv("__ZFS_POOL_EXCLUDE");
365 restricted
= getenv("__ZFS_POOL_RESTRICT");
368 if (exclude
!= NULL
) {
371 end
= strchr(cur
, ' ');
372 len
= (NULL
== end
) ? strlen(cur
) : (end
- cur
);
373 if (len
== namelen
&& 0 == strncmp(cur
, poolname
, len
))
376 } while (NULL
!= end
);
379 if (NULL
== restricted
)
384 end
= strchr(cur
, ' ');
385 len
= (NULL
== end
) ? strlen(cur
) : (end
- cur
);
387 if (len
== namelen
&& 0 == strncmp(cur
, poolname
, len
)) {
392 } while (NULL
!= end
);
398 * Iterate over all pools in the system.
401 zpool_iter(libzfs_handle_t
*hdl
, zpool_iter_f func
, void *data
)
408 * If someone makes a recursive call to zpool_iter(), we want to avoid
409 * refreshing the namespace because that will invalidate the parent
410 * context. We allow recursive calls, but simply re-use the same
411 * namespace AVL tree.
413 if (!hdl
->libzfs_pool_iter
&& namespace_reload(hdl
) != 0)
416 hdl
->libzfs_pool_iter
++;
417 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
418 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
420 if (zpool_skip_pool(cn
->cn_name
))
423 if (zpool_open_silent(hdl
, cn
->cn_name
, &zhp
) != 0) {
424 hdl
->libzfs_pool_iter
--;
431 if ((ret
= func(zhp
, data
)) != 0) {
432 hdl
->libzfs_pool_iter
--;
436 hdl
->libzfs_pool_iter
--;
442 * Iterate over root datasets, calling the given function for each. The zfs
443 * handle passed each time must be explicitly closed by the callback.
446 zfs_iter_root(libzfs_handle_t
*hdl
, zfs_iter_f func
, void *data
)
452 if (namespace_reload(hdl
) != 0)
455 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
456 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
458 if (zpool_skip_pool(cn
->cn_name
))
461 if ((zhp
= make_dataset_handle(hdl
, cn
->cn_name
)) == NULL
)
464 if ((ret
= func(zhp
, data
)) != 0)