xref: /netbsd-src/sbin/iscsid/iscsid_globals.h (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: iscsid_globals.h,v 1.2 2011/10/29 16:54:49 christos 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);
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