libiscsitgt.h revision ecd6cf800b63704be73fb264c3f5b6e0dafc068d
/*
* CDDL HEADER START
*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBISCSITGT_H
#define _LIBISCSITGT_H
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Management API for the iSCSI Target.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* These includes resolve
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/iscsi_protocol.h>
#include <sys/scsi/generic/inquiry.h>
#define EUI64_SIZE 16
#define VID_SIZE 8
#define PID_SIZE 16
/*
* []------------------------------------------------------------------[]
* | Structures and enums returned by the list functions |
* []------------------------------------------------------------------[]
*/
typedef enum { LU_Offline, LU_Online } iscsit_status_t;
typedef enum { Target, Initiator, TPGT } iscsit_obj_type_t;
/*
* Logical Unit (LU) Structure.
* Each iSCSI Target has one or more Logical Units.
*/
typedef struct iscsit_lu {
/* This is the LU number for SCSI commands */
int l_num;
/* Globally unique identifier */
uint8_t l_guid[EUI64_SIZE];
/*
* VID/PID used in SCSI INQUIRY responses
*/
char l_vid[VID_SIZE],
l_pid[PID_SIZE];
/*
* Value will be one of DTYPE_DIRECT, DTYPE_SEQUENTIAL, etc ...
* Look at sys/scsi/generic/inquiry.h for full list
*/
uint8_t l_dtype;
/* Size of device in blocks */
diskaddr_t l_size;
iscsit_status_t l_status;
} iscsit_lu_t;
/*
* iSCSI Session information.
*/
typedef struct iscsit_conn {
char c_name[ISCSI_MAX_NAME_LEN],
*c_alias;
} iscsit_conn_t;
typedef struct iscsit_target {
/* This is the full IQN name of the target */
char t_name[ISCSI_MAX_NAME_LEN];
/*
* The Alias which is the same as "friendly name" used during the
* creation of the target.
*/
char *t_alias;
/*
* The number of Logical Units associated with this target.
* There will always be at least one LU with a value of 0.
* If there are more than LU the order is not guaranteed.
*/
int t_lu_count;
iscsit_lu_t **t_lu_list;
/*
* A list of initiator which may access this target. This list
* may be 0 in length.
*/
int t_acl_count;
char **t_acl_list;
/*
* Target Portal Group Tags. A value of zero for the count
* is valid.
*/
int t_tpgt_count;
char **t_tpgt_list;
/*
* The number of sessions that are currently attached to the
* target. Zero is valid.
*/
int t_conn_count;
iscsit_conn_t **t_conn_list;
} iscsit_target_t;
/*
* Information stored locally about initiators. Local initiator information
* is setup when administrators wish to control access to each target. The
* use of iSNS will be the prefered method once it's supported.
*/
typedef struct iscsit_initiator {
char i_name[ISCSI_MAX_NAME_LEN],
*i_chap_name;
/*
* While the target daemon has the CHAP secret available it's
* never returned. The CHAP name and secret can be changed at
* any time. This boolean will indicate if the CHAP secret is set
* and if so will cause the daemon to perform unidirectional
* authentication.
*/
boolean_t i_chap_secret_set;
} iscsit_initiator_t;
/*
* The list of IP addresses associated with a Target Portal Group Tag
*/
typedef struct iscsit_tpgt {
int t_ip_count;
struct sockaddr_storage **t_ip_list;
} iscsit_tpgt_t;
/*
* These are values which are used globally through the target daemon.
*/
typedef struct iscsit_admin {
/*
* This is the targets CHAP information. When an initiator needs
* to authenticate the target these values are used when creating
* the response.
*/
char *a_chap_name;
boolean_t a_chap_secret_set;
/*
* The location of the target configuration and default storage for LUs
*/
char *a_base_directory;
struct sockaddr_storage a_radius_server;
boolean_t a_radius_secret_set,
a_isns_discovery;
struct sockaddr_storage a_isns_ip;
boolean_t a_fast_write_ack;
} iscsit_admin_t;
typedef void *iscsit_handle_t;
/*
* []------------------------------------------------------------------[]
* | Funtion Prototypes |
* []------------------------------------------------------------------[]
*/
/*
* []------------------------------------------------------------------[]
* | Functions for ZFS |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_zfs_share -- advertise a ZFS volume through iSCSI
* iscsitgt_zfs_unshare -- unadvertise a ZFS volume through iSCSI
*
* dataset = this must be a valid ZFS dataset which has a "type" property
* of "volume".
*
* These functions will return 0 on success and -1 on failure setting errno
* thusly:
*
* ENODEV - dataset not found
* EINVAL - a share parameter has an invalid value
* ENOSYS - the option string cannot be understood for any other reason
*/
int iscsitgt_zfs_share(const char *dataset);
int iscsitgt_zfs_unshare(const char *dataset);
/*
* iscsitgt_zfs_is_shared -- returns 1 and 0 otherwise
*/
int iscsitgt_zfs_is_shared(const char *dataset);
/*
* []------------------------------------------------------------------[]
* | Functions to create handles which are used by methods defined below|
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_init -- Create a handle for each daemon
*
* A future release will enable this library to work to control multiple
* daemons on different hosts. For now, the argument 'host' should be
* set to NULL which will indicate the local host.
*/
iscsit_handle_t iscsitgt_init(char *host);
/*
* iscsitgt_fini -- free resources allocated by iscsitgt_init()
*/
void iscsitgt_fini(iscsit_handle_t h);
/*
* []------------------------------------------------------------------[]
* | Funtions for creating base objects |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_creat_target -- creates a new target/lu
*
* h = This is handle which indicates to which target the request is sent.
* If NULL, the target daemon on the current host is used.
* friendly_name = any ASCII string with the following restrictions.
* - it must be no more than 163 characters
* - it must only contain charcters from the set of 'a-z', 'A-Z', '0-9',
* ':', '.', or '-'
* The friendly_name will also be used as the iSCSI TargetAlias which
* is sent to the initiator as part of the log in parameters.
* lun = If the friendly_name has never been used before then lun must be 0.
* If friendly_name has already been created other luns will be created
* under that target. 0 <= lun <= 65535. NOTE: Using LUNs larger than
* 255 is not guaranteed to work for all initiators.
* size = The requested size for the device in blocks. There must be
* available space on the device for the create to succeed. size may
* be zero if, and only if, a 'backing' argument is given which exists.
* dtype = This indicates which type of emulation is performed by the
* daemon. Currently DTYPE_DIRECT, DTYPE_SEQUENTIAL, and DTYPE_UNKNOWN
* are supported. A dtype of DTYPE_UNKNOWN indicates to the daemon
* that a pass through mode should be used. For the pass through mode
* to work 'backing' must be a character device which supports the USCSI
* ioctl. For ZVOLs the dtype should be DTYPE_DIRECT.
* backing = optional location for the backing store. Normally the storage
* for the LU is created in the directory supplied to iscsit_mod_adm_store().
* If the 'backing' file name doesn't exist *and* a valid device 'size' is
* given then the backing store will be created in that location. When the
* target/lu is removed this backing store will also be removed.
*
* Return codes:
* EINVAL = one or more of the arguments are invalid
* ENOSPC = No space remains to create the backing store.
* EEXIST = A target with the same friendly_name already exists
*/
int iscsitgt_creat_target(iscsit_handle_t h, char *friendly_name,
int lun, diskaddr_t size, int dtype, char *backing);
/*
* iscsitgt_creat_initiator -- creates an initiator object
*
* Associates a fully compliant iSCSI name (IQN or EUI type) with
* a really human readable name.
*
* h = Handle used to communicate with remote target daemons. A NULL
* value may be used to indicate that the local host target daemon
* friendly_name = Any ASCII string.
* iqn_name = An initiator IQN or EUI string. There will be no validation
* of the name to determine if it complies with RFC3720. This way if
* an initiator has a poorly formed name we can still be configured to
* work with it.
*
* Return codes:
* 0 = success
* EEXIST = The friendly_name is already used.
*/
int iscsitgt_creat_initiator(iscsit_handle_t h, char *friendly_name,
char *iqn_name);
/*
* iscsitgt_creat_tpgt -- Create a Target Portal Group Tag
*
* Once a TPGT object has been created iscsitgt_add_tpgt_ip would be used
* to associate certain IP addresses with this TPGT. This is used to
* limit which NICs connections are accepted on for a given target.
* Once a TPGT is setup it can be added to a target using:
* iscsitgt_add_target_tpgt().
*
* h = See iscsitgt_creat_target
* tpgt_num = a value between 1 and 65535 inclusive
*
* Return codes:
* 0 = success
* EEXIST = A tpgt with that number already exists.
* EINVAL = TPGT must be a value between 1 and 65535 inclusive
*/
int iscsitgt_creat_tpgt(iscsit_handle_t h, int tpgt_num);
/*
* []------------------------------------------------------------------[]
* | Funtions for removing base objects |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_rem_target -- Removes a target/LU from the system
*
* Logical Unit Number 0 *must* be the last LUN removed from a target
* If not, an error will be returned. When LUN0 is removed all references
* to friendly_name are also removed from the system. e.g. Once the LU's
* are removed there's nothing else required to remove the target.
*
* h = See iscsitgt_creat_target()
* friendly_name = This is the same name used during the creation of
* the target.
* lun = Logical Unit Number
*
* Return codes:
* 0 = success
* ENOENT = either friendly_name wasn't found or lun not found
* EINVAL = attempt made to remove LUN0 while other LUs still exist.
*/
int iscsitgt_rem_target(iscsit_handle_t h, char *friendly_name,
int lun);
/*
* iscsitgt_rem_initiator -- Removes initiator object
*
* This method removes just the initiator object, but not any references
* to this object. For example let's say an initiator was called
* payroll_server and that this server was replaced with a new server
* that had the same function, but with a new IQN value and CHAP secret.
* The user of this library could then remove the initiator object
* and create a new one with the changes *without* needing to update all
* of the target objects that have a reference to 'payroll_server' in
* their ACLs. This is a security feature. If a target has a reference
* to an initiator object which doesn't exist, nobody will be able to
* log into the target. If the daemon we're to remove all references
* along with the object it would then be possible for an initiator to
* log into the target during the time the target didn't have a reference.
*
* h = See iscsitgt_creat_target()
* friendly_name = same value as that used during create.
*
* Return codes:
* 0 = success
* ENOENT = Can't find friendly_name
*/
int iscsitgt_rem_initiator(iscsit_handle_t h, char *friendly_name);
/*
* iscsitgt_rem_tpgt -- Removes a tpgt object
*
* Similar in function to iscsitgt_rem_initiator. This method only
* removes the TPGT object, but not any references to the object. This
* alows the administrator to remove an old TPGT and create a new one
* without needing to update each and every target first.
*
* h = See iscsitgt_creat_target
* tpgt_num = value used during create
*
* Return codes:
* 0 = success
* ENOENT = tpgt_num wasn't found
* EINVAL = a value outside of the accepted range for tpgt_num was used.
*/
int iscsitgt_rem_tpgt(iscsit_handle_t h, int tpgt_num);
/*
* []------------------------------------------------------------------[]
* | Funtions for adding attributes to base objects |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_add_target_initiator -- Adds an initiator object to ACL for target
*
* h = See iscsitgt_creat_target
* friendly_name = Existing target
* initiator = name of initiator object which doesn't need to exist before
* it's added.
*
* Return codes:
* 0 = success
* ENOENT = friendly_name doesn't exist.
*/
int iscsitgt_add_target_initiator(iscsit_handle_t h, char *friendly_name,
char *initiator);
/*
* iscsitgt_add_target_tpgt -- adds TPGT to the target
*
* h = See iscsitgt_creat_target()
* friendly_name = Must be a valid target object name
* tpgt_num = While the TPGT object doesn't need to exist, the value will
* be validated to see if it's within the valid range of 1 to 65535 inclusive
*
* Return codes:
* 0 = success
* ENOENT = friendly_name not found
* EINVAL = tpgt_num is not within the valid range.
*/
int iscsitgt_add_target_tpgt(iscsit_handle_t h, char *friendly_name,
int tpgt_num);
/*
* iscsitgt_add_tpgt_ip -- Adds IP address to TPGT object
*
* Return codes:
* 0 = success
* ENOENT = tpgt_num doesn't exist
* EINVAL = tpgt_num is not within the valid range
*/
int iscsitgt_add_tpgt_ip(iscsit_handle_t h, int tpgt_num,
struct sockaddr_storage *s);
/*
* []------------------------------------------------------------------[]
* | Funtions for deleting attributes from base objects |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_del_target_initiator -- Removes initiator from target ACL
*
* h = See iscsitgt_creat_target()
* friendly_name = target object
* initiator = initiator object to remove from ACL
*
* Return codes:
* 0 = success
* ENOENT = friendly_name or initiator don't exist
*/
int iscsitgt_del_target_initiator(iscsit_handle_t h, char *friendly_name,
char *initiator);
/*
* iscsitgt_del_target_tpgt -- Removes TPGT from specific target
*
* Return codes:
* 0 = success
* ENOENT = Either friendly_name or tpgt_num doesn't exist as a valid
* type
* EINVAL = tpgt_num is outside of the valid range (1 to 65535)
*/
int iscsitgt_del_target_tpgt(iscsit_handle_t h, char *friendly_name,
int tpgt_num);
/*
* iscsitgt_del_tpgt_ip -- Removes IP address from TPGT
*
* Return codes:
* 0 = success
* ENOENT = tpgt_num wasn't found or the IP address wasn't found within a valid
* tpgt
* EINVAL = tpgt_num is outside of the valid range (1 to 65535)
*/
int iscsitgt_del_tpgt_ip(iscsit_handle_t h, int tpgt_num,
struct sockaddr_storage *s);
/*
* []------------------------------------------------------------------[]
* | Funtions for modifying singular attributes for base objects |
* []------------------------------------------------------------------[]
*/
/*
* iscsitgt_mode_target_alias -- Modifies the TargetAlias associated with target
*
* By default the TargetAlias is the same as that given for the friendly_name.
* If another name is desired then it can be changed using this interface.
*
* h = See iscsitgt_creat_target()
* friendly_name = target object
*
* Return codes:
* 0 = success
* ENOENT = friendly_name doesn't exist
*/
int iscsitgt_mod_target_alias(iscsit_handle_t h, char *friendly_name,
char *alias);
int iscsitgt_mod_target_maxrec(iscsit_handle_t h, char *friendly_name,
size_t maxrecv);
int iscsitgt_mod_initiator_chap(iscsit_handle_t h,
char *friendly_name, char *chap_name, char *chap_secret);
int iscsitgt_mod_adm_store(iscsit_handle_t h, char *base);
int iscsitgt_mod_adm_chap(iscsit_handle_t h, char *chap_name,
char *chap_secret);
int iscsitgt_mod_adm_radius(iscsit_handle_t h, struct sockaddr_storage *s,
char *secret);
int iscsitgt_mod_adm_isns_discover(iscsit_handle_t h,
boolean_t find);
int iscsitgt_mod_adm_isns(iscsit_handle_t h,
struct sockaddr_storage *s);
int iscsitgt_mod_adm_fwa(iscsit_handle_t h, boolean_t enable);
/*
* []------------------------------------------------------------------[]
* | Funtions for listing objects |
* | |
* | NOTE: Each of the following function have a specific free routine |
* | which must be called to free the data. |
* []------------------------------------------------------------------[]
*/
/*
* iscsit_list_find -- returns list of specific object names.
*
* There are three types of objects which are manipulated by these
* interfaces (Target, Initiator, and TPGT). This function will return
* an array of character strings which represent all of the available
* objects of the specific type. These strings are the same ones that
* where used during the creation.
*
* NOTE: Since there's no locking a call to this this function may
* return a name which then doesn't exist when the user attempts to
* get the specific information on that object. This would be caused
* when another operator deletes an object between the first and second
* calls.
*/
char **iscsit_list_find(iscsit_handle_t h, iscsit_obj_type_t t);
void iscsit_list_free(char **list);
/*
* iscsit_list_target -- returns detailed information about a target
*/
iscsit_target_t *iscsit_list_target(iscsit_handle_t h, char *targ);
void iscsit_list_target_free(iscsit_target_t *t);
/*
* iscsit_list_initiator -- returns detailed information about an initiator
*/
iscsit_initiator_t *iscsit_list_initiator(iscsit_handle_t h, char *initiator);
void iscsit_list_initiator_free(iscsit_initiator_t *t);
/*
* iscsit_list_tpgt -- returns detailed information about a target port group
*/
iscsit_tpgt_t *iscsit_list_tpgt(iscsit_handle_t h, char *tpgt);
void iscsit_list_tpgt_free(iscsit_tpgt_t *t);
/*
* iscsit_list_adm -- returns information about the global variables used.
*/
iscsit_admin_t *iscsit_list_adm(iscsit_handle_t h);
void iscsit_list_adm_free(iscsit_admin_t *t);
/*
* Misc functions
*/
int iscsitgt_svc_online();
#ifdef __cplusplus
}
#endif
#endif /* _LIBISCSITGT_H */