Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
/*	$NetBSD: iscsid_globals.h,v 1.9 2016/05/30 22:02:41 joerg Exp $	*/

/*-
 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Wasabi Systems, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ISCSID_GLOBALS_H
#define _ISCSID_GLOBALS_H

#ifndef _THREAD_SAFE
#define _THREAD_SAFE 1
#endif

#include <sys/queue.h>
#include <sys/scsiio.h>
#include <sys/param.h>

#include <uvm/uvm_param.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <signal.h>

#ifndef ISCSI_NOTHREAD
#include <pthread.h>
#endif

#include <iscsi.h>
#include <iscsi_ioctl.h>

#include "iscsid.h"

/* -------------------------  Global Constants  ----------------------------- */

/* Version information */

#define INTERFACE_VERSION	2
#define VERSION_MAJOR		3
#define VERSION_MINOR		1
#define VERSION_STRING		"NetBSD iSCSI Software Initiator Daemon 20110407 "

/* Sizes for the static request and response buffers. */
/* 8k should be more than enough for both. */
#define REQ_BUFFER_SIZE    8192
#define RSP_BUFFER_SIZE    8192

#define ISCSI_DEFAULT_PORT 3260
#define ISCSI_DEFAULT_ISNS_PORT 3205

/* ---------------------------  Global Types  ------------------------------- */

#ifndef TRUE
typedef int boolean_t;
#define	TRUE	1
#define	FALSE	0
#endif


/*
 * The generic list entry.
 * Almost all lists in the daemon use this structure as the base for
 * list processing. It contains both a numeric ID and a symbolic name.
 * Using the same structure for all lists greatly simplifies processing.
 *
 * All structures that will be linked into searchable lists have to define
 * their first structure field as "generic_entry_t entry".
*/

struct generic_entry_s
{
	TAILQ_ENTRY(generic_entry_s) link;	/* the list link */
	iscsid_sym_id_t sid;		/* the entry ID and name */
};

typedef struct generic_entry_s generic_entry_t;
TAILQ_HEAD(generic_list_s, generic_entry_s);
typedef struct generic_list_s generic_list_t;

/*
 * The iSNS list structure.
 * This structure contains the list of iSNS servers that have been added
 */

struct isns_s
{
	generic_entry_t entry;		/* global list link */

	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* iSNS Server Address */
	uint16_t port;				/* Port (0 = default) */

	int sock;					/* socket if registered, else -1 */
	/* following fields only valid if sock >= 0 */
	uint8_t reg_iscsi_name[ISCSI_STRING_LENGTH];	/* Registered ISCSI Name */
	uint8_t reg_entity_id[ISCSI_STRING_LENGTH];	/* Registered Entity Identifier */
	uint8_t reg_ip_addr[16];	/* registered IP address */
	uint32_t reg_ip_port;		/* registered IP port */
};


TAILQ_HEAD(isns_list_s, isns_s);
typedef struct isns_s isns_t;
typedef struct isns_list_s isns_list_t;


/*
 *  The initiator portal list structure.
 */

typedef struct initiator_s initiator_t;

struct initiator_s
{
	generic_entry_t entry;		/* global list link */

	uint8_t address[ISCSI_ADDRESS_LENGTH];	/* address */
	uint32_t active_connections;	/* connection count */
};

TAILQ_HEAD(initiator_list_s, initiator_s);
typedef struct initiator_list_s initiator_list_t;


/*
 * The portal structure.
 * This structure is linked into two lists - a global portal list (this list
 * is used for searches and to verify unique IDs) and a portal group list
 * attached to the owning target.
 */

typedef enum
{
	PORTAL_TYPE_STATIC = 0,
	PORTAL_TYPE_SENDTARGET = 1,
	PORTAL_TYPE_ISNS = 2,
	PORTAL_TYPE_REFRESHING = 99
} iscsi_portal_types_t;
/*
   PORTAL_TYPE_STATIC
      Indicates that target was statically added
   PORTAL_TYPE_SENDTARGET
      Indicates that target was added as result of SendTargets discovery
   PORTAL_TYPE_ISNS
      Indicates that target was added as result of iSNS discovery
   PORTAL_TYPE_REFRESHING
      Discovered portals are set to this when we are refreshing
      (via REFRESH_TARGETS). As a portal is discovered, its type is reset to
      SENDTARGET or ISNS, so any portals which remain set to REFRESHING were not
      discovered and thus can be removed.
*/

