Esempio n. 1
0
void
namespace_clear(libzfs_handle_t *hdl)
{
	if (hdl->libzfs_ns_avl) {
		config_node_t *cn;
		void *cookie = NULL;

		while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl,
		    &cookie)) != NULL) {
			nvlist_free(cn->cn_config);
			free(cn->cn_name);
			free(cn);
		}

		uu_avl_destroy(hdl->libzfs_ns_avl);
		hdl->libzfs_ns_avl = NULL;
	}

	if (hdl->libzfs_ns_avlpool) {
		uu_avl_pool_destroy(hdl->libzfs_ns_avlpool);
		hdl->libzfs_ns_avlpool = NULL;
	}
}
Esempio n. 2
0
/*
 * Loads the pool namespace, or re-loads it if the cache has changed.
 */
static int
namespace_reload(libzfs_handle_t *hdl)
{
	nvlist_t *config;
	config_node_t *cn;
	nvpair_t *elem;
	zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
	void *cookie;

	if (hdl->libzfs_ns_gen == 0) {
		/*
		 * This is the first time we've accessed the configuration
		 * cache.  Initialize the AVL tree and then fall through to the
		 * common code.
		 */
		if ((hdl->libzfs_ns_avlpool = uu_avl_pool_create("config_pool",
		    sizeof (config_node_t),
		    offsetof(config_node_t, cn_avl),
		    config_node_compare, UU_DEFAULT)) == NULL)
			return (no_memory(hdl));

		if ((hdl->libzfs_ns_avl = uu_avl_create(hdl->libzfs_ns_avlpool,
		    NULL, UU_DEFAULT)) == NULL)
			return (no_memory(hdl));
	}

	if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
		return (-1);

	for (;;) {
		zc.zc_cookie = hdl->libzfs_ns_gen;
		//if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CONFIGS, &zc) != 0) {
		if (zfs_ioctl(hdl, ZFS_IOC_POOL_CONFIGS, &zc) != 0) {
			switch (errno) {
			case EEXIST:
				/*
				 * The namespace hasn't changed.
				 */
				zcmd_free_nvlists(&zc);
				return (0);

			case ENOMEM:
				if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
					zcmd_free_nvlists(&zc);
					return (-1);
				}
				break;

			default:
				zcmd_free_nvlists(&zc);
				return (zfs_standard_error(hdl, errno,
				    dgettext(TEXT_DOMAIN, "failed to read "
				    "pool configuration")));
			}
		} else {
			hdl->libzfs_ns_gen = zc.zc_cookie;
			break;
		}
	}

	if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
		zcmd_free_nvlists(&zc);
		return (-1);
	}

	zcmd_free_nvlists(&zc);

	/*
	 * Clear out any existing configuration information.
	 */
	cookie = NULL;
	while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) {
		nvlist_free(cn->cn_config);
		free(cn->cn_name);
		free(cn);
	}

	elem = NULL;
	while ((elem = nvlist_next_nvpair(config, elem)) != NULL) {
		nvlist_t *child;
		uu_avl_index_t where;

		if ((cn = zfs_alloc(hdl, sizeof (config_node_t))) == NULL) {
			nvlist_free(config);
			return (-1);
		}

		if ((cn->cn_name = zfs_strdup(hdl,
		    nvpair_name(elem))) == NULL) {
			free(cn);
			nvlist_free(config);
			return (-1);
		}

		verify(nvpair_value_nvlist(elem, &child) == 0);
		if (nvlist_dup(child, &cn->cn_config, 0) != 0) {
			free(cn->cn_name);
			free(cn);
			nvlist_free(config);
			return (no_memory(hdl));
		}
		verify(uu_avl_find(hdl->libzfs_ns_avl, cn, NULL, &where)
		    == NULL);

		uu_avl_insert(hdl->libzfs_ns_avl, cn, where);
	}

	nvlist_free(config);
	return (0);
}
Esempio n. 3
0
static int namespace_reload(libzfs_handle_t *p_hdl)
{
        nvlist_t *pnv_config;
        nvpair_t *pnv_elem;
        config_node_t *p_cn;
        void *cookie;

        if(p_hdl->libzfs_ns_gen == 0)
        {
                /*
                 * This is the first time we've accessed the configuration
                 * cache.  Initialize the AVL tree and then fall through to the
                 * common code.
                */
                if(!(p_hdl->libzfs_ns_avlpool =
                        uu_avl_pool_create("config_pool", sizeof (config_node_t),
                                           offsetof(config_node_t, cn_avl),
                                           config_node_compare, UU_DEFAULT)))
			return -1;

                if((p_hdl->libzfs_ns_avl =
                        uu_avl_create(p_hdl->libzfs_ns_avlpool, NULL, UU_DEFAULT)) == NULL)
                        return 1;
	}

        pnv_config = spa_all_configs(&p_hdl->libzfs_ns_gen);
        if(!pnv_config)
                return -1;

        /*
         * Clear out any existing configuration information.
         */
        cookie = NULL;
        while((p_cn = uu_avl_teardown(p_hdl->libzfs_ns_avl, &cookie)) != NULL)
        {
                nvlist_free(p_cn->cn_config);
                free(p_cn->cn_name);
                free(p_cn);
        }

        pnv_elem = NULL;
        while((pnv_elem = nvlist_next_nvpair(pnv_config, pnv_elem)) != NULL)
        {
                nvlist_t *child;
                uu_avl_index_t where;

                if((p_cn = zfs_alloc(p_hdl, sizeof (config_node_t))) == NULL)
                {
                        nvlist_free(pnv_config);
                        return -1;
                }

                if((p_cn->cn_name = zfs_strdup(p_hdl,
		    nvpair_name(pnv_elem))) == NULL) {
                        free(p_cn);
                        nvlist_free(pnv_config);
                        return -1;
                }

		verify(nvpair_value_nvlist(pnv_elem, &child) == 0);
		if (nvlist_dup(child, &p_cn->cn_config, 0) != 0) {
			free(p_cn->cn_name);
			free(p_cn);
			nvlist_free(pnv_config);
			return -1;
		}
		verify(uu_avl_find(p_hdl->libzfs_ns_avl, p_cn, NULL, &where)
		    == NULL);

		uu_avl_insert(p_hdl->libzfs_ns_avl, p_cn, where);
	}

	nvlist_free(pnv_config);
	return 0;
}