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>