Current File : //usr/include/suri_impl.h
/*
 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef	_SURI_IMPL_H
#define	_SURI_IMPL_H

/*
 * This is an internal libsuri header file. Should be never included from
 * outside of libsuri itself.
 */

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <limits.h>
/* Needed for ima.h */
#define	SOLARIS 1
#include <ima.h>
#include <suri.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <lofi.h>

#define	SURI_LOFI_RESULT_ERR(r) \
	((r) != NULL ? lofi_result_err(r) : errno)
#define	SURI_LOFI_RESULT_ERR_STR(r) \
	((r) != NULL ? lofi_result_error_str(r) : strerror(errno))

/* Convert a number to a string */
#define	SURI_STR_VALUE(arg)	#arg
#define	SURI_NAME(name)		SURI_STR_VALUE(name)

#define	ARRAY_SIZE(a)	(sizeof (a) / sizeof ((a)[0]))

/*
 * Default flags for file/NFS based SURI_OP_CREATE(). Flags for open can
 * never be changed.  Files are created with mode 600.
 */
#define	SURI_CREATE_OPEN_FLAGS	(O_WRONLY | O_CREAT | O_EXCL)
#define	SURI_CREATE_OPEN_MODE	(S_IRUSR | S_IWUSR)

/*
 * Flags for NFS based SURI_OP_CREATE(), SURI_OP_MAP().
 * Used to create the directories needed for the default mountpoint with
 * mode of 755.
 */
#define	SURI_MKDIR_MODE	(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)

/*
 * Defines used for NFS and FILE suris.
 */
#define	SURI_FILE_STRING	"file://%s:%s@%s"
#define	SURI_NFS_STRING		"nfs://%s:%s@%s%s%s"


#define	SURI_ISCSI_DEFAULT_PORT		3260
#define	SURI_ISCSI_DEFAULT_PORT_STR	SURI_NAME(SURI_ISCSI_DEFAULT_PORT)

/*
 * Logical unit or target/initiator name type strings.  They must all be
 * 3-character strings.
 */
#define	SURI_EUI		"eui"
#define	SURI_IQN		"iqn"
#define	SURI_NAA		"naa"
#define	SURI_T10		"t10"
/* Use this to avoid using numbers 3 and 4 in the code */
#define	SURI_GTYPE_LEN		(3)
#define	SURI_GTYPE_W_PERIOD_LEN	(SURI_GTYPE_LEN + 1)

/* Used string for our iSCSI/LU URIs */
#define	SURI_INITIATOR		"initiator"
#define	SURI_LUN		"lun"
#define	SURI_LUNAME		"luname"
#define	SURI_TARGET		"target"

/* Flags for GUIDs.  Two bytes should be enough (16 types). */
#define	SURI_GF_UNKNOWN		0x0000
#define	SURI_GF_EUI		0x0001
#define	SURI_GF_IQN		0x0002
#define	SURI_GF_NAA		0x0004
#define	SURI_GF_T10		0x0008

/* Flags for prefixes.  Leave two lower bytes empty for GUID types. */
#define	SURI_GF_INITIATOR	0x010000
#define	SURI_GF_LUNAME		0x020000
#define	SURI_GF_TARGET		0x040000

#define	SURI_MAX_LUN		INT_MAX

/* for suri_remove_duplicate_handles() */
#define	SURI_URI_SORT_NORMAL	B_FALSE
#define	SURI_URI_SORT_REVERSE	B_TRUE

/*
 * A common function works with the device tree and needs to know what exectly
 * it is supposed to do and on which URI type.
 */
typedef enum suri_lu_iscsi_action {
	SURI_ISCSI_MAP_LUNAME = 1,
	SURI_ISCSI_LOOKUP_URI,
	SURI_LU_MAP,
	SURI_LU_LOOKUP_URI,
	SURI_ISCSI_MAP_TARGET_LUN
} suri_lu_iscsi_action_t;

