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.
33 * The pool configuration repository is stored in /etc/zfs/zpool.cache as a
34 * single packed nvlist. While it would be nice to just read in this
35 * file from userland, this wouldn't work from a local zone. So we have to have
36 * a zpool ioctl to return the complete configuration for all pools. In the
37 * global zone, this will be identical to reading the file and unpacking it in
50 #include "libzfs_impl.h"
52 typedef struct config_node
{
60 config_node_compare(const void *a
, const void *b
, void *unused
)
64 const config_node_t
*ca
= (config_node_t
*)a
;
65 const config_node_t
*cb
= (config_node_t
*)b
;
67 ret
= strcmp(ca
->cn_name
, cb
->cn_name
);
78 namespace_clear(libzfs_handle_t
*hdl
)
80 if (hdl
->libzfs_ns_avl
) {
84 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
,
86 nvlist_free(cn
->cn_config
);
91 uu_avl_destroy(hdl
->libzfs_ns_avl
);
92 hdl
->libzfs_ns_avl
= NULL
;
95 if (hdl
->libzfs_ns_avlpool
) {
96 uu_avl_pool_destroy(hdl
->libzfs_ns_avlpool
);
97 hdl
->libzfs_ns_avlpool
= NULL
;
102 * Loads the pool namespace, or re-loads it if the cache has changed.
105 namespace_reload(libzfs_handle_t
*hdl
)
110 zfs_cmd_t zc
= {"\0"};
113 if (hdl
->libzfs_ns_gen
== 0) {
115 * This is the first time we've accessed the configuration
116 * cache. Initialize the AVL tree and then fall through to the
119 if ((hdl
->libzfs_ns_avlpool
= uu_avl_pool_create("config_pool",
120 sizeof (config_node_t
),
121 offsetof(config_node_t
, cn_avl
),
122 config_node_compare
, UU_DEFAULT
)) == NULL
)
123 return (no_memory(hdl
));
125 if ((hdl
->libzfs_ns_avl
= uu_avl_create(hdl
->libzfs_ns_avlpool
,
126 NULL
, UU_DEFAULT
)) == NULL
)
127 return (no_memory(hdl
));
130 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, 0) != 0)
134 zc
.zc_cookie
= hdl
->libzfs_ns_gen
;
135 if (ioctl(hdl
->libzfs_fd
, ZFS_IOC_POOL_CONFIGS
, &zc
) != 0) {
139 * The namespace hasn't changed.
141 zcmd_free_nvlists(&zc
);
145 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
146 zcmd_free_nvlists(&zc
);
152 zcmd_free_nvlists(&zc
);
153 return (zfs_standard_error(hdl
, errno
,
154 dgettext(TEXT_DOMAIN
, "failed to read "
155 "pool configuration")));
158 hdl
->libzfs_ns_gen
= zc
.zc_cookie
;
163 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
164 zcmd_free_nvlists(&zc
);
168 zcmd_free_nvlists(&zc
);
171 * Clear out any existing configuration information.
174 while ((cn
= uu_avl_teardown(hdl
->libzfs_ns_avl
, &cookie
)) != NULL
) {
175 nvlist_free(cn
->cn_config
);
181 while ((elem
= nvlist_next_nvpair(config
, elem
)) != NULL
) {
183 uu_avl_index_t where
;
185 if ((cn
= zfs_alloc(hdl
, sizeof (config_node_t
))) == NULL
) {
190 if ((cn
->cn_name
= zfs_strdup(hdl
,
191 nvpair_name(elem
))) == NULL
) {
197 verify(nvpair_value_nvlist(elem
, &child
) == 0);
198 if (nvlist_dup(child
, &cn
->cn_config
, 0) != 0) {
202 return (no_memory(hdl
));
204 verify(uu_avl_find(hdl
->libzfs_ns_avl
, cn
, NULL
, &where
)
207 uu_avl_insert(hdl
->libzfs_ns_avl
, cn
, where
);
215 * Retrieve the configuration for the given pool. The configuration is an nvlist
216 * describing the vdevs, as well as the statistics associated with each one.
219 zpool_get_config(zpool_handle_t
*zhp
, nvlist_t
**oldconfig
)
222 *oldconfig
= zhp
->zpool_old_config
;
223 return (zhp
->zpool_config
);
227 * Retrieves a list of enabled features and their refcounts and caches it in
231 zpool_get_features(zpool_handle_t
*zhp
)
233 nvlist_t
*config
, *features
;
235 config
= zpool_get_config(zhp
, NULL
);
237 if (config
== NULL
|| !nvlist_exists(config
,
238 ZPOOL_CONFIG_FEATURE_STATS
)) {
240 boolean_t missing
= B_FALSE
;
242 error
= zpool_refresh_stats(zhp
, &missing
);
244 if (error
!= 0 || missing
)
247 config
= zpool_get_config(zhp
, NULL
);
250 if (nvlist_lookup_nvlist(config
, ZPOOL_CONFIG_FEATURE_STATS
,
258 * Refresh the vdev statistics associated with the given pool. This is used in
259 * iostat to show configuration changes and determine the delta from the last
260 * time the function was called. This function can fail, in case the pool has
264 zpool_refresh_stats(zpool_handle_t
*zhp
, boolean_t
*missing
)
266 zfs_cmd_t zc
= {"\0"};
269 libzfs_handle_t
*hdl
= zhp
->zpool_hdl
;
272 (void) strcpy(zc
.zc_name
, zhp
->zpool_name
);
274 if (zhp
->zpool_config_size
== 0)
275 zhp
->zpool_config_size
= 1 << 16;
277 if (zcmd_alloc_dst_nvlist(hdl
, &zc
, zhp
->zpool_config_size
) != 0)
281 if (ioctl(zhp
->zpool_hdl
->libzfs_fd
, ZFS_IOC_POOL_STATS
,
284 * The real error is returned in the zc_cookie field.
286 error
= zc
.zc_cookie
;
290 if (errno
== ENOMEM
) {
291 if (zcmd_expand_dst_nvlist(hdl
, &zc
) != 0) {
292 zcmd_free_nvlists(&zc
);
296 zcmd_free_nvlists(&zc
);
297 if (errno
== ENOENT
|| errno
== EINVAL
)
299 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
304 if (zcmd_read_dst_nvlist(hdl
, &zc
, &config
) != 0) {
305 zcmd_free_nvlists(&zc
);
309 zcmd_free_nvlists(&zc
);
311 zhp
->zpool_config_size
= zc
.zc_nvlist_dst_size
;
313 if (zhp
->zpool_config
!= NULL
) {
314 nvlist_free(zhp
->zpool_old_config
);
316 zhp
->zpool_old_config
= zhp
->zpool_config
;
319 zhp
->zpool_config
= config
;
321 zhp
->zpool_state
= POOL_STATE_UNAVAIL
;
323 zhp
->zpool_state
= POOL_STATE_ACTIVE
;
329 * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over
332 * This is an undocumented feature for use during testing only.
334 * This function returns B_TRUE if the pool should be skipped
338 check_restricted(const char *poolname
)
340 static boolean_t initialized
= B_FALSE
;
341 static char *restricted
= NULL
;
343 const char *cur
, *end
;
347 initialized
= B_TRUE
;
348 restricted
= getenv("__ZFS_POOL_RESTRICT");
351 if (NULL
== restricted
)
355 namelen
= strlen(poolname
);
357 end
= strchr(cur
, ' ');
358 len
= (NULL
== end
) ? strlen(cur
) : (end
- cur
);
360 if (len
== namelen
&& 0 == strncmp(cur
, poolname
, len
)) {
365 } while (NULL
!= end
);
371 * Iterate over all pools in the system.
374 zpool_iter(libzfs_handle_t
*hdl
, zpool_iter_f func
, void *data
)
381 * If someone makes a recursive call to zpool_iter(), we want to avoid
382 * refreshing the namespace because that will invalidate the parent
383 * context. We allow recursive calls, but simply re-use the same
384 * namespace AVL tree.
386 if (!hdl
->libzfs_pool_iter
&& namespace_reload(hdl
) != 0)
389 hdl
->libzfs_pool_iter
++;
390 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
391 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
393 if (check_restricted(cn
->cn_name
))
396 if (zpool_open_silent(hdl
, cn
->cn_name
, &zhp
) != 0) {
397 hdl
->libzfs_pool_iter
--;
404 if ((ret
= func(zhp
, data
)) != 0) {
405 hdl
->libzfs_pool_iter
--;
409 hdl
->libzfs_pool_iter
--;
415 * Iterate over root datasets, calling the given function for each. The zfs
416 * handle passed each time must be explicitly closed by the callback.
419 zfs_iter_root(libzfs_handle_t
*hdl
, zfs_iter_f func
, void *data
)
425 if (namespace_reload(hdl
) != 0)
428 for (cn
= uu_avl_first(hdl
->libzfs_ns_avl
); cn
!= NULL
;
429 cn
= uu_avl_next(hdl
->libzfs_ns_avl
, cn
)) {
431 if (check_restricted(cn
->cn_name
))
434 if ((zhp
= make_dataset_handle(hdl
, cn
->cn_name
)) == NULL
)
437 if ((ret
= func(zhp
, data
)) != 0)