typedef struct portal_s portal_t;
typedef struct portal_group_s portal_group_t;
typedef struct target_s target_t;
typedef struct send_target_s send_target_t;

struct portal_s
{
	generic_entry_t entry;		/* global list link */

	  TAILQ_ENTRY(portal_s) group_list;	/* group list link */

	iscsi_portal_address_t addr;	/* address */
	iscsid_portal_options_t options; /* portal options (override target options) */
	target_t *target;			/* back pointer to target */
	portal_group_t *group;		/* back pointer to group head */
	iscsi_portal_types_t portaltype;   /* Type of portal (how it was discovered) */
	uint32_t discoveryid;		/* ID of sendtargets or isnsserver */
	uint32_t active_connections; /* Number of connections active on this portal */
};

TAILQ_HEAD(portal_list_s, portal_s);
typedef struct portal_list_s portal_list_t;


/*
 * The portal group structure.
 * This structure is not searchable, and has no generic list entry field.
 * It links all portals with the same group tag to the owning target.
*/

struct portal_group_s
{
	TAILQ_ENTRY(portal_group_s) groups;	/* link to next group */

	portal_list_t portals;		/* the list of portals for this tag */

	uint32_t tag;				/* the group tag */
	u_short num_portals;		/* the number of portals in this list */
};

TAILQ_HEAD(portal_group_list_s, portal_group_s);
typedef struct portal_group_list_s portal_group_list_t;


/*
 * The target structure.
 * Contains target information including connection and authentication options.
 *****************************************************************************
 * WARNING: This structure is used interchangeably with a send_target structure
 *          in many routines dealing with targets to avoid duplicating code.
 *          The first fields in both structures up to and including
 *          the authentication options MUST match for this to work.
 *          If you change one, you MUST change the other accordingly.
 *****************************************************************************
*/

struct target_s
{
	generic_entry_t entry;		/* global list link */

	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */

	u_short num_portals;		/* the number of portals */
	u_short num_groups;			/* the number of groups */

	iscsid_get_set_target_options_t options;	/* connection options */
	iscsid_set_target_authentication_req_t auth;	/* authentication options */

	portal_group_list_t group_list;	/* the list of portal groups */
};

TAILQ_HEAD(target_list_s, target_s);
typedef struct target_list_s target_list_t;


/*
 * The Send Target structure.
 * Contains target information including connection and authentication options
 * plus a single portal.
 *****************************************************************************
 * WARNING: This structure is used interchangeably with a target structure
 *          in many routines dealing with targets to avoid duplicating code.
 *          The first fields in both structures up to and including
 *          the authentication options MUST match for this to work.
 *          If you change one, you MUST change the other accordingly.
 *****************************************************************************
 */

struct send_target_s
{
	generic_entry_t entry;		/* global list link */

	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */

	u_short num_portals;		/* the number of portals */
	u_short num_groups;			/* the number of groups */
	/* */
	iscsid_get_set_target_options_t options;	/* connection options */
	iscsid_set_target_authentication_req_t auth;	/* authentication options */

	iscsi_portal_address_t addr;	/* address */
};

TAILQ_HEAD(send_target_list_s, send_target_s);
typedef struct send_target_list_s send_target_list_t;

/*
   Target and Portal information maintained in the connection structure.
*/

struct target_info_s
{
	iscsid_sym_id_t sid;		/* the entry ID and name */
	uint8_t TargetName[ISCSI_STRING_LENGTH];	/* TargetName */
	uint8_t TargetAlias[ISCSI_STRING_LENGTH];	/* TargetAlias */
	iscsid_get_set_target_options_t options;	/* connection options */
	iscsid_set_target_authentication_req_t auth;	/* authentication options */
};
typedef struct target_info_s target_info_t;