/*
 * Services libsuri may temporarily enable.
 */
#define	SURI_ISCSI_INITIATOR_SVC "network/iscsi/initiator:default"
#define	SURI_CHASSIS_SVC "system/devchassis:daemon"

/*
 * validation macros for public data types
 */
#define	SURI_VALID_STATE(x)						\
	(((x) > SURI_STATE_INVALID) && ((x) < SURI_STATE_MAX))

#define	SURI_VALID_TYPE(x)	(((x) == SURI_TYPE_ANY) ||		\
	(((x) > SURI_TYPE_INVALID) && ((x) < SURI_TYPE_MAX)))

/*
 * Regular expression compiled with the parser code together with all other
 * regular expressions present in libsuri but used from another module.
 */
extern regex_t suri_re_ctds_name;
extern regex_t suri_re_ctds_path;
extern regex_t suri_re_ctd_path;

typedef struct suri_dev suri_dev_t;
typedef struct suri_file suri_file_t;
typedef struct suri_iscsi suri_iscsi_t;
typedef struct suri_lu suri_lu_t;
typedef struct suri_nfs suri_nfs_t;
typedef struct suri_ops suri_ops_t;
typedef struct suri_mdev_node suri_mdev_node_t;

#define	SURIH2DEV(h)	((suri_dev_t *)(h)->sh_data)
#define	SURIH2FILE(h)	((suri_file_t *)(h)->sh_data)
#define	SURIH2ISCSI(h)	((suri_iscsi_t *)(h)->sh_data)
#define	SURIH2LU(h)	((suri_lu_t *)(h)->sh_data)
#define	SURIH2NFS(h)	((suri_nfs_t *)(h)->sh_data)

/* Allow enough space for a long URI or a unix path and a message. */
#define	SURI_ERR_STR_LEN	(2 * SURI_MAX_URI_LEN)
/* Error messages shouldn't be longer than 1/4 of the error string length */
#define	SURI_ERRMSG_LEN		(SURI_MAX_URI_LEN/4)
/* Warnings may contain full URIs so be careful here. */
#define	SURI_WARN_STR_LEN	320
/*
 * The fundamental handle for the consumer to deal with suri objects.
 */
struct suri_handle {
	/* URI string */
	char		sh_uri[SURI_MAX_URI_LEN];
	/* URI type of attached shared object */
	suri_type_t	sh_uri_type;
	/*
	 * List of mapped devices. Here we store SURI_PROP_RO_MAPPED_DEV
	 * and SURI_PROP_RO_MAPPED_DEVS as the OS device name.
	 */
	list_t sh_mdev_list;
	/* Number of nodes in the mdev list. */
	size_t sh_mdev_count;
	/* Length of the longest string in the mdev list. */
	size_t sh_mdev_max_len;
	/*
	 * Array of mapped devices. This is the data returned to the consumer of
	 * the libsuri by suri_get_mvprop_str(). This array is constructed when
	 * the state of handle becomes SURI_STATE_MAPPED by
	 * suri_set_mapped_state() and it uses data in sh_mdev_list. Thus, it's
	 * illegal to access this data when the state is not SURI_STATE_MAPPED
	 * and sh_mdev_list must not be freed as long as sh_mdev_array is used.
	 */
	const char **sh_mdev_array;
	/* state of attached shared object */
	suri_state_t	sh_state;
	/* A pointer to a URI type specific structure with object properties. */
	void		*sh_data;
	/* Operations specific to the URI type. */
	suri_ops_t	*sh_ops;
	/*
	 * Cached return code for the last operation. Useful with lookup-uri
	 * that can return multiple handles. Use this entry only in public API
	 * functions.
	 */
	int		sh_err_code;
	/*
	 * Dynamic action error message on what failed. Is supposed to include
	 * the object being operated on (URI, mapped-path).
	 */
	char		sh_err_action[SURI_ERR_STR_LEN];
	/*
	 * Error message on why it failed. Use either a dynamic message or a
	 * static description string, not both.
	 */
	char		sh_err_desc[SURI_ERR_STR_LEN];
	char		*sh_err_static_desc;
	/* We can have only two warnings at the same time. */
	char		*sh_warn[3];
	char		sh_warnings[2][SURI_WARN_STR_LEN];
};

