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