struct portal_info_s
{
	iscsid_sym_id_t sid;		/* the entry ID and name */
	iscsi_portal_address_t addr;	/* address */
};
typedef struct portal_info_s portal_info_t;

/*
   Per connection data: the connection structure.
*/

typedef struct connection_s connection_t;
typedef struct session_s session_t;


struct connection_s
{
	generic_entry_t entry;		/* connection list link */

	session_t *session;			/* back pointer to the owning session */
	target_info_t target;		/* connected target */
	portal_info_t portal;		/* connected portal */
	uint32_t initiator_id;		/* connected initiator portal */

	iscsi_login_parameters_t loginp;	/* Login parameters for recovery */
};


/*
   Per session data: the session structure
*/

struct session_s
{
	generic_entry_t entry;		/* global list link */

	target_info_t target;		/* connected target */
	iscsi_login_session_type_t login_type;	/* session type */

	uint32_t max_connections;	/* maximum connections */
	uint32_t num_connections;	/* currently active connections */
	generic_list_t connections;	/* the list of connections */
};

/* the session list type */

TAILQ_HEAD(session_list_s, session_s);
typedef struct session_list_s session_list_t;


/* list head with entry count */

typedef struct
{
	generic_list_t list;
	int num_entries;
} list_head_t;

/* -------------------------  Global Variables  ----------------------------- */

/* In iscsid_main.c */

int driver;						/* the driver's file desc */
int client_sock;				/* the client communication socket */

list_head_t list[NUM_DAEMON_LISTS];	/* the lists this daemon keeps */

#ifndef ISCSI_NOTHREAD
pthread_t event_thread;			/* event handler thread ID */
pthread_mutex_t sesslist_lock;	/* session list lock */
#endif

/* in iscsid_discover.c */

iscsid_set_node_name_req_t node_name;


/* -------------------------  Global Functions  ----------------------------- */

/* Debugging stuff */

extern int debug_level;

#define DEBOUT(x) iscsid_log x
#define DEB(lev,x) { if (debug_level >= lev) iscsid_log x ; }
void iscsid_log(const char *, ...) __printflike(1, 2);

/* Session list protection shortcuts */

#define LOCK_SESSIONS   pthread_mutex_lock(&sesslist_lock) 
#define UNLOCK_SESSIONS pthread_mutex_unlock(&sesslist_lock)

/* Check whether ID is present */

#define NO_ID(sid) (!(sid)->id && !(sid)->name[0])

/* iscsid_main.c */

iscsid_response_t *make_rsp(size_t, iscsid_response_t **, int *);

/* iscsid_lists.c */

generic_entry_t *find_id(generic_list_t *, uint32_t);
generic_entry_t *find_name(generic_list_t *, uint8_t *);
generic_entry_t *find_sym_id(generic_list_t *, iscsid_sym_id_t *);
uint32_t get_id(generic_list_t *, iscsid_sym_id_t *);
target_t *find_target(iscsid_list_kind_t, iscsid_sym_id_t *);
target_t *find_TargetName(iscsid_list_kind_t, uint8_t *);
portal_t *find_portal_by_addr(target_t *, iscsi_portal_address_t *);
send_target_t *find_send_target_by_addr(iscsi_portal_address_t *);

#define find_isns_id(id) \
   (isns_t *)(void *)find_id(&list [ISNS_LIST].list, id)
#define find_session_id(id) \
   (session_t *)(void *)find_id(&list [SESSION_LIST].list, id)
#define find_connection_id(session, id) \
   (connection_t *)(void *)find_id(&session->connections, id)
#define find_portal_id(id) \
   (portal_t *)(void *)find_id(&list [PORTAL_LIST].list, id)
#define find_target_id(lst, id) \
   (target_t *)(void *)find_id(&list [lst].list, id)
#define find_send_target_id(id) \
   (send_target_t *)(void *)find_id(&list [SEND_TARGETS_LIST].list, id)
#define find_initiator_id(id) \
   (initiator_t *)(void *)find_id(&list [INITIATOR_LIST].list, id)