typedef struct suri_gen_uri {
	char sgu_scheme[SURI_MAX_URI_LEN];
	char sgu_authority[SURI_MAX_URI_LEN];
	char sgu_path[SURI_MAX_URI_LEN];
	char sgu_query[SURI_MAX_URI_LEN];
	char sgu_fragment[SURI_MAX_URI_LEN];
} suri_gen_uri_t;

/*
 * List node of mapped devices.
 */
struct suri_mdev_node {
	char sh_mdev[MAXPATHLEN];
	list_node_t node_info;
};

/*
 * suri specific operations
 */
struct suri_ops {
	suri_err_t	(*op_parse)(struct suri_handle *,
			const suri_gen_uri_t *, nvlist_t *);
	suri_err_t	(*op_map)(struct suri_handle *, nvlist_t *);
	suri_err_t	(*op_lookup_mapping)(struct suri_handle *, nvlist_t *);
	suri_err_t	(*op_lookup_uri)(struct suri_handle *, nvlist_t *,
			struct suri_handle ***);
	suri_err_t	(*op_unmap)(struct suri_handle *, nvlist_t *,
			boolean_t);
	boolean_t	(*op_prop_valid)(suri_prop_t);
	boolean_t	(*op_prop_defined)(struct suri_handle *, suri_prop_t);
	const char	*(*op_get_prop_str)(struct suri_handle *, suri_prop_t);
	uint64_t	(*op_get_prop_uint64)(struct suri_handle *,
			suri_prop_t);
	boolean_t	(*op_get_prop_bool)(struct suri_handle *, suri_prop_t);
	suri_err_t	(*op_create)(struct suri_handle *, nvlist_t *);
	suri_err_t	(*op_destroy)(struct suri_handle *, nvlist_t *);
	suri_err_t	(*op_normalize)(struct suri_handle *, nvlist_t *);
};

#define	SURI_OP_PARSE(h, s, p)		(h->sh_ops->op_parse)(h, s, p)
#define	SURI_OP_MAP(h, p)		(h->sh_ops->op_map)(h, p)
#define	SURI_OP_LOOKUP_MAPPING(h, p)	(h->sh_ops->op_lookup_mapping)(h, p)
#define	SURI_OP_LOOKUP_URI(h, l, ph)	(h->sh_ops->op_lookup_uri)(h, l, ph)
#define	SURI_OP_UNMAP(h, p, t)		(h->sh_ops->op_unmap)(h, p, t)
#define	SURI_OP_PROP_DEFINED(h, prop) \
	(h->sh_ops->op_prop_defined)(h, prop)
#define	SURI_OP_PROP_VALID(h, prop) \
	(h->sh_ops->op_prop_valid)(prop)
#define	SURI_OP_GET_PROP_STR(h, prop) \
	(h->sh_ops->op_get_prop_str)(h, prop)
#define	SURI_OP_GET_PROP_UINT64(h, prop) \
	(h->sh_ops->op_get_prop_uint64)(h, prop)
#define	SURI_OP_GET_PROP_BOOL(h, prop) \
	(h->sh_ops->op_get_prop_bool)(h, prop)
#define	SURI_OP_GET_PROP_SOTYPE(h, t) \
	(h->sh_ops->op_get_prop_sotype)(h, t)
#define	SURI_OP_CREATE(h, p)		(h->sh_ops->op_create)(h, p)
#define	SURI_OP_DESTROY(h, p)		(h->sh_ops->op_destroy)(h, p)
#define	SURI_OP_NORMALIZE(h, p)		(h->sh_ops->op_normalize)(h, p)

