File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / istgt / src / istgt.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:13:23 2012 UTC (12 years, 6 months ago) by misho
Branches: istgt, MAIN
CVS tags: v20121028, v20120901, HEAD
dhcp 4.1 r7

    1: /*
    2:  * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
    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: 
   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: 
   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
   77: #define MAX_PORTAL_GROUP 4096
   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
   92: #define DEFAULT_MAX_SESSIONS 32
   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
  105: #define DEFAULT_TIMEOUT 60
  106: #define DEFAULT_NOPININTERVAL 20
  107: #define DEFAULT_MAXR2T 16
  108: 
  109: #define ISTGT_PG_TAG_MAX 0x0000ffff
  110: #define ISTGT_LU_TAG_MAX 0x0000ffff
  111: #define ISTGT_UC_TAG     0x00010000
  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
  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
  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;
  172: 	int ref;
  173: 	int idx;
  174: 	int tag;
  175: 	int sock;
  176: } PORTAL;
  177: typedef PORTAL *PORTAL_Ptr;
  178: 
  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: 
  188: typedef struct istgt_initiator_group_t {
  189: 	int ninitiators;
  190: 	char **initiators;
  191: 	int nnetmasks;
  192: 	char **netmasks;
  193: 	int ref;
  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;
  216: 	CONFIG *config_old;
  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;
  227: 	pthread_mutexattr_t mutex_attr;
  228: 	pthread_mutex_t mutex;
  229: 	pthread_mutex_t state_mutex;
  230: 	pthread_mutex_t reload_mutex;
  231: 	pthread_cond_t reload_cond;
  232: 
  233: 	ISTGT_STATE state;
  234: 	ISTGT_SWMODE swmode;
  235: 	uint32_t generation;
  236: 	int sig_pipe[2];
  237: 	int daemon;
  238: 	int pg_reload;
  239: 
  240: 	int nuctl_portal;
  241: 	PORTAL uctl_portal[MAX_UCPORTAL];
  242: 	int nuctl_netmasks;
  243: 	char **uctl_netmasks;
  244: 
  245: 	int nportal_group;
  246: 	PORTAL_GROUP portal_group[MAX_PORTAL_GROUP];
  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
  287: static inline __attribute__((__always_inline__)) int
  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: }
  300: static inline __attribute__((__always_inline__)) void
  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: }
  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
  337: istgt_get_state(ISTGT_Ptr istgt)
  338: {
  339: 	ISTGT_STATE state;
  340: 	MTX_LOCK(&istgt->state_mutex);
  341: 	state = istgt->state;
  342: 	MTX_UNLOCK(&istgt->state_mutex);
  343: 	return state;
  344: }
  345: 
  346: static inline __attribute__((__always_inline__)) void
  347: istgt_set_state(ISTGT_Ptr istgt, ISTGT_STATE state)
  348: {
  349: 	MTX_LOCK(&istgt->state_mutex);
  350: 	istgt->state = state;
  351: 	MTX_UNLOCK(&istgt->state_mutex);
  352: }
  353: #endif /* USE_ATOMIC */
  354: 
  355: #endif /* ISTGT_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>