#define find_isns_name(name) \
   (isns_t *)(void *)find_name(&list [ISNS_LIST].list, name)
#define find_session_name(name) \
   (session_t *)(void *)find_name(&list [SESSION_LIST].list, name)
#define find_connection_name(session, name) \
   (connection_t *)(void *)find_name(&session->connections, name)
#define find_portal_name(name) \
   (portal_t *)(void *)find_name(&list [PORTAL_LIST].list, name)
#define find_target_symname(lst, name) \
   (target_t *)(void *)find_name(&list [lst].list, name)
#define find_initiator_name(name) \
   (initiator_t *)(void *)find_name(&list [INITIATOR_LIST].list, name)
#define find_isns(sid) \
   (isns_t *)(void *)find_sym_id(&list [ISNS_LIST].list, sid)
#define find_session(sid) \
   (session_t *)(void *)find_sym_id(&list [SESSION_LIST].list, sid)
#define find_connection(session, sid) \
   (connection_t *)(void *)find_sym_id(&session->connections, sid)
#define find_portal(sid) \
   (portal_t *)(void *)find_sym_id(&list [PORTAL_LIST].list, sid)
#define find_initiator(sid) \
   (initiator_t *)(void *)find_sym_id(&list [INITIATOR_LIST].list, sid)

void get_list(iscsid_get_list_req_t *, iscsid_response_t **, int *);
void search_list(iscsid_search_list_req_t *, iscsid_response_t **, int *);

void get_session_list(iscsid_response_t **, int *);
void get_connection_info(iscsid_get_connection_info_req_t *,
						 iscsid_response_t **, int *);
void get_connection_list(iscsid_sym_id_t *, iscsid_response_t **, int *);

void add_initiator_portal(iscsid_add_initiator_req_t *, iscsid_response_t **,
						  int *);
uint32_t remove_initiator_portal(iscsid_sym_id_t *);
void get_initiator_portal(iscsid_sym_id_t *, iscsid_response_t **, int *);
initiator_t *select_initiator(void);

void event_kill_session(uint32_t);
void event_kill_connection(uint32_t, uint32_t);

/* iscsid_targets.c */

void add_target(iscsid_add_target_req_t *, iscsid_response_t **, int *);
uint32_t set_target_options(iscsid_get_set_target_options_t *);
uint32_t set_target_auth(iscsid_set_target_authentication_req_t *);
void add_portal(iscsid_add_portal_req_t *, iscsid_response_t **, int *);
void delete_portal(portal_t *, boolean_t);

void get_target_info(iscsid_list_id_t *, iscsid_response_t **, int *);
void get_portal_info(iscsid_list_id_t *, iscsid_response_t **, int *);
uint32_t remove_target(iscsid_list_id_t *);
uint32_t refresh_targets(iscsid_refresh_req_t *);
target_t *add_discovered_target(uint8_t *, iscsi_portal_address_t *,
								iscsi_portal_types_t, uint32_t);

/* iscsid_driverif.c */

boolean_t register_event_handler(void);
void deregister_event_handler(void);
void *event_handler(void *);

uint32_t set_node_name(iscsid_set_node_name_req_t *);
void log_in(iscsid_login_req_t *, iscsid_response_t *);
void add_connection(iscsid_login_req_t *, iscsid_response_t *);
uint32_t send_targets(uint32_t, uint8_t **, uint32_t *);
uint32_t log_out(iscsid_sym_id_t *);
uint32_t remove_connection(iscsid_remove_connection_req_t *);
void get_version(iscsid_response_t **, int *);

/* iscsid_discover.c */

#ifndef ISCSI_MINIMAL
void add_isns_server(iscsid_add_isns_server_req_t *, iscsid_response_t **,
					 int *);
void get_isns_server(iscsid_sym_id_t *, iscsid_response_t **, int *);
uint32_t refresh_isns_server(uint32_t);
uint32_t remove_isns_server(iscsid_sym_id_t *);
void dereg_all_isns_servers(void);
#endif

#endif /* !_ISCSID_GLOBALS_H */