/*
 * the file URI specific storage object components
 */
struct suri_file {
	/* SURI_PROP_RO_PATH, unix path from URI */
	char		sf_prop_path[MAXPATHLEN];
	/* SURI_PROP_RO_USER, user from URI */
	char		sf_prop_user[LOGNAME_MAX + 1];
	/* SURI_PROP_RO_GROUP, group from URI */
	char		sf_prop_group[LOGNAME_MAX + 1];
	/* SURI_PROP_RW_CREATE_SIZE */
	char		sf_prop_create_size[SURI_MAX_UINT64_LEN];
	/* SURI_PROP_RW_FILE_PERMS */
	uint64_t	sf_prop_file_perms;
	/*
	 * These properties are for internal purpose only and are not exposed
	 * to the consumer.  sf_uid/gid is the uid/gid derived from the URI.
	 */
	uid_t		sf_uid;
	gid_t		sf_gid;
};

/*
 * the NFS URI specific storage object components
 */
struct suri_nfs {
	/* SURI_PROP_RO_PATH, unix path from URI, nfs path */
	char		sn_prop_path[MAXPATHLEN];
	/* SURI_PROP_RO_USER, user from URI */
	char		sn_prop_user[LOGNAME_MAX + 1];
	/* SURI_PROP_RO_GROUP, group from URI */
	char		sn_prop_group[LOGNAME_MAX + 1];
	/* SURI_PROP_RW_CREATE_SIZE */
	char		sn_prop_create_size[SURI_MAX_UINT64_LEN];
	/* SURI_PROP_RW_FILE_PERMS */
	uint64_t	sn_prop_file_perms;
	/* SURI_PROP_RO_HOSTNAME, nfs hostname */
	char		sn_prop_hname[NI_MAXHOST];
	/* SURI_PROP_RO_MOUNTPOINT */
	char		sn_prop_mountpoint[MAXPATHLEN];
	/* SURI_PROP_RO_PORT, nfs port */
	in_port_t	sn_prop_port;
	/* SURI_PROP_RW_MOUNTPOINT_PREFIX */
	char		sn_prop_mountpoint_prefix[MAXPATHLEN];
	/* SURI_PROP_RW_MOUNT_OPTIONS */
	char		sn_prop_mount_opts[MAX_MNTOPT_STR];
	/*
	 * These properties are for internal purpose only and are not exposed
	 * to the consumer.
	 * sn_share_pathname is the NFS share to be mounted on the client.
	 * sn_mounted_filepath is the absolute path of the file in the
	 * NFS share mounted on the client.
	 * sn_uid and sn_gid are the validated values from user/group.
	 */
	char		sn_share_pathname[MAXPATHLEN];
	char		sn_mounted_filepath[MAXPATHLEN];
	uid_t		sn_uid;
	gid_t		sn_gid;
};

/*
 * EUI-64 ID is 8 bytes and NAA 8 or 16 bytes long.  Those GUIDs are always
 * formatted in hexadecimal digits and we store them with the prefix ("naa." or
 * "eui.") and a terminating NUL character.
 *
 * However, T10 identifier can be arbitrarily long in theory.  Despite of that,
 * we should give it a reasonable limit anyway.  Solaris currently limits them
 * in devid_to_guid() to 32 ASCII (not hexa) characters.  Note that the device
 * tree devid property uses ASCII encoding for T10 IDs in contrast to EUI/NAA
 * IDs.
 */
#define	SURI_MAX_T10_LEN	48
/* One +1 is for ".", the other one is for a terminating NUL. */
#define	SURI_MAX_LUNAME_PROP_LEN (SURI_GTYPE_LEN + 1 + SURI_MAX_T10_LEN + 1)
#if SURI_MAX_T10_LEN < 32
#error "Maximum T10 ID length not sufficient to accomodate NAA IDs."
#endif

