Home | History | Annotate | Line # | Download | only in iscsid
iscsid_globals.h revision 1.3
      1 /*	$NetBSD: iscsid_globals.h,v 1.3 2011/11/17 16:20:47 joerg Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Wasabi Systems, Inc.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _ISCSID_GLOBALS_H
     33 #define _ISCSID_GLOBALS_H
     34 
     35 #ifndef _THREAD_SAFE
     36 #define _THREAD_SAFE 1
     37 #endif
     38 
     39 #include <sys/queue.h>
     40 #include <sys/scsiio.h>
     41 #include <sys/param.h>
     42 
     43 #include <uvm/uvm_param.h>
     44 
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <unistd.h>
     49 #include <errno.h>
     50 
     51 #ifndef ISCSI_NOTHREAD
     52 #include <pthread.h>
     53 #endif
     54 
     55 #include <iscsi.h>
     56 #include <iscsi_ioctl.h>
     57 
     58 #include "iscsid.h"
     59 
     60 /* -------------------------  Global Constants  ----------------------------- */
     61 
     62 /* Version information */
     63 
     64 #define INTERFACE_VERSION	2
     65 #define VERSION_MAJOR		3
     66 #define VERSION_MINOR		1
     67 #define VERSION_STRING		"NetBSD iSCSI Software Initiator Daemon 20110407 "
     68 
     69 /* Sizes for the static request and response buffers. */
     70 /* 8k should be more than enough for both. */
     71 #define REQ_BUFFER_SIZE    8192
     72 #define RSP_BUFFER_SIZE    8192
     73 
     74 #define ISCSI_DEFAULT_PORT 3260
     75 #define ISCSI_DEFAULT_ISNS_PORT 3205
     76 
     77 /* ---------------------------  Global Types  ------------------------------- */
     78 
     79 #ifndef TRUE
     80 typedef int boolean_t;
     81 #define	TRUE	1
     82 #define	FALSE	0
     83 #endif
     84 
     85 
     86 /*
     87  * The generic list entry.
     88  * Almost all lists in the daemon use this structure as the base for
     89  * list processing. It contains both a numeric ID and a symbolic name.
     90  * Using the same structure for all lists greatly simplifies processing.
     91  *
     92  * All structures that will be linked into searchable lists have to define
     93  * their first structure field as "generic_entry_t entry".
     94 */
     95 
     96 struct generic_entry_s
     97 {
     98 	TAILQ_ENTRY(generic_entry_s) link;	/* the list link */
     99 	iscsid_sym_id_t sid;		/* the entry ID and name */
    100 };
    101 
    102 typedef struct generic_entry_s generic_entry_t;
    103 TAILQ_HEAD(generic_list_s, generic_entry_s);
    104 typedef struct generic_list_s generic_list_t;
    105 
    106 /*
    107  * The iSNS list structure.
    108  * This structure contains the list of iSNS servers that have been added
    109  */
    110 
    111 struct isns_s
    112 {
    113 	generic_entry_t entry;		/* global list link */
    114 
    115 	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* iSNS Server Address */
    116 	uint16_t port;				/* Port (0 = default) */
    117 
    118 	int sock;					/* socket if registered, else -1 */
    119 	/* following fields only valid if sock >= 0 */
    120 	uint8_t reg_iscsi_name[ISCSI_STRING_LENGTH];	/* Registered ISCSI Name */
    121 	uint8_t reg_entity_id[ISCSI_STRING_LENGTH];	/* Registered Entity Identifier */
    122 	uint8_t reg_ip_addr[16];	/* registered IP address */
    123 	uint32_t reg_ip_port;		/* registered IP port */
    124 };
    125 
    126 
    127 TAILQ_HEAD(isns_list_s, isns_s);
    128 typedef struct isns_s isns_t;
    129 typedef struct isns_list_s isns_list_t;
    130 
    131 
    132 /*
    133  *  The initiator portal list structure.
    134  */
    135 
    136 typedef struct initiator_s initiator_t;
    137 
    138 struct initiator_s
    139 {
    140 	generic_entry_t entry;		/* global list link */
    141 
    142 	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* address */
    143 	uint32_t active_connections;	/* connection count */
    144 };
    145 
    146 TAILQ_HEAD(initiator_list_s, initiator_s);
    147 typedef struct initiator_list_s initiator_list_t;
    148 
    149 
    150 /*
    151  * The portal structure.
    152  * This structure is linked into two lists - a global portal list (this list
    153  * is used for searches and to verify unique IDs) and a portal group list
    154  * attached to the owning target.
    155  */
    156 
    157 typedef enum
    158 {
    159 	PORTAL_TYPE_STATIC = 0,
    160 	PORTAL_TYPE_SENDTARGET = 1,
    161 	PORTAL_TYPE_ISNS = 2,
    162 	PORTAL_TYPE_REFRESHING = 99
    163 } iscsi_portal_types_t;
    164 /*
    165    PORTAL_TYPE_STATIC
    166       Indicates that target was statically added
    167    PORTAL_TYPE_SENDTARGET
    168       Indicates that target was added as result of SendTargets discovery
    169    PORTAL_TYPE_ISNS
    170       Indicates that target was added as result of iSNS discovery
    171    PORTAL_TYPE_REFRESHING
    172       Discovered portals are set to this when we are refreshing
    173       (via REFRESH_TARGETS). As a portal is discovered, its type is reset to
    174       SENDTARGET or ISNS, so any portals which remain set to REFRESHING were not
    175       discovered and thus can be removed.
    176 */
    177 
    178 typedef struct portal_s portal_t;
    179 typedef struct portal_group_s portal_group_t;
    180 typedef struct target_s target_t;
    181 typedef struct send_target_s send_target_t;
    182 
    183 struct portal_s
    184 {
    185 	generic_entry_t entry;		/* global list link */
    186 
    187 	  TAILQ_ENTRY(portal_s) group_list;	/* group list link */
    188 
    189 	iscsi_portal_address_t addr;	/* address */
    190 	iscsid_portal_options_t options; /* portal options (override target options) */
    191 	target_t *target;			/* back pointer to target */
    192 	portal_group_t *group;		/* back pointer to group head */
    193 	iscsi_portal_types_t portaltype;   /* Type of portal (how it was discovered) */
    194 	uint32_t discoveryid;		/* ID of sendtargets or isnsserver */
    195 	uint32_t active_connections; /* Number of connections active on this portal */
    196 };
    197 
    198 TAILQ_HEAD(portal_list_s, portal_s);
    199 typedef struct portal_list_s portal_list_t;
    200 
    201 
    202 /*
    203  * The portal group structure.
    204  * This structure is not searchable, and has no generic list entry field.
    205  * It links all portals with the same group tag to the owning target.
    206 */
    207 
    208 struct portal_group_s
    209 {
    210 	TAILQ_ENTRY(portal_group_s) groups;	/* link to next group */
    211 
    212 	portal_list_t portals;		/* the list of portals for this tag */
    213 
    214 	uint32_t tag;				/* the group tag */
    215 	u_short num_portals;		/* the number of portals in this list */
    216 };
    217 
    218 TAILQ_HEAD(portal_group_list_s, portal_group_s);
    219 typedef struct portal_group_list_s portal_group_list_t;
    220 
    221 
    222 /*
    223  * The target structure.
    224  * Contains target information including connection and authentication options.
    225  *****************************************************************************
    226  * WARNING: This structure is used interchangeably with a send_target structure
    227  *          in many routines dealing with targets to avoid duplicating code.
    228  *          The first fields in both structures up to and including
    229  *          the authentication options MUST match for this to work.
    230  *          If you change one, you MUST change the other accordingly.
    231  *****************************************************************************
    232 */
    233 
    234 struct target_s
    235 {
    236 	generic_entry_t entry;		/* global list link */
    237 
    238 	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
    239 	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
    240 
    241 	u_short num_portals;		/* the number of portals */
    242 	u_short num_groups;			/* the number of groups */
    243 
    244 	iscsid_get_set_target_options_t options;	/* connection options */
    245 	iscsid_set_target_authentication_req_t auth;	/* authentication options */
    246 
    247 	portal_group_list_t group_list;	/* the list of portal groups */
    248 };
    249 
    250 TAILQ_HEAD(target_list_s, target_s);
    251 typedef struct target_list_s target_list_t;
    252 
    253 
    254 /*
    255  * The Send Target structure.
    256  * Contains target information including connection and authentication options
    257  * plus a single portal.
    258  *****************************************************************************
    259  * WARNING: This structure is used interchangeably with a target structure
    260  *          in many routines dealing with targets to avoid duplicating code.
    261  *          The first fields in both structures up to and including
    262  *          the authentication options MUST match for this to work.
    263  *          If you change one, you MUST change the other accordingly.
    264  *****************************************************************************
    265  */
    266 
    267 struct send_target_s
    268 {
    269 	generic_entry_t entry;		/* global list link */
    270 
    271 	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
    272 	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
    273 
    274 	u_short num_portals;		/* the number of portals */
    275 	u_short num_groups;			/* the number of groups */
    276 	/* */
    277 	iscsid_get_set_target_options_t options;	/* connection options */
    278 	iscsid_set_target_authentication_req_t auth;	/* authentication options */
    279 
    280 	iscsi_portal_address_t addr;	/* address */
    281 };
    282 
    283 TAILQ_HEAD(send_target_list_s, send_target_s);
    284 typedef struct send_target_list_s send_target_list_t;
    285 
    286 /*
    287    Target and Portal information maintained in the connection structure.
    288 */
    289 
    290 struct target_info_s
    291 {
    292 	iscsid_sym_id_t sid;		/* the entry ID and name */
    293 	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
    294 	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
    295 	iscsid_get_set_target_options_t options;	/* connection options */
    296 	iscsid_set_target_authentication_req_t auth;	/* authentication options */
    297 };
    298 typedef struct target_info_s target_info_t;
    299 
    300 
    301 struct portal_info_s
    302 {
    303 	iscsid_sym_id_t sid;		/* the entry ID and name */
    304 	iscsi_portal_address_t addr;	/* address */
    305 };
    306 typedef struct portal_info_s portal_info_t;
    307 
    308 /*
    309    Per connection data: the connection structure.
    310 */
    311 
    312 typedef struct connection_s connection_t;
    313 typedef struct session_s session_t;
    314 
    315 
    316 struct connection_s
    317 {
    318 	generic_entry_t entry;		/* connection list link */
    319 
    320 	session_t *session;			/* back pointer to the owning session */
    321 	target_info_t target;		/* connected target */
    322 	portal_info_t portal;		/* connected portal */
    323 	uint32_t initiator_id;		/* connected initiator portal */
    324 
    325 	iscsi_login_parameters_t loginp;	/* Login parameters for recovery */
    326 };
    327 
    328 
    329 /*
    330    Per session data: the session structure
    331 */
    332 
    333 struct session_s
    334 {
    335 	generic_entry_t entry;		/* global list link */
    336 
    337 	target_info_t target;		/* connected target */
    338 	iscsi_login_session_type_t login_type;	/* session type */
    339 
    340 	uint32_t max_connections;	/* maximum connections */
    341 	uint32_t num_connections;	/* currently active connections */
    342 	generic_list_t connections;	/* the list of connections */
    343 };
    344 
    345 /* the session list type */
    346 
    347 TAILQ_HEAD(session_list_s, session_s);
    348 typedef struct session_list_s session_list_t;
    349 
    350 
    351 /* list head with entry count */
    352 
    353 typedef struct
    354 {
    355 	generic_list_t list;
    356 	int num_entries;
    357 } list_head_t;
    358 
    359 /* -------------------------  Global Variables  ----------------------------- */
    360 
    361 /* In iscsid_main.c */
    362 
    363 int driver;						/* the driver's file desc */
    364 int client_sock;				/* the client communication socket */
    365 
    366 list_head_t list[NUM_DAEMON_LISTS];	/* the lists this daemon keeps */
    367 
    368 #ifndef ISCSI_NOTHREAD
    369 pthread_t event_thread;			/* event handler thread ID */
    370 pthread_mutex_t sesslist_lock;	/* session list lock */
    371 #endif
    372 
    373 /* in iscsid_discover.c */
    374 
    375 iscsid_set_node_name_req_t node_name;
    376 
    377 
    378 /* -------------------------  Global Functions  ----------------------------- */
    379 
    380 /* Debugging stuff */
    381 
    382 #ifdef ISCSI_DEBUG
    383 
    384 int debug_level;				/* How much info to display */
    385 
    386 #define DEBOUT(x) printf x
    387 #define DEB(lev,x) {if (debug_level >= lev) printf x ;}
    388 
    389 #define STATIC static
    390 
    391 #else
    392 
    393 #define DEBOUT(x)
    394 #define DEB(lev,x)
    395 
    396 #define STATIC static
    397 
    398 #endif
    399 
    400 /* Session list protection shortcuts */
    401 
    402 #if 0
    403 #define LOCK_SESSIONS   verify_sessions()
    404 #define UNLOCK_SESSIONS
    405 #endif
    406 #ifdef ISCSI_NOTHREAD
    407 #define LOCK_SESSIONS   event_handler(NULL)
    408 #define UNLOCK_SESSIONS
    409 #else
    410 #define LOCK_SESSIONS   pthread_mutex_lock(&sesslist_lock)
    411 #define UNLOCK_SESSIONS pthread_mutex_unlock(&sesslist_lock)
    412 #endif
    413 
    414 /* Check whether ID is present */
    415 
    416 #define NO_ID(sid) (!(sid)->id && !(sid)->name[0])
    417 
    418 /* iscsid_main.c */
    419 
    420 iscsid_response_t *make_rsp(size_t, iscsid_response_t **, int *);
    421 void exit_daemon(void) __dead;
    422 
    423 /* iscsid_lists.c */
    424 
    425 generic_entry_t *find_id(generic_list_t *, uint32_t);
    426 generic_entry_t *find_name(generic_list_t *, uint8_t *);
    427 generic_entry_t *find_sym_id(generic_list_t *, iscsid_sym_id_t *);
    428 uint32_t get_id(generic_list_t *, iscsid_sym_id_t *);
    429 target_t *find_target(iscsid_list_kind_t, iscsid_sym_id_t *);
    430 target_t *find_TargetName(iscsid_list_kind_t, uint8_t *);
    431 portal_t *find_portal_by_addr(target_t *, iscsi_portal_address_t *);
    432 send_target_t *find_send_target_by_addr(iscsi_portal_address_t *);
    433 
    434 #define find_isns_id(id) \
    435    (isns_t *)(void *)find_id(&list [ISNS_LIST].list, id)
    436 #define find_session_id(id) \
    437    (session_t *)(void *)find_id(&list [SESSION_LIST].list, id)
    438 #define find_connection_id(session, id) \
    439    (connection_t *)(void *)find_id(&session->connections, id)
    440 #define find_portal_id(id) \
    441    (portal_t *)(void *)find_id(&list [PORTAL_LIST].list, id)
    442 #define find_target_id(lst, id) \
    443    (target_t *)(void *)find_id(&list [lst].list, id)
    444 #define find_send_target_id(id) \
    445    (send_target_t *)(void *)find_id(&list [SEND_TARGETS_LIST].list, id)
    446 #define find_initiator_id(id) \
    447    (initiator_t *)(void *)find_id(&list [INITIATOR_LIST].list, id)
    448 #define find_isns_name(name) \
    449    (isns_t *)(void *)find_name(&list [ISNS_LIST].list, name)
    450 #define find_session_name(name) \
    451    (session_t *)(void *)find_name(&list [SESSION_LIST].list, name)
    452 #define find_connection_name(session, name) \
    453    (connection_t *)(void *)find_name(&session->connections, name)
    454 #define find_portal_name(name) \
    455    (portal_t *)(void *)find_name(&list [PORTAL_LIST].list, name)
    456 #define find_target_symname(lst, name) \
    457    (target_t *)(void *)find_name(&list [lst].list, name)
    458 #define find_initiator_name(name) \
    459    (initiator_t *)(void *)find_name(&list [INITIATOR_LIST].list, name)
    460 #define find_isns(sid) \
    461    (isns_t *)(void *)find_sym_id(&list [ISNS_LIST].list, sid)
    462 #define find_session(sid) \
    463    (session_t *)(void *)find_sym_id(&list [SESSION_LIST].list, sid)
    464 #define find_connection(session, sid) \
    465    (connection_t *)(void *)find_sym_id(&session->connections, sid)
    466 #define find_portal(sid) \
    467    (portal_t *)(void *)find_sym_id(&list [PORTAL_LIST].list, sid)
    468 #define find_initiator(sid) \
    469    (initiator_t *)(void *)find_sym_id(&list [INITIATOR_LIST].list, sid)
    470 
    471 void get_list(iscsid_get_list_req_t *, iscsid_response_t **, int *);
    472 void search_list(iscsid_search_list_req_t *, iscsid_response_t **, int *);
    473 
    474 void get_session_list(iscsid_response_t **, int *);
    475 void get_connection_info(iscsid_get_connection_info_req_t *,
    476 						 iscsid_response_t **, int *);
    477 void get_connection_list(iscsid_sym_id_t *, iscsid_response_t **, int *);
    478 
    479 void add_initiator_portal(iscsid_add_initiator_req_t *, iscsid_response_t **,
    480 						  int *);
    481 uint32_t remove_initiator_portal(iscsid_sym_id_t *);
    482 void get_initiator_portal(iscsid_sym_id_t *, iscsid_response_t **, int *);
    483 initiator_t *select_initiator(void);
    484 
    485 void event_kill_session(uint32_t);
    486 void event_kill_connection(uint32_t, uint32_t);
    487 
    488 /* iscsid_targets.c */
    489 
    490 void add_target(iscsid_add_target_req_t *, iscsid_response_t **, int *);
    491 uint32_t set_target_options(iscsid_get_set_target_options_t *);
    492 uint32_t set_target_auth(iscsid_set_target_authentication_req_t *);
    493 void add_portal(iscsid_add_portal_req_t *, iscsid_response_t **, int *);
    494 void delete_portal(portal_t *, boolean_t);
    495 
    496 void get_target_info(iscsid_list_id_t *, iscsid_response_t **, int *);
    497 void get_portal_info(iscsid_list_id_t *, iscsid_response_t **, int *);
    498 uint32_t remove_target(iscsid_list_id_t *);
    499 uint32_t refresh_targets(iscsid_refresh_req_t *);
    500 target_t *add_discovered_target(uint8_t *, iscsi_portal_address_t *,
    501 								iscsi_portal_types_t, uint32_t);
    502 
    503 /* iscsid_driverif.c */
    504 
    505 boolean_t register_event_handler(void);
    506 void deregister_event_handler(void);
    507 void *event_handler(void *);
    508 
    509 uint32_t set_node_name(iscsid_set_node_name_req_t *);
    510 void login(iscsid_login_req_t *, iscsid_response_t *);
    511 void add_connection(iscsid_login_req_t *, iscsid_response_t *);
    512 uint32_t send_targets(uint32_t, uint8_t **, uint32_t *);
    513 uint32_t logout(iscsid_sym_id_t *);
    514 uint32_t remove_connection(iscsid_remove_connection_req_t *);
    515 void get_version(iscsid_response_t **, int *);
    516 
    517 /* iscsid_discover.c */
    518 
    519 #ifndef ISCSI_MINIMAL
    520 void add_isns_server(iscsid_add_isns_server_req_t *, iscsid_response_t **,
    521 					 int *);
    522 void get_isns_server(iscsid_sym_id_t *, iscsid_response_t **, int *);
    523 uint32_t refresh_isns_server(uint32_t);
    524 uint32_t remove_isns_server(iscsid_sym_id_t *);
    525 void dereg_all_isns_servers(void);
    526 #endif
    527 
    528 #endif /* !_ISCSID_GLOBALS_H */
    529