/*
* CDDL HEADER SART
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LIBFS_IMPL_H
#define _LIBFS_IMPL_H
#include <sys/dmu.h>
#include <sys/fs/zfs.h>
#include <sys/zfs_ioctl.h>
#include <sys/spa.h>
#include <sys/nvpair.h>
#include <libuutil.h>
#include <libzfs.h>
#include <libshare.h>
#include <libdevinfo.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef VERIFY
#undef VERIFY
#endif
#define VERIFY verify
typedef struct zfs_crypt {
/* Creating, loading, or changed key value */
char *zc_key_data;
size_t zc_key_data_len;
boolean_t zc_clone_newkey;
/* Private */
boolean_t zc_is_key_change;
} zfs_crypt_t;
typedef struct zprop_table {
struct libzfs_handle *zpt_libzfs;
int zpt_type;
avl_tree_t zpt_props;
nvlist_t *zpt_default_sublists;
int zpt_prop_seq;
int zpt_sublist_seq;
const zpropdef_t **zpt_array;
int zpt_array_slots;
boolean_t zpt_loaded;
} zprop_table_t;
/* libzfs_flags */
#define LIBZFS_FLAG_CLOSE_LIBSHARE 0x1
struct libzfs_handle {
int libzfs_error;
int libzfs_fd;
FILE *libzfs_mnttab;
zpool_handle_t *libzfs_pool_handles;
uu_avl_pool_t *libzfs_ns_avlpool;
uu_avl_t *libzfs_ns_avl;
uint64_t libzfs_ns_gen;
int libzfs_desc_active;
char libzfs_action[1024];
char libzfs_desc[1024];
char *libzfs_log_str;
int libzfs_printerr;
int libzfs_storeerr; /* stuff error messages into buffer */
int libzfs_flags;
boolean_t libzfs_mnttab_enable;
avl_tree_t libzfs_mnttab_cache;
int libzfs_pool_iter;
zfs_crypt_t libzfs_crypt;
libzfs_spawn_f libzfs_spawn;
void *libzfs_spawn_data;
libzfs_cro_handle_t *libzfs_cro_hdl;
zprop_table_t libzfs_props;
zprop_table_t libzfs_poolprops;
libshare_handle_t *libzfs_libshare_hdl;
zfs_handle_cache_t *libzfs_handle_cache;
};
struct zfs_handle {
libzfs_handle_t *zfs_hdl;
zpool_handle_t *zpool_hdl;
char zfs_name[ZFS_MAXNAMELEN];
zfs_type_t zfs_type; /* type including snapshot */
zfs_type_t zfs_head_type; /* type excluding snapshot */
dmu_objset_stats_t zfs_dmustats;
nvlist_t *zfs_props;
nvlist_t *zfs_user_props;
nvlist_t *zfs_recvd_props;
uint8_t *zfs_props_table;
/*
* Cached mountpoint and mount properties
*/
boolean_t zfs_mntcheck;
char *zfs_mntopts;
char *zfs_mountp;
/*
* Fields used by libzfs_cache.c
*/
boolean_t zfs_cached;
};
/*
* This is different from checking zfs_type, because it will also catch
* snapshots of volumes.
*/
#define ZFS_IS_VOLUME(zhp) ((zhp)->zfs_head_type == ZFS_TYPE_VOLUME)
struct zpool_handle {
libzfs_handle_t *zpool_hdl;
zpool_handle_t *zpool_next;
char zpool_name[ZPOOL_MAXNAMELEN];
int zpool_state;
size_t zpool_config_size;
nvlist_t *zpool_config;
nvlist_t *zpool_old_config;
nvlist_t *zpool_props;
diskaddr_t zpool_start_block;
};
#define ZFS_LIBSHARE_HDL(_zhp) (libzfs_get_libshare((_zhp)->zfs_hdl))
typedef enum {
PROTO_NFS = 0,
PROTO_SMB = 1,
PROTO_END = 2
} zfs_share_proto_t;
/*
* The following can be used as a bitmask and any new values
* added must preserve that capability.
*/
typedef enum {
SHARED_NOT_SHARED = 0x0,
SHARED_NFS = 0x2,
SHARED_SMB = 0x4
} zfs_share_type_t;
int zfs_error(libzfs_handle_t *, int, const char *);
int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
void zfs_error_aux(libzfs_handle_t *, const char *, ...);
void *zfs_alloc(libzfs_handle_t *, size_t);
void *zfs_realloc(libzfs_handle_t *, void *, size_t, size_t);
char *zfs_asprintf(libzfs_handle_t *, const char *, ...);
char *zfs_strdup(libzfs_handle_t *, const char *);
int no_memory(libzfs_handle_t *);
zfs_type_t zfs_type_for_error(zfs_handle_t *);
int zfs_standard_error(libzfs_handle_t *, const char *, zfs_type_t, int,
const char *);
int zfs_standard_error_fmt(libzfs_handle_t *, const char *, zfs_type_t, int,
const char *, ...);
int zpool_standard_error(libzfs_handle_t *, int, const char *);
int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
void zfs_errlist(libzfs_handle_t *, zfs_cmd_t *,
void (*)(libzfs_handle_t *, const char *, const char *, int),
void (*)(int), nvlist_t **);
int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
size_t *);
int zfs_do_list_ioctl(zfs_handle_t *, int, zfs_cmd_t *);
const char *zfs_list_ioctl_typestr(int);
int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
zfs_type_t type, zprop_showtype_t, boolean_t recursive);
/*
* Use this changelist_gather() flag to force attempting mounts
* on each change node regardless of whether or not it is currently
* mounted.
*/
#define CL_GATHER_MOUNT_ALWAYS 1
/*
* changelist_prefix should fail if new sharing problems would be introduced.
*/
#define CL_GATHER_VERIFY_SHARING 2
/*
* changelist_postfix should not mount filesystems that were not mounted
* before the change and should not activate any sharing
*/
#define CL_GATHER_NO_SHARE_ACTIVATE 4
/*
* Use this to avoid mounting during receive when -u is used
*/
#define CL_GATHER_NOMOUNT 8
typedef struct prop_changelist prop_changelist_t;
int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
void zcmd_free_nvlists(zfs_cmd_t *);
int changelist_prefix(prop_changelist_t *);
int changelist_postfix(prop_changelist_t *);
void changelist_rename(prop_changelist_t *, const char *, const char *);
void changelist_remove(prop_changelist_t *, const char *);
void changelist_free(prop_changelist_t *);
prop_changelist_t *changelist_gather(zfs_handle_t *,
const zpropdef_t *, int, int);
int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
int changelist_haszonedchild(prop_changelist_t *);
int changelist_validate(prop_changelist_t *, nvlist_t *, const zpropdef_t *);
void remove_mountpoint(zfs_handle_t *);
int create_parents(libzfs_handle_t *, char *, int);
boolean_t isa_child_of(const char *dataset, const char *parent);
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *);
zfs_handle_t *make_share_handle(libzfs_handle_t *, const char *);
zfs_handle_t *make_share_handle_zc(libzfs_handle_t *, zfs_cmd_t *);
void zfs_prop_get_source(zfs_handle_t *, zfs_prop_t, zprop_source_t *,
char *, char *, size_t);
boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
int zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
boolean_t modifying);
typedef struct config_node {
char *cn_name;
nvlist_t *cn_config;
uu_avl_node_t cn_avl;
} config_node_t;
void namespace_clear(libzfs_handle_t *);
int namespace_reload(libzfs_handle_t *);
extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
/* cache lookup by path */
typedef struct zfs_pathent {
avl_node_t zp_avl_link; /* AVL linkage */
const char *zp_name; /* zp_zhp->zfs_name or associated file path */
zfs_handle_t *zp_zhp; /* NULL if removed or zp_name is a file */
/*
* For "path" based entries, we store a direct link to the "main"
* cache entry for this filesystem. The main entry has zp_name = the
* filesystem's dataset name and its zp_zhp points to the zfs_handle_t
* we are looking for. If something changes in the system that would
* change the mapping from sharepoint to filesystem, then the cache
* must be cleared.
*/
struct zfs_pathent *zp_zhp_ent; /* link to 'main' entry for this fs */
boolean_t zp_needsfree; /* cleanup needs to free zp_name */
} zfs_pathent_t;
/*
* cache of dataset and share handles (zfs_handle_t)
*/
struct zfs_handle_cache {
libzfs_handle_t *zhc_hdl;
avl_tree_t zhc_path_avl;
};
#define ZFS_GET_CACHE(_zhp) ((_zhp)->zfs_hdl->libzfs_handle_cache)
int zfs_cache_do_stats_ioctl(libzfs_handle_t *, int, zfs_cmd_t *);
/*
* Shadow data migration.
*/
extern int zfs_shadow_validate(libzfs_handle_t *, const char *);
extern int zfs_shadow_mount(zfs_handle_t *, char *, boolean_t *);
extern int zfs_shadow_unmount(zfs_handle_t *);
extern int zfs_shadow_change(zfs_handle_t *);
/*
* Functions related to external property support.
*/
extern void zprop_init(libzfs_handle_t *);
extern void zprop_fini(libzfs_handle_t *);
extern int zprop_load_external(libzfs_handle_t *, const char *, zfs_type_t,
nvlist_t *, nvlist_t *);
extern void zprop_set_loaded(libzfs_handle_t *);
/*
* sharing interfaces used internally.
*/
zfs_handle_t *zfs_share_open_parent(libzfs_handle_t *, const char *);
boolean_t zfs_is_shareable(zfs_handle_t *, char *, size_t, boolean_t);
int zfs_dot_prop_fixup_values(libzfs_handle_t *, sa_share_props_t *);
int zfs_sharing_upgrade(zfs_handle_t *);
int zfs_sharing_upgrade_impl(zfs_handle_t *, const char *);
int zfs_get_share_location(zfs_handle_t *, char *, size_t, char *, size_t);
const char *zfs_get_fsname(zfs_handle_t *, char *, size_t);
boolean_t zfs_is_known_to_libshare(zfs_handle_t *);
int zfs_share_inherited_name(const char *, const char *, const char *,
char *, size_t);
int zfs_get_auto_share_name(zfs_handle_t *, char *, size_t);
int zfs_matches_auto_share(zfs_handle_t *, const char *, boolean_t *);
int zfs_share_getname(zfs_handle_t *, char *, size_t);
int zfs_share_rename(zfs_handle_t *, char *);
int zfs_share_remove_one(zfs_handle_t *);
int zfs_share_one_quiet(zfs_handle_t *);
boolean_t zfs_share_proto_prop_get(zfs_handle_t *, sa_proto_t, char **);
int zfs_share_prop_set(zfs_handle_t *, zfs_prop_t, char *);
int zfs_share_unpublish_proto(zfs_handle_t *, sa_proto_t, int);
int zfs_share_unpublish_allprotos(zfs_handle_t *, int);
int zfs_specify_share_path(const char *, const char *,
const char *, nvlist_t *, const char **);
int zfs_update_sharing_s2(zfs_handle_t *);
int zfs_update_sharing_from_props(zfs_handle_t *, boolean_t);
int zfs_unshare_proto(zfs_handle_t *, const char *, zfs_share_proto_t *);
int zfs_unshare_one_impl(zfs_handle_t *);
int zfs_validate_sharing_newprops(zfs_handle_t *, const char *, nvlist_t *,
boolean_t, boolean_t);
void zfs_share_notify(zfs_handle_t *, zfs_share_state_t);
int zfs_gather_mount_props(zfs_handle_t *);
void zfs_clear_mount_props(zfs_handle_t *);
#ifdef __cplusplus
}
#endif
#endif /* _LIBFS_IMPL_H */