/*
 * When looking up URIs, we may internally pass any target GUID in a target
 * property of the handle for any URI type.  For example, we may look up LU URIs
 * based on an IQN target if we have a multipathed node with multiple transport
 * types.  So the target property must accomodate all target types.
 */
#define	SURI_MAX_TARGET_PROP_LEN	(IMA_NODE_NAME_LEN + 1)
#define	SURI_MAX_INITIATOR_PROP_LEN	(SURI_MAX_LUNAME_PROP_LEN)

#if SURI_MAX_TARGET_PROP_LEN < SURI_MAX_LUNAME_PROP_LEN
#error "Maximum target length not sufficient to accomodate all target types."
#endif

/* used in the parser error message */
#define	SURI_MAX_T10_LEN_STR	SURI_NAME(SURI_MAX_T10_LEN)

/*
 * The logical unit specific storage object components.
 */
struct suri_lu {
	/* SURI_PROP_RO_LUNAME, a GUID with a ".<3-char-type>" prefix */
	char		sl_prop_luname[SURI_MAX_LUNAME_PROP_LEN];
	/* SURI_PROP_RO_INITIATOR, a GUID with a ".<3-char-type>" prefix */
	char		sl_prop_initiator[SURI_MAX_INITIATOR_PROP_LEN];
	/* SURI_PROP_RO_TARGET, a GUID with a ".<3-char-type>" prefix */
	char		sl_prop_target[SURI_MAX_TARGET_PROP_LEN];
	/*
	 * Internal only property used in the look-up URI code.  You cannot get
	 * this value via suri_get_prop_uint64().
	 */
	uint64_t	sl_prop_lun;
};

/*
 * We borrow the maximum IQN length from libima but assert its value here
 * as max URI length is 1024 and if in the future we wish to have a URI that
 * contains a target and initiator IQN each cannot be greater than 512
 */
#if IMA_NODE_NAME_LEN > 512
#error "Maximum IQN length cannot exceed 512. Libsuri conflict with libima."
#endif
/*
 * The iSCSI target specific storage object components.
 */
struct suri_iscsi {
	char		si_prop_hname[NI_MAXHOST]; /* target hostname */
	in_port_t	si_prop_port;		   /* target port */
	/* SURI_PROP_RO_LUNAME. See suri_lu for more information. */
	char		si_prop_luname[SURI_MAX_LUNAME_PROP_LEN];
	/* SURI_PROP_RO_TARGET.  See suri_lu for more information. */
	char		si_prop_target[SURI_MAX_TARGET_PROP_LEN];
	/* SURI_PROP_RO_LUN.  Logical Unit Number of logical unit on target */
	uint64_t	si_prop_lun;
};

/*
 * the dev URI specific storage object components
 */
struct suri_dev {
	/* SURI_PROP_RO_PATH, unix path from URI */
	char		sd_prop_path[MAXPATHLEN];
};

/* For parsing URIs. */
suri_err_t suri_get_uri_type(struct suri_handle *, suri_gen_uri_t *);
suri_err_t suri_dev_parse(struct suri_handle *, const suri_gen_uri_t *,
    nvlist_t *);
suri_err_t suri_file_parse(struct suri_handle *, const suri_gen_uri_t *,
    nvlist_t *);
suri_err_t suri_lu_parse(struct suri_handle *, const suri_gen_uri_t *,
    nvlist_t *);
suri_err_t suri_iscsi_parse(struct suri_handle *, const suri_gen_uri_t *,
    nvlist_t *);
suri_err_t suri_nfs_parse(struct suri_handle *, const suri_gen_uri_t *,
    nvlist_t *);

