Annotation of embedaddon/istgt/src/istgt.h, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
1.1 misho 3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24: * SUCH DAMAGE.
25: *
26: */
27:
28: #ifndef ISTGT_H
29: #define ISTGT_H
30:
31: #ifdef HAVE_CONFIG_H
32: #include "config.h"
33: #endif
34:
35: #ifdef USE_ATOMIC
36: #ifdef HAVE_SYS_TYPES_H
37: #include <sys/types.h>
38: #endif
39: #ifdef HAVE_MACHINE_ATOMIC_H
40: #include <machine/atomic.h>
41: #endif
42: #ifdef HAVE_SYS_ATOMIC_H
43: #include <sys/atomic.h>
44: #endif
45: #endif /* USE_ATOMIC */
46:
47: #include "build.h"
48:
49: #include <pthread.h>
50: #include <signal.h>
51: #include "istgt_log.h"
52: #include "istgt_conf.h"
53:
1.1.1.2 ! misho 54: #if !defined(__GNUC__)
! 55: #undef __attribute__
! 56: #define __attribute__(x)
! 57: #endif
! 58: #if defined(__GNUC__) && defined(__GNUC_MINOR__)
! 59: #define ISTGT_GNUC_PREREQ(ma,mi) \
! 60: (__GNUC__ > (ma) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
! 61: #else
! 62: #define ISTGT_GNUC_PREREQ(ma,mi) 0
! 63: #endif
! 64:
1.1 misho 65: #define MAX_TMPBUF 1024
66: #define MAX_ADDRBUF 64
67: #define MAX_INITIATOR_ADDR (MAX_ADDRBUF)
68: #define MAX_INITIATOR_NAME 256
69: #define MAX_TARGET_ADDR (MAX_ADDRBUF)
70: #define MAX_TARGET_NAME 256
71: #define MAX_ISCSI_NAME 256
72:
73: #define MAX_UCPORTAL 16
74: #define MAX_PORTAL 1024
75: #define MAX_INITIATOR 256
76: #define MAX_NETMASK 256
1.1.1.2 ! misho 77: #define MAX_PORTAL_GROUP 4096
1.1 misho 78: #define MAX_INITIATOR_GROUP 4096
79: #define MAX_LOGICAL_UNIT 4096
80: #define MAX_R2T 256
81:
82: #define DEFAULT_CONFIG BUILD_ETC_ISTGT "/istgt.conf"
83: #define DEFAULT_PIDFILE "/var/run/istgt.pid"
84: #define DEFAULT_AUTHFILE BUILD_ETC_ISTGT "/auth.conf"
85: #if 0
86: #define DEFAULT_MEDIAFILE BUILD_ETC_ISTGT "/media.conf"
87: #define DEFAULT_LIVEFILE BUILD_ETC_ISTGT "/istgt.live"
88: #endif
89: #define DEFAULT_MEDIADIRECTORY BUILD_VAR_ISTGT
90: #define DEFAULT_NODEBASE "iqn.2007-09.jp.ne.peach.istgt"
91: #define DEFAULT_PORT 3260
1.1.1.2 ! misho 92: #define DEFAULT_MAX_SESSIONS 32
1.1 misho 93: #define DEFAULT_MAX_CONNECTIONS 4
94: #define DEFAULT_MAXOUTSTANDINGR2T 16
95: #define DEFAULT_DEFAULTTIME2WAIT 2
96: #define DEFAULT_DEFAULTTIME2RETAIN 20
97: #define DEFAULT_FIRSTBURSTLENGTH 65536
98: #define DEFAULT_MAXBURSTLENGTH 262144
99: #define DEFAULT_MAXRECVDATASEGMENTLENGTH 8192
100: #define DEFAULT_INITIALR2T 1
101: #define DEFAULT_IMMEDIATEDATA 1
102: #define DEFAULT_DATAPDUINORDER 1
103: #define DEFAULT_DATASEQUENCEINORDER 1
104: #define DEFAULT_ERRORRECOVERYLEVEL 0
1.1.1.2 ! misho 105: #define DEFAULT_TIMEOUT 60
1.1 misho 106: #define DEFAULT_NOPININTERVAL 20
107: #define DEFAULT_MAXR2T 16
108:
1.1.1.2 ! misho 109: #define ISTGT_PG_TAG_MAX 0x0000ffff
! 110: #define ISTGT_LU_TAG_MAX 0x0000ffff
! 111: #define ISTGT_UC_TAG 0x00010000
1.1 misho 112: #define ISTGT_IOBUFSIZE (2 * 1024 * 1024)
113: #define ISTGT_SNSBUFSIZE 4096
114: #define ISTGT_SHORTDATASIZE 8192
115: #define ISTGT_SHORTPDUSIZE (48+4+ISTGT_SHORTDATASIZE+4)
116: #define ISTGT_CONDWAIT (50 * 1000) /* ms */
117: #define ISTGT_CONDWAIT_MIN (5 * 1000) /* ms */
118: #define ISTGT_STACKSIZE (2 * 1024 * 1024)
119:
120: #if defined (SIGRTMIN)
121: #define ISTGT_SIGWAKEUP (SIGRTMIN + 1)
122: #define ISTGT_USE_SIGRT
123: #elif defined (SIGIO)
124: #define ISTGT_SIGWAKEUP (SIGIO)
125: #else
126: #error "no signal for internal"
127: #endif
128: #if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__)
129: #define ISTGT_USE_KQUEUE
1.1.1.2 ! misho 130: #if defined (__FreeBSD__)
! 131: #define ISTGT_EV_SET(kevp,a,b,c,d,e,f) EV_SET((kevp),(a),(b),(c),(d),(e),(void *)(f))
! 132: #elif defined (__NetBSD__)
! 133: #define ISTGT_EV_SET(kevp,a,b,c,d,e,f) EV_SET((kevp),(a),(b),(c),(d),(e),(intptr_t)(f))
! 134: #else
! 135: #define ISTGT_EV_SET(kevp,a,b,c,d,e,f) EV_SET((kevp),(a),(b),(c),(d),(e),(f))
! 136: #endif
1.1 misho 137: #endif
138:
139: #define MTX_LOCK(MTX) \
140: do { \
141: if (pthread_mutex_lock((MTX)) != 0) { \
142: ISTGT_ERRLOG("lock error\n"); \
143: pthread_exit(NULL); \
144: } \
145: } while (0)
146: #define MTX_UNLOCK(MTX) \
147: do { \
148: if (pthread_mutex_unlock((MTX)) != 0) { \
149: ISTGT_ERRLOG("unlock error\n"); \
150: pthread_exit(NULL); \
151: } \
152: } while (0)
153: #define SPIN_LOCK(SPIN) \
154: do { \
155: if (pthread_spin_lock((SPIN)) != 0) { \
156: ISTGT_ERRLOG("lock error\n"); \
157: pthread_exit(NULL); \
158: } \
159: } while (0)
160: #define SPIN_UNLOCK(SPIN) \
161: do { \
162: if (pthread_spin_unlock((SPIN)) != 0) { \
163: ISTGT_ERRLOG("unlock error\n"); \
164: pthread_exit(NULL); \
165: } \
166: } while (0)
167:
168: typedef struct istgt_portal_t {
169: char *label;
170: char *host;
171: char *port;
1.1.1.2 ! misho 172: int ref;
1.1 misho 173: int idx;
174: int tag;
175: int sock;
176: } PORTAL;
177: typedef PORTAL *PORTAL_Ptr;
178:
1.1.1.2 ! misho 179: typedef struct istgt_portal_group_t {
! 180: int nportals;
! 181: PORTAL **portals;
! 182: int ref;
! 183: int idx;
! 184: int tag;
! 185: } PORTAL_GROUP;
! 186: typedef PORTAL_GROUP *PORTAL_GROUP_Ptr;
! 187:
1.1 misho 188: typedef struct istgt_initiator_group_t {
189: int ninitiators;
190: char **initiators;
191: int nnetmasks;
192: char **netmasks;
1.1.1.2 ! misho 193: int ref;
1.1 misho 194: int idx;
195: int tag;
196: } INITIATOR_GROUP;
197: typedef INITIATOR_GROUP *INITIATOR_GROUP_Ptr;
198:
199: typedef enum {
200: ISTGT_STATE_INVALID = 0,
201: ISTGT_STATE_INITIALIZED = 1,
202: ISTGT_STATE_RUNNING = 2,
203: ISTGT_STATE_EXITING = 3,
204: ISTGT_STATE_SHUTDOWN = 4,
205: } ISTGT_STATE;
206:
207: #define DEFAULT_ISTGT_SWMODE ISTGT_SWMODE_NORMAL
208: typedef enum {
209: ISTGT_SWMODE_TRADITIONAL = 0,
210: ISTGT_SWMODE_NORMAL = 1,
211: ISTGT_SWMODE_EXPERIMENTAL = 2,
212: } ISTGT_SWMODE;
213:
214: typedef struct istgt_t {
215: CONFIG *config;
1.1.1.2 ! misho 216: CONFIG *config_old;
1.1 misho 217: char *pidfile;
218: char *authfile;
219: #if 0
220: char *mediafile;
221: char *livefile;
222: #endif
223: char *mediadirectory;
224: char *nodebase;
225:
226: pthread_attr_t attr;
1.1.1.2 ! misho 227: pthread_mutexattr_t mutex_attr;
1.1 misho 228: pthread_mutex_t mutex;
1.1.1.2 ! misho 229: pthread_mutex_t state_mutex;
! 230: pthread_mutex_t reload_mutex;
! 231: pthread_cond_t reload_cond;
1.1 misho 232:
233: ISTGT_STATE state;
234: ISTGT_SWMODE swmode;
1.1.1.2 ! misho 235: uint32_t generation;
! 236: int sig_pipe[2];
! 237: int daemon;
! 238: int pg_reload;
1.1 misho 239:
240: int nuctl_portal;
241: PORTAL uctl_portal[MAX_UCPORTAL];
242: int nuctl_netmasks;
243: char **uctl_netmasks;
244:
1.1.1.2 ! misho 245: int nportal_group;
! 246: PORTAL_GROUP portal_group[MAX_PORTAL_GROUP];
1.1 misho 247: int ninitiator_group;
248: INITIATOR_GROUP initiator_group[MAX_INITIATOR_GROUP];
249: int nlogical_unit;
250: struct istgt_lu_t *logical_unit[MAX_LOGICAL_UNIT];
251:
252: int timeout;
253: int nopininterval;
254: int maxr2t;
255: int no_discovery_auth;
256: int req_discovery_auth;
257: int req_discovery_auth_mutual;
258: int discovery_auth_group;
259: int no_uctl_auth;
260: int req_uctl_auth;
261: int req_uctl_auth_mutual;
262: int uctl_auth_group;
263:
264: int MaxSessions;
265: int MaxConnections;
266: int MaxOutstandingR2T;
267: int DefaultTime2Wait;
268: int DefaultTime2Retain;
269: int FirstBurstLength;
270: int MaxBurstLength;
271: int MaxRecvDataSegmentLength;
272: int InitialR2T;
273: int ImmediateData;
274: int DataPDUInOrder;
275: int DataSequenceInOrder;
276: int ErrorRecoveryLevel;
277: } ISTGT;
278: typedef ISTGT *ISTGT_Ptr;
279:
280: char *istgt_get_nmval(CF_SECTION *sp, const char *key, int idx1, int idx2);
281: char *istgt_get_nval(CF_SECTION *sp, const char *key, int idx);
282: char *istgt_get_val(CF_SECTION *sp, const char *key);
283: int istgt_get_nintval(CF_SECTION *sp, const char *key, int idx);
284: int istgt_get_intval(CF_SECTION *sp, const char *key);
285:
286: #ifdef USE_ATOMIC
1.1.1.2 ! misho 287: static inline __attribute__((__always_inline__)) int
1.1 misho 288: istgt_get_state(ISTGT_Ptr istgt)
289: {
290: ISTGT_STATE state;
291: #if defined HAVE_ATOMIC_LOAD_ACQ_INT
292: state = atomic_load_acq_int((unsigned int *)&istgt->state);
293: #elif defined HAVE_ATOMIC_OR_UINT_NV
294: state = (int)atomic_or_uint_nv((unsigned int *)&istgt->state, 0);
295: #else
296: #error "no atomic operation"
297: #endif
298: return state;
299: }
1.1.1.2 ! misho 300: static inline __attribute__((__always_inline__)) void
1.1 misho 301: istgt_set_state(ISTGT_Ptr istgt, ISTGT_STATE state)
302: {
303: #if defined HAVE_ATOMIC_STORE_REL_INT
304: atomic_store_rel_int((unsigned int *)&istgt->state, state);
305: #elif defined HAVE_ATOMIC_SWAP_UINT
306: (void)atomic_swap_uint((unsigned int *)&istgt->state, state);
307: #if defined HAVE_MEMBAR_PRODUCER
308: membar_producer();
309: #endif
310: #else
311: #error "no atomic operation"
312: #endif
313: }
1.1.1.2 ! misho 314: #elif defined (USE_GCC_ATOMIC)
! 315: /* gcc >= 4.1 builtin functions */
! 316: static inline __attribute__((__always_inline__)) int
! 317: istgt_get_state(ISTGT_Ptr istgt)
! 318: {
! 319: ISTGT_STATE state;
! 320: state = __sync_fetch_and_add((unsigned int *)&istgt->state, 0);
! 321: return state;
! 322: }
! 323: static inline __attribute__((__always_inline__)) void
! 324: istgt_set_state(ISTGT_Ptr istgt, ISTGT_STATE state)
! 325: {
! 326: ISTGT_STATE state_old;
! 327: do {
! 328: state_old = __sync_fetch_and_add((unsigned int *)&istgt->state, 0);
! 329: } while (__sync_val_compare_and_swap((unsigned int *)&istgt->state,
! 330: state_old, state) != state_old);
! 331: #if defined (HAVE_GCC_ATOMIC_SYNCHRONIZE)
! 332: __sync_synchronize();
! 333: #endif
! 334: }
! 335: #else /* !USE_ATOMIC && !USE_GCC_ATOMIC */
! 336: static inline __attribute__((__always_inline__)) int
1.1 misho 337: istgt_get_state(ISTGT_Ptr istgt)
338: {
339: ISTGT_STATE state;
1.1.1.2 ! misho 340: MTX_LOCK(&istgt->state_mutex);
1.1 misho 341: state = istgt->state;
1.1.1.2 ! misho 342: MTX_UNLOCK(&istgt->state_mutex);
1.1 misho 343: return state;
344: }
345:
1.1.1.2 ! misho 346: static inline __attribute__((__always_inline__)) void
1.1 misho 347: istgt_set_state(ISTGT_Ptr istgt, ISTGT_STATE state)
348: {
1.1.1.2 ! misho 349: MTX_LOCK(&istgt->state_mutex);
1.1 misho 350: istgt->state = state;
1.1.1.2 ! misho 351: MTX_UNLOCK(&istgt->state_mutex);
1.1 misho 352: }
353: #endif /* USE_ATOMIC */
354:
355: #endif /* ISTGT_H */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>