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

/*
 * This header file defines a private interface provided by libsuri(3LIB).
 */

#ifndef	_SURI_H
#define	_SURI_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/list.h>
#include <libnvpair.h>
#include <netdb.h>

/* Supported URI schemes. */
#define	SURI_DEV_SCHEME		"dev"
#define	SURI_FILE_SCHEME	"file"
#define	SURI_ISCSI_SCHEME	"iscsi"
#define	SURI_LU_SCHEME		"lu"
#define	SURI_NFS_SCHEME		"nfs"

/* Invalid URI scheme name */
#define	SURI_INVALID_SCHEME	"Invalid URI type"

/*
 * When converted to a string, uint64_t object is at most 21 chars including
 * the terminating null.
 */
#define	SURI_MAX_UINT64_LEN	21

/*
 * Max number of chars to hold string for port number.
 * A string of 7 chars holds a null-terminated uint16 number possibly
 * prepended with a ':', if needed.  Length of string doesn't include
 * the terminating null.
 */
#define	SURI_MAX_UINT16_STR	7
#define	SURI_MAX_UINT16_LEN	(SURI_MAX_UINT16_STR - 1)

/*
 * Maximum length allowed for a URI string including the terminating '\0'. Some
 * space is added for a scheme part to accomodate a full unix path length.
 * Space is also added to hold the NFS URI with username, groupname, hostname,
 * port (max size is 5 digits plus ':') and 7 chars syntax of 'nfs:/',
 * : and @ in user:group@host).
 */
#define	SURI_MAX_URI_LEN	(MAXPATHLEN + 32 + (2 * LOGNAME_MAX) + \
    NI_MAXHOST + SURI_MAX_UINT16_LEN + 7)

#define	SURI_LIBSURI_SYS_DIR	"/libsuri/"

/*
 * Public opague suri handle for dealing with suri objects
 */
typedef struct __suri_handle *suri_handle_t;

/*
 * suri handle states describing the state of the associated storage object.
 */
typedef enum suri_state {
	SURI_STATE_INVALID = 0,
	SURI_STATE_ALLOCATED,
	SURI_STATE_PARSED,
	SURI_STATE_MAPPED,
	SURI_STATE_MAX
} suri_state_t;

/*
 * suri handle types which describe the type of URI.
 */
typedef enum suri_type {
	SURI_TYPE_ANY = -1,
	SURI_TYPE_INVALID = 0,
	SURI_TYPE_DEV,
	SURI_TYPE_FILE,
	SURI_TYPE_ISCSI,
	SURI_TYPE_LU,
	SURI_TYPE_NFS,
	SURI_TYPE_MAX
} suri_type_t;

/*
 * suri specific properties for the associated storage object.
 */
typedef enum suri_prop {
	/* to indicate an error on property look-ups */
	SURI_PROP_INVALID = -1,
	/* read-only properties */
	SURI_PROP_RO_INVALID = 0,
	SURI_PROP_RO_URI_TYPE,		/* All storage uri types */
	SURI_PROP_RO_URI,		/* All storage uri types */
	SURI_PROP_RO_MAPPED_DEV,	/* All storage uri types */
	SURI_PROP_RO_MAPPED_DEVS,	/* All storage uri types */
	SURI_PROP_RO_CREATE_SUPPORTED,	/* All storage uri types */
	SURI_PROP_RO_TEARDOWN_SUPPORTED, /* All storage uri types */
	SURI_PROP_RO_PATH,		/* types: dev, file, nfs */
	SURI_PROP_RO_INITIATOR,		/* types: lu */
	SURI_PROP_RO_TARGET,		/* types: lu, iscsi */
	SURI_PROP_RO_LUNAME,		/* types: iscsi, lu */
	SURI_PROP_RO_LUN,		/* types: iscsi */
	SURI_PROP_RO_HOSTNAME,		/* types: iscsi, nfs, file */
	SURI_PROP_RO_PORT,		/* types: iscsi, nfs */
	SURI_PROP_RO_USER,		/* types: file, nfs */
	SURI_PROP_RO_GROUP,		/* types: file, nfs */
	SURI_PROP_RO_MOUNTPOINT,	/* types: nfs */
	SURI_PROP_RO_MAX,
	/* read-write properties */
	SURI_PROP_RW_INVALID = 0x1000,
	SURI_PROP_RW_CREATE_SIZE,	/* types: file, nfs */
	SURI_PROP_RW_FILE_PERMS,	/* types: file, nfs */
	SURI_PROP_RW_MOUNT_OPTIONS,	/* types: nfs */
	SURI_PROP_RW_MOUNTPOINT_PREFIX,	/* types: nfs */
	SURI_PROP_RW_MAX
} suri_prop_t;