/* For normalizing URI's */
suri_err_t suri_dev_normalize(struct suri_handle *, nvlist_t *);
suri_err_t suri_file_normalize(struct suri_handle *, nvlist_t *);
suri_err_t suri_lu_iscsi_normalize(struct suri_handle *, nvlist_t *);
suri_err_t suri_nfs_normalize(struct suri_handle *, nvlist_t *);
void suri_normalize_usergroup(struct suri_handle *);
void suri_normalize_host_port(struct suri_handle *, char *, size_t,
    in_port_t *);

/* For mapping fibre channel and SAS shared objects. */
suri_err_t devinfo_target_mapping(struct suri_handle *, suri_lu_iscsi_action_t,
    struct suri_handle ***);

/* For mapping iSCSI shared objects. */
suri_err_t suri_resolve_hostname(struct suri_handle *, const char *,
    struct addrinfo **, char *, size_t);
suri_err_t suri_iscsi_add_disc_addrs(struct suri_handle *, struct addrinfo *);
suri_err_t suri_get_discovery_addresses(struct suri_handle *, IMA_OID_LIST **);
suri_err_t suri_get_auth_section_for_iscsi_tgt(struct suri_handle *,
    const char *, IMA_OID);
suri_err_t suri_get_devname_for_iqn_lun(struct suri_handle *,
    const char *, size_t, char *, size_t);
suri_err_t suri_get_iqn_lun_for_devpath(struct suri_handle *, const char *,
    char **, uint64_t *);

/* Auxiliary functions */
suri_err_t suri_enable_service(struct suri_handle *h, char *);
suri_err_t suri_enforce_real_devpath(struct suri_handle *, const char *,
    boolean_t);
suri_err_t suri_enforce_block_dev_or_chassis(struct suri_handle *, const char *,
    boolean_t);
boolean_t suri_experimental_enabled(void);
struct suri_handle **suri_expand_handle_array(struct suri_handle **, int *);
suri_err_t suri_clone(struct suri_handle *, struct suri_handle **);
void suri_destroy_handle_array(struct suri_handle ***);
int suri_get_handle_count(struct suri_handle **);
void suri_remove_duplicate_handles(struct suri_handle **, boolean_t);
boolean_t suri_ctd_path(const char *);
boolean_t suri_ctds_path(const char *);
boolean_t suri_devchassis_path(const char *);
suri_err_t suri_check_lun(struct suri_handle *, const char *, uint64_t *);
suri_err_t check_guid_with_flags(struct suri_handle *, const char *,
    const char *, int, int);
suri_err_t suri_validate_usergroup(struct suri_handle *, lofi_usergroup_t *);
suri_err_t suri_convert_errno(int err);
boolean_t suri_isnumber(const char *);
suri_err_t suri_regular_file_check(struct suri_handle *, const char *);
suri_err_t suri_get_create_size(struct suri_handle *, uint64_t *, mode_t *);
suri_err_t suri_setid_stat(struct suri_handle *, struct stat64 *, uid_t, gid_t,
    const char *);
suri_err_t suri_validate_set_props(struct suri_handle *, nvlist_t *,
    suri_prop_t *);
suri_err_t suri_required_props(struct suri_handle *, nvlist_t *, suri_prop_t *);
suri_err_t suri_nvprop_get_mountopts(struct suri_handle *, nvpair_t *, char *,
    size_t);
suri_err_t suri_lofi_lookup_cmp(struct suri_handle *, struct suri_handle **);
void suri_set_remap_props(struct suri_handle *, struct suri_handle *);
void suri_get_uid_gid(struct suri_handle *, uid_t *, gid_t *);

/* Internal interface for mapped devices. */
boolean_t suri_mdev_exist(struct suri_handle *);
const char *suri_get_first_mdev(struct suri_handle *);
suri_err_t suri_add_mdev(struct suri_handle *, const char *);
suri_err_t suri_mdev_list_replace(struct suri_handle *, const char *);
suri_err_t suri_set_mapped_state(struct suri_handle *);

