10SN/A/* 22362SN/A * CDDL HEADER START 30SN/A * 40SN/A * The contents of this file are subject to the terms of the 50SN/A * Common Development and Distribution License (the "License"). 60SN/A * You may not use this file except in compliance with the License. 72362SN/A * 80SN/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92362SN/A * or http://www.opensolaris.org/os/licensing. 100SN/A * See the License for the specific language governing permissions 110SN/A * and limitations under the License. 120SN/A * 130SN/A * When distributing Covered Code, include this CDDL HEADER in each 140SN/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150SN/A * If applicable, add the following below this CDDL HEADER, with the 160SN/A * fields enclosed by brackets "[]" replaced with your own identifying 170SN/A * information: Portions Copyright [yyyy] [name of copyright owner] 180SN/A * 190SN/A * CDDL HEADER END 200SN/A */ 212362SN/A 222362SN/A/* 232362SN/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 240SN/A * Use is subject to license terms. 250SN/A */ 260SN/A 270SN/A/* 280SN/A * Copyright (c) 2012 by Delphix. All rights reserved. 290SN/A */ 300SN/A 310SN/A/* 320SN/A * The pool configuration repository is stored in /etc/zfs/zpool.cache as a 330SN/A * single packed nvlist. While it would be nice to just read in this 340SN/A * file from userland, this wouldn't work from a local zone. So we have to have 350SN/A * a zpool ioctl to return the complete configuration for all pools. In the 360SN/A * global zone, this will be identical to reading the file and unpacking it in 370SN/A * userland. 380SN/A */ 390SN/A 400SN/A#include <errno.h> 410SN/A#include <sys/stat.h> 420SN/A#include <fcntl.h> 430SN/A#include <stddef.h> 440SN/A#include <string.h> 450SN/A#include <unistd.h> 460SN/A#include <libintl.h> 470SN/A#include <libuutil.h> 480SN/A 490SN/A#include "libzfs_impl.h" 500SN/A 510SN/Atypedef struct config_node { 520SN/A char *cn_name; 530SN/A nvlist_t *cn_config; 540SN/A uu_avl_node_t cn_avl; 550SN/A} config_node_t; 560SN/A 570SN/A/* ARGSUSED */ 580SN/Astatic int 590SN/Aconfig_node_compare(const void *a, const void *b, void *unused) 600SN/A{ 610SN/A int ret; 620SN/A 630SN/A const config_node_t *ca = (config_node_t *)a; 640SN/A const config_node_t *cb = (config_node_t *)b; 650SN/A 660SN/A ret = strcmp(ca->cn_name, cb->cn_name); 670SN/A 680SN/A if (ret < 0) 690SN/A return (-1); 700SN/A else if (ret > 0) 710SN/A return (1); 720SN/A else 730SN/A return (0); 740SN/A} 750SN/A 760SN/Avoid 770SN/Anamespace_clear(libzfs_handle_t *hdl) 780SN/A{ 790SN/A if (hdl->libzfs_ns_avl) { 800SN/A config_node_t *cn; 810SN/A void *cookie = NULL; 820SN/A 830SN/A while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, 840SN/A &cookie)) != NULL) { 850SN/A nvlist_free(cn->cn_config); 860SN/A free(cn->cn_name); 870SN/A free(cn); 880SN/A } 890SN/A 900SN/A uu_avl_destroy(hdl->libzfs_ns_avl); 910SN/A hdl->libzfs_ns_avl = NULL; 920SN/A } 930SN/A 940SN/A if (hdl->libzfs_ns_avlpool) { 950SN/A uu_avl_pool_destroy(hdl->libzfs_ns_avlpool); 960SN/A hdl->libzfs_ns_avlpool = NULL; 970SN/A } 980SN/A} 990SN/A 1000SN/A/* 1010SN/A * Loads the pool namespace, or re-loads it if the cache has changed. 1020SN/A */ 1030SN/Astatic int 1040SN/Anamespace_reload(libzfs_handle_t *hdl) 1050SN/A{ 1060SN/A nvlist_t *config; 1070SN/A config_node_t *cn; 1080SN/A nvpair_t *elem; 1090SN/A zfs_cmd_t zc = { 0 }; 1100SN/A void *cookie; 1110SN/A 1120SN/A if (hdl->libzfs_ns_gen == 0) { 1130SN/A /* 1140SN/A * This is the first time we've accessed the configuration 1150SN/A * cache. Initialize the AVL tree and then fall through to the 1160SN/A * common code. 1170SN/A */ 1180SN/A if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool", 1190SN/A sizeof (config_node_t), 1200SN/A offsetof(config_node_t, cn_avl), 1210SN/A config_node_compare, UU_DEFAULT)) == NULL) 1220SN/A return (no_memory(hdl)); 1230SN/A 1240SN/A if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool, 1250SN/A NULL, UU_DEFAULT)) == NULL) 1260SN/A return (no_memory(hdl)); 1270SN/A } 1280SN/A 1290SN/A if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) 1300SN/A return (-1); 1310SN/A 1320SN/A for (;;) { 1330SN/A zc.zc_cookie = hdl->libzfs_ns_gen; 1340SN/A if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CONFIGS, &zc) != 0) { 1350SN/A switch (errno) { 1360SN/A case EEXIST: 1370SN/A /* 1380SN/A * The namespace hasn't changed. 1390SN/A */ 1400SN/A zcmd_free_nvlists(&zc); 1410SN/A return (0); 1420SN/A 1430SN/A case ENOMEM: 1440SN/A if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) { 1450SN/A zcmd_free_nvlists(&zc); 1460SN/A return (-1); 1470SN/A } 1480SN/A break; 1490SN/A 1500SN/A default: 1510SN/A zcmd_free_nvlists(&zc); 1520SN/A return (zfs_standard_error(hdl, errno, 1530SN/A dgettext(TEXT_DOMAIN, "failed to read " 1540SN/A "pool configuration"))); 1550SN/A } 1560SN/A } else { 1570SN/A hdl->libzfs_ns_gen = zc.zc_cookie; 1580SN/A break; 1590SN/A } 1600SN/A } 1610SN/A 1620SN/A if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) { 1630SN/A zcmd_free_nvlists(&zc); 1640SN/A return (-1); 1650SN/A } 1660SN/A 1670SN/A zcmd_free_nvlists(&zc); 1680SN/A 1690SN/A /* 1700SN/A * Clear out any existing configuration information. 1710SN/A */ 1720SN/A cookie = NULL; 1730SN/A while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) { 1740SN/A nvlist_free(cn->cn_config); 1750SN/A free(cn->cn_name); 1760SN/A free(cn); 1770SN/A } 1780SN/A 1790SN/A elem = NULL; 1800SN/A while ((elem = nvlist_next_nvpair(config, elem)) != NULL) { 1810SN/A nvlist_t *child; 1820SN/A uu_avl_index_t where; 1830SN/A 1840SN/A if ((cn = zfs_alloc(hdl, sizeof (config_node_t))) == NULL) { 1850SN/A nvlist_free(config); 1860SN/A return (-1); 1870SN/A } 1880SN/A 1890SN/A if ((cn->cn_name = zfs_strdup(hdl, 1900SN/A nvpair_name(elem))) == NULL) { 1910SN/A free(cn); 1920SN/A nvlist_free(config); 1930SN/A return (-1); 1940SN/A } 1950SN/A 1960SN/A verify(nvpair_value_nvlist(elem, &child) == 0); 1970SN/A if (nvlist_dup(child, &cn->cn_config, 0) != 0) { 1980SN/A free(cn->cn_name); 1990SN/A free(cn); 2000SN/A nvlist_free(config); 2010SN/A return (no_memory(hdl)); 2020SN/A } 2030SN/A verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where) 2040SN/A == NULL); 2050SN/A 2060SN/A uu_avl_insert(hdl->libzfs_ns_avl, cn, where); 2070SN/A } 2080SN/A 2090SN/A nvlist_free(config); 2100SN/A return (0); 2110SN/A} 2120SN/A 2130SN/A/* 2140SN/A * Retrieve the configuration for the given pool. The configuration is a nvlist 2150SN/A * describing the vdevs, as well as the statistics associated with each one. 2160SN/A */ 2170SN/Anvlist_t * 2180SN/Azpool_get_config(zpool_handle_t *zhp, nvlist_t **oldconfig) 2190SN/A{ 2200SN/A if (oldconfig) 2210SN/A *oldconfig = zhp->zpool_old_config; 2220SN/A return (zhp->zpool_config); 2230SN/A} 2240SN/A 2250SN/A/* 2260SN/A * Retrieves a list of enabled features and their refcounts and caches it in 2270SN/A * the pool handle. 2280SN/A */ 2290SN/Anvlist_t * 2300SN/Azpool_get_features(zpool_handle_t *zhp) 2310SN/A{ 2320SN/A nvlist_t *config, *features; 2330SN/A 2340SN/A config = zpool_get_config(zhp, NULL); 2350SN/A 2360SN/A if (config == NULL || !nvlist_exists(config, 2370SN/A ZPOOL_CONFIG_FEATURE_STATS)) { 2380SN/A int error; 2390SN/A boolean_t missing = B_FALSE; 2400SN/A 2410SN/A error = zpool_refresh_stats(zhp, &missing); 2420SN/A 2430SN/A if (error != 0 || missing) 2440SN/A return (NULL); 2450SN/A 2460SN/A config = zpool_get_config(zhp, NULL); 2470SN/A } 2480SN/A 2490SN/A verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_FEATURE_STATS, 2500SN/A &features) == 0); 2510SN/A 2520SN/A return (features); 2530SN/A} 2540SN/A 2550SN/A/* 2560SN/A * Refresh the vdev statistics associated with the given pool. This is used in 2570SN/A * iostat to show configuration changes and determine the delta from the last 2580SN/A * time the function was called. This function can fail, in case the pool has 2590SN/A * been destroyed. 2600SN/A */ 2610SN/Aint 2620SN/Azpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing) 2630SN/A{ 2640SN/A zfs_cmd_t zc = { 0 }; 2650SN/A int error; 2660SN/A nvlist_t *config; 2670SN/A libzfs_handle_t *hdl = zhp->zpool_hdl; 2680SN/A 2690SN/A *missing = B_FALSE; 2700SN/A (void) strcpy(zc.zc_name, zhp->zpool_name); 2710SN/A 2720SN/A if (zhp->zpool_config_size == 0) 2730SN/A zhp->zpool_config_size = 1 << 16; 2740SN/A 2750SN/A if (zcmd_alloc_dst_nvlist(hdl, &zc, zhp->zpool_config_size) != 0) 2760SN/A return (-1); 2770SN/A 2780SN/A for (;;) { 2790SN/A if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_POOL_STATS, 2800SN/A &zc) == 0) { 2810SN/A /* 2820SN/A * The real error is returned in the zc_cookie field. 2830SN/A */ 2840SN/A error = zc.zc_cookie; 2850SN/A break; 2860SN/A } 2870SN/A 2880SN/A if (errno == ENOMEM) { 2890SN/A if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) { 2900SN/A zcmd_free_nvlists(&zc); 2910SN/A return (-1); 2920SN/A } 2930SN/A } else { 2940SN/A zcmd_free_nvlists(&zc); 2950SN/A if (errno == ENOENT || errno == EINVAL) 2960SN/A *missing = B_TRUE; 2970SN/A zhp->zpool_state = POOL_STATE_UNAVAIL; 2980SN/A return (0); 2990SN/A } 3000SN/A } 3010SN/A 3020SN/A if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) { 3030SN/A zcmd_free_nvlists(&zc); 3040SN/A return (-1); 3050SN/A } 3060SN/A 3070SN/A zcmd_free_nvlists(&zc); 3080SN/A 3090SN/A zhp->zpool_config_size = zc.zc_nvlist_dst_size; 3100SN/A 3110SN/A if (zhp->zpool_config != NULL) { 3120SN/A uint64_t oldtxg, newtxg; 3130SN/A 3140SN/A verify(nvlist_lookup_uint64(zhp->zpool_config, 3150SN/A ZPOOL_CONFIG_POOL_TXG, &oldtxg) == 0); 3160SN/A verify(nvlist_lookup_uint64(config, 3170SN/A ZPOOL_CONFIG_POOL_TXG, &newtxg) == 0); 3180SN/A 3190SN/A if (zhp->zpool_old_config != NULL) 3200SN/A nvlist_free(zhp->zpool_old_config); 3210SN/A 3220SN/A if (oldtxg != newtxg) { 3230SN/A nvlist_free(zhp->zpool_config); 3240SN/A zhp->zpool_old_config = NULL; 3250SN/A } else { 3260SN/A zhp->zpool_old_config = zhp->zpool_config; 3270SN/A } 3280SN/A } 3290SN/A 3300SN/A zhp->zpool_config = config; 3310SN/A if (error) 3320SN/A zhp->zpool_state = POOL_STATE_UNAVAIL; 3330SN/A else 3340SN/A zhp->zpool_state = POOL_STATE_ACTIVE; 3350SN/A 3360SN/A return (0); 3370SN/A} 3380SN/A 3390SN/A/* 3400SN/A * If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over 3410SN/A * pools it lists. 3420SN/A * 3430SN/A * This is an undocumented feature for use during testing only. 3440SN/A * 3450SN/A * This function returns B_TRUE if the pool should be skipped 3460SN/A * during iteration. 3470SN/A */ 3480SN/Astatic boolean_t 3490SN/Acheck_restricted(const char *poolname) 3500SN/A{ 3510SN/A static boolean_t initialized = B_FALSE; 3520SN/A static char *restricted = NULL; 3530SN/A 3540SN/A const char *cur, *end; 3550SN/A int len, namelen; 3560SN/A 3570SN/A if (!initialized) { 3580SN/A initialized = B_TRUE; 3590SN/A restricted = getenv("__ZFS_POOL_RESTRICT"); 3600SN/A } 3610SN/A 3620SN/A if (NULL == restricted) 3630SN/A return (B_FALSE); 3640SN/A 3650SN/A cur = restricted; 3660SN/A namelen = strlen(poolname); 3670SN/A do { 3680SN/A end = strchr(cur, ' '); 3690SN/A len = (NULL == end) ? strlen(cur) : (end - cur); 3700SN/A 3710SN/A if (len == namelen && 0 == strncmp(cur, poolname, len)) { 3720SN/A return (B_FALSE); 3730SN/A } 3740SN/A 3750SN/A cur += (len + 1); 3760SN/A } while (NULL != end); 3770SN/A 3780SN/A return (B_TRUE); 3790SN/A} 3800SN/A 3810SN/A/* 3820SN/A * Iterate over all pools in the system. 3830SN/A */ 3840SN/Aint 3850SN/Azpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data) 3860SN/A{ 3870SN/A config_node_t *cn; 3880SN/A zpool_handle_t *zhp; 3890SN/A int ret; 3900SN/A 3910SN/A /* 3920SN/A * If someone makes a recursive call to zpool_iter(), we want to avoid 3930SN/A * refreshing the namespace because that will invalidate the parent 3940SN/A * context. We allow recursive calls, but simply re-use the same 3950SN/A * namespace AVL tree. 3960SN/A */ 3970SN/A if (!hdl->libzfs_pool_iter && namespace_reload(hdl) != 0) 3980SN/A return (-1); 3990SN/A 4000SN/A hdl->libzfs_pool_iter++; 4010SN/A for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL; 4020SN/A cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) { 4030SN/A 4040SN/A if (check_restricted(cn->cn_name)) 4050SN/A continue; 4060SN/A 4070SN/A if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) { 4080SN/A hdl->libzfs_pool_iter--; 4090SN/A return (-1); 4100SN/A } 4110SN/A 4120SN/A if (zhp == NULL) 4130SN/A continue; 4140SN/A 4150SN/A if ((ret = func(zhp, data)) != 0) { 4160SN/A hdl->libzfs_pool_iter--; 4170SN/A return (ret); 4180SN/A } 4190SN/A } 4200SN/A hdl->libzfs_pool_iter--; 4210SN/A 4220SN/A return (0); 4230SN/A} 4240SN/A 4250SN/A/* 4260SN/A * Iterate over root datasets, calling the given function for each. The zfs 4270SN/A * handle passed each time must be explicitly closed by the callback. 4280SN/A */ 4290SN/Aint 4300SN/Azfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data) 4310SN/A{ 4320SN/A config_node_t *cn; 4330SN/A zfs_handle_t *zhp; 4340SN/A int ret; 4350SN/A 4360SN/A if (namespace_reload(hdl) != 0) 4370SN/A return (-1); 4380SN/A 4390SN/A for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL; 4400SN/A cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) { 4410SN/A 4420SN/A if (check_restricted(cn->cn_name)) 443 continue; 444 445 if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL) 446 continue; 447 448 if ((ret = func(zhp, data)) != 0) 449 return (ret); 450 } 451 452 return (0); 453} 454