/*
 * Property validation macros
 */
#define	SURI_VALID_RO_PROP(x) \
	(((x) > SURI_PROP_RO_INVALID) && ((x) < SURI_PROP_RO_MAX))

#define	SURI_VALID_RW_PROP(x) \
	(((x) > SURI_PROP_RW_INVALID) && ((x) < SURI_PROP_RW_MAX))

#define	SURI_VALID_PROP(x) \
	(SURI_VALID_RO_PROP(x) || SURI_VALID_RW_PROP(x))

/*
 * The suri operation errors are used as exit codes from libsuri/suriadm
 * so all error codes must be between 0 and 255.
 */
typedef enum suri_err {
	ESURI_OK = 0,			/* op success */
	ESURI_ERR = 200,		/* generic error */
	ESURI_PARSE,			/* invalid suri, parsing failed */
	ESURI_LU_INUSE,			/* logical unit is in use */
	ESURI_NOMEM,			/* like ENOMEM */
	ESURI_NAMETOOLONG,		/* like ENAMETOOLONG */
	ESURI_NOTSUP,			/* like ENOTSUP */
	ESURI_NOENT,			/* like ENOENT */
	ESURI_BUSY,			/* like EBUSY */
	ESURI_NOSLICE,			/* internal error */
	ESURI_EXIST,			/* like EEXIST */
	ESURI_NOSPC,			/* like ENOSPC */
	ESURI_PERM,			/* like EPERM */
	ESURI_ACCES,			/* like EACCES */
	ESURI_NOENT_IDENTITY,		/* map exists with different uid/gid */
	ESURI_OPT_INVAL,		/* Invalid mount option */
	ESURI_TIMEDOUT			/* like ETIMEDOUT */
} suri_err_t;

/*
 * suri handle alloc/free
 */
extern suri_handle_t suri_alloc(void);
extern void suri_free(suri_handle_t);

/*
 * suri handle error management interfaces
 *
 * libsuri(3LIB) error model is modeled after libzfs(3LIB). Two error strings
 * are used to provide rich error reporting. One string is an action string,
 * giving information on what failed ("Failed to parse URI"), and the other
 * string is a description, giving information on why it failed ("Unsupported
 * URI type"). Two different strings are provided since it is desirable to
 * distinguish between "what" and "why".
 *
 * Some operations that succeed may still return warnings.
 */
extern suri_err_t suri_err_code(suri_handle_t);
extern const char *suri_err_action(suri_handle_t);
extern const char *suri_err_description(suri_handle_t);
extern char **suri_warning(suri_handle_t);

/*
 * suri handle management interfaces
 */
extern suri_state_t suri_get_state(suri_handle_t);
extern suri_type_t suri_get_type(suri_handle_t);
extern suri_err_t suri_parse(suri_handle_t, const char *, nvlist_t *);
extern suri_err_t suri_map(suri_handle_t, nvlist_t *);
extern suri_err_t suri_lookup_mapping(suri_handle_t, nvlist_t *);
extern suri_err_t suri_lookup_uri(suri_type_t, nvlist_t *, suri_handle_t **);
extern suri_err_t suri_lookup_uri_all(nvlist_t *, suri_handle_t **);
extern suri_err_t suri_unmap(suri_handle_t, nvlist_t *, boolean_t);
extern suri_err_t suri_create(suri_handle_t, nvlist_t *);
extern suri_err_t suri_destroy(suri_handle_t, nvlist_t *);
extern suri_err_t suri_normalize(suri_handle_t, nvlist_t *);

/*
 * suri property query interfaces
 */
extern boolean_t suri_prop_valid(suri_handle_t, suri_prop_t);
extern boolean_t suri_prop_defined(suri_handle_t, suri_prop_t);
extern const char *suri_get_prop_str(suri_handle_t, suri_prop_t);
extern uint64_t suri_get_prop_uint64(suri_handle_t, suri_prop_t);
extern boolean_t suri_get_prop_bool(suri_handle_t, suri_prop_t);
extern const char *suri_prop_to_name(suri_prop_t);
extern const char *suri_prop_to_description(suri_prop_t);
extern suri_prop_t suri_name_to_prop(const char *);
extern size_t suri_get_mvprop_count(suri_handle_t, suri_prop_t);
extern size_t suri_get_mvprop_str_width(suri_handle_t, suri_prop_t);
extern const char **suri_get_mvprop_str(suri_handle_t, suri_prop_t);

/*
 * suri helper functions
 */
extern const char *suri_type_to_name(suri_type_t);
extern suri_type_t suri_name_to_type(const char *);

#ifdef	__cplusplus
}
#endif

#endif	/* _SURI_H */