/* Lofi functions */
suri_err_t suri_lofi_map(struct suri_handle *);
suri_err_t suri_lofi_lookup(struct suri_handle *, const char *);
suri_err_t suri_lofi_lookup_uri(struct suri_handle *);
suri_err_t suri_lofi_unmap(struct suri_handle *, const char *);
suri_err_t suri_lofi_teardown(struct suri_handle *, const char *);

/* dev URI functions */
suri_err_t suri_get_compdev_for_chassis(struct suri_handle *, const char *);
suri_err_t suri_get_chassis_for_compdev(struct suri_handle *, char **);

/* Error functions */
void suri_err_set_action(struct suri_handle *, const char *fmt, ...);
void suri_err_set_desc(struct suri_handle *, const char *fmt, ...);
suri_err_t suri_err_set_static_desc(struct suri_handle *, suri_err_t);
void suri_set_warn(struct suri_handle *, const char *, ...);
void suri_err_clear(struct suri_handle *);
boolean_t suri_err_check_null_warnings(struct suri_handle *);
boolean_t suri_err_check_null_errors(struct suri_handle *);

/* file URI functions */
suri_err_t suri_file_map(struct suri_handle *, nvlist_t *);
suri_err_t suri_file_lookup_mapping(struct suri_handle *, nvlist_t *);
suri_err_t suri_file_lookup_uri(struct suri_handle *, nvlist_t *,
    struct suri_handle ***);
suri_err_t suri_file_unmap(struct suri_handle *, nvlist_t *, boolean_t);
suri_err_t suri_file_create(struct suri_handle *, nvlist_t *);
suri_err_t suri_file_destroy(struct suri_handle *, nvlist_t *);
boolean_t suri_file_prop_valid(suri_prop_t);
boolean_t suri_file_prop_defined(struct suri_handle *, suri_prop_t);
const char *suri_file_get_prop_str(struct suri_handle *, suri_prop_t);
boolean_t suri_file_get_prop_bool(struct suri_handle *, suri_prop_t);
uint64_t suri_file_get_prop_uint64(struct suri_handle *, suri_prop_t);

/* NFS URI functions */
suri_err_t suri_nfs_map(struct suri_handle *, nvlist_t *prop);
suri_err_t suri_nfs_lookup_mapping(struct suri_handle *, nvlist_t *prop);
suri_err_t suri_nfs_lookup_uri(struct suri_handle *, nvlist_t *,
    struct suri_handle ***);
suri_err_t suri_nfs_unmap(struct suri_handle *, nvlist_t *prop, boolean_t);
suri_err_t suri_nfs_create(struct suri_handle *, nvlist_t *prop);
suri_err_t suri_nfs_destroy(struct suri_handle *, nvlist_t *prop);
boolean_t suri_nfs_prop_valid(suri_prop_t);
boolean_t suri_nfs_prop_defined(struct suri_handle *, suri_prop_t);
const char *suri_nfs_get_prop_str(struct suri_handle *, suri_prop_t);
boolean_t suri_nfs_get_prop_bool(struct suri_handle *, suri_prop_t);
uint64_t suri_nfs_get_prop_uint64(struct suri_handle *, suri_prop_t);
suri_err_t suri_nfs_set_prop_mountpoint(struct suri_handle *);

/* Setid Callback functions */
typedef struct __suri_setid_cb_arg *suri_setid_cb_arg_t;
typedef int (*suri_setid_cb_t)(suri_setid_cb_arg_t arg,
    size_t arg_size, char *errbuf, size_t errbuf_size);
suri_err_t suri_setid_cb(struct suri_handle *, char *, uid_t, gid_t, boolean_t,
    suri_setid_cb_t, suri_setid_cb_arg_t, size_t);
suri_err_t suri_setid_create_file(struct suri_handle *, const char *, uint64_t,
    mode_t);
int suri_setid_cb_destroy_file(suri_setid_cb_arg_t, size_t, char *, size_t);

#ifdef	__cplusplus
}
#endif

#endif	/* _SURI_IMPL_H */