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_PROTO_H
29 #define ISTGT_PROTO_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 <stdint.h>
48 #include <signal.h>
49 #include <sys/socket.h>
50 #ifdef HAVE_UUID_H
51 #include <uuid.h>
52 #endif
53 #include "istgt.h"
54 #include "istgt_iscsi.h"
55 #include "istgt_lu.h"
56 
57 #if !defined(__GNUC__)
58 #undef __attribute__
59 #define __attribute__(x)
60 #endif
61 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
62 #define ISTGT_GNUC_PREREQ(ma,mi) \
63 	(__GNUC__ > (ma) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
64 #else
65 #define ISTGT_GNUC_PREREQ(ma,mi) 0
66 #endif
67 
68 /* istgt_iscsi.c */
69 int istgt_chap_get_authinfo(ISTGT_CHAP_AUTH *auth, const char *authfile, const char *authuser, int ag_tag);
70 int istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint8_t *data, size_t alloc_len, size_t transfer_len);
71 int istgt_create_sess(ISTGT_Ptr istgt, CONN_Ptr conn, ISTGT_LU_Ptr lu);
72 int istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen);
73 void istgt_lock_gconns(void);
74 void istgt_unlock_gconns(void);
75 int istgt_get_gnconns(void);
76 CONN_Ptr istgt_get_gconn(int idx);
77 int istgt_get_active_conns(void);
78 int istgt_stop_conns(void);
79 CONN_Ptr istgt_find_conn(const char *initiator_port, const char *target_name, uint16_t tsih);
80 int istgt_iscsi_init(ISTGT_Ptr istgt);
81 int istgt_iscsi_shutdown(ISTGT_Ptr istgt);
82 int istgt_iscsi_copy_pdu(ISCSI_PDU_Ptr dst_pdu, ISCSI_PDU_Ptr src_pdu);
83 
84 /* istgt_lu.c */
85 int istgt_lu_allow_netmask(const char *netmask, const char *addr);
86 int istgt_lu_access(CONN_Ptr conn, ISTGT_LU_Ptr lu, const char *iqn, const char *addr);
87 int istgt_lu_visible(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu, const char *iqn, int pg_tag);
88 int istgt_lu_sendtargets(CONN_Ptr conn, const char *iiqn, const char *iaddr, const char *tiqn, uint8_t *data, int alloc_len, int data_len);
89 ISTGT_LU_Ptr istgt_lu_find_target(ISTGT_Ptr istgt, const char *target_name);
90 uint16_t istgt_lu_allocate_tsih(ISTGT_LU_Ptr lu, const char *initiator_port, int tag);
91 void istgt_lu_free_tsih(ISTGT_LU_Ptr lu, uint16_t tsih, char *initiator_port);
92 char *istgt_lu_get_media_flags_string(int flags, char *buf, size_t len);
93 uint64_t istgt_lu_get_devsize(const char *file);
94 uint64_t istgt_lu_get_filesize(const char *file);
95 uint64_t istgt_lu_parse_size(const char *size);
96 int istgt_lu_parse_media_flags(const char *flags);
97 uint64_t istgt_lu_parse_media_size(const char *file, const char *size, int *flags);
98 PORTAL_GROUP *istgt_lu_find_portalgroup(ISTGT_Ptr istgt, int tag);
99 INITIATOR_GROUP *istgt_lu_find_initiatorgroup(ISTGT_Ptr istgt, int tag);
100 int istgt_lu_init(ISTGT_Ptr istgt);
101 int istgt_lu_reload_delete(ISTGT_Ptr istgt);
102 int istgt_lu_reload_update(ISTGT_Ptr istgt);
103 int istgt_lu_set_all_state(ISTGT_Ptr istgt, ISTGT_STATE state);
104 int istgt_lu_create_threads(ISTGT_Ptr istgt);
105 int istgt_lu_shutdown(ISTGT_Ptr istgt);
106 int istgt_lu_islun2lun(uint64_t islun);
107 uint64_t istgt_lu_lun2islun(int lun, int maxlun);
108 int istgt_lu_reset(ISTGT_LU_Ptr lu, uint64_t lun);
109 int istgt_lu_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
110 int istgt_lu_create_task(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, ISTGT_LU_TASK_Ptr lu_task, int lun);
111 int istgt_lu_destroy_task(ISTGT_LU_TASK_Ptr lu_task);
112 int istgt_lu_clear_task_IT(CONN_Ptr conn, ISTGT_LU_Ptr lu);
113 int istgt_lu_clear_task_ITL(CONN_Ptr conn, ISTGT_LU_Ptr lu, uint64_t lun);
114 int istgt_lu_clear_task_ITLQ(CONN_Ptr conn, ISTGT_LU_Ptr lu, uint64_t lun, uint32_t CmdSN);
115 int istgt_lu_clear_all_task(ISTGT_LU_Ptr lu, uint64_t lun);
116 
117 /* istgt_lu_ctl.c */
118 int istgt_create_uctl(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen);
119 int istgt_uctl_init(ISTGT_Ptr istgt);
120 int istgt_uctl_shutdown(ISTGT_Ptr istgt);
121 
122 /* istgt_lu_disk.c */
123 struct istgt_lu_disk_t;
124 void istgt_scsi_dump_cdb(uint8_t *cdb);
125 void istgt_strcpy_pad(uint8_t *dst, size_t size, const char *src, int pad);
126 #ifdef HAVE_UUID_H
127 uint64_t istgt_uuid2uint64(uuid_t *uuid);
128 #endif /* HAVE_UUID_H */
129 uint64_t istgt_get_lui(const char *name, int lun);
130 uint64_t istgt_get_rkey(const char *initiator_name, uint64_t lui);
131 int istgt_lu_set_lid(uint8_t *buf, uint64_t vid);
132 int istgt_lu_set_id(uint8_t *buf, uint64_t vid);
133 int istgt_lu_set_extid(uint8_t *buf, uint64_t vid, uint64_t vide);
134 int istgt_lu_scsi_build_sense_data(uint8_t *data, int sk, int asc, int ascq);
135 int istgt_lu_scsi_build_sense_data2(uint8_t *data, int sk, int asc, int ascq);
136 int istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
137 int istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
138 int istgt_lu_disk_reset(ISTGT_LU_Ptr lu, int lun);
139 int istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
140 int istgt_lu_disk_queue_clear_IT(CONN_Ptr conn, ISTGT_LU_Ptr lu);
141 int istgt_lu_disk_queue_clear_ITL(CONN_Ptr conn, ISTGT_LU_Ptr lu, int lun);
142 int istgt_lu_disk_queue_clear_ITLQ(CONN_Ptr conn, ISTGT_LU_Ptr lu, int lun, uint32_t CmdSN);
143 int istgt_lu_disk_queue_clear_all(ISTGT_LU_Ptr lu, int lun);
144 int istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
145 int istgt_lu_disk_queue_count(ISTGT_LU_Ptr lu, int *lun);
146 int istgt_lu_disk_queue_start(ISTGT_LU_Ptr lu, int lun);
147 void istgt_lu_disk_aio_done(siginfo_t *info);
148 
149 /* istgt_lu_disk_vbox.c */
150 int istgt_lu_disk_vbox_lun_init(ISTGT_LU_DISK *spec, ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
151 int istgt_lu_disk_vbox_lun_shutdown(ISTGT_LU_DISK *spec, ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
152 
153 /* istgt_lu_dvd.c */
154 struct istgt_lu_dvd_t;
155 int istgt_lu_dvd_media_present(struct istgt_lu_dvd_t *spec);
156 int istgt_lu_dvd_media_lock(struct istgt_lu_dvd_t *spec);
157 int istgt_lu_dvd_load_media(struct istgt_lu_dvd_t *spec);
158 int istgt_lu_dvd_unload_media(struct istgt_lu_dvd_t *spec);
159 int istgt_lu_dvd_change_media(struct istgt_lu_dvd_t *spec, char *type, char *flags, char *file, char *size);
160 int istgt_lu_dvd_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
161 int istgt_lu_dvd_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
162 int istgt_lu_dvd_reset(ISTGT_LU_Ptr lu, int lun);
163 int istgt_lu_dvd_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
164 
165 /* istgt_lu_tape.c */
166 struct istgt_lu_tape_t;
167 int istgt_lu_tape_media_present(struct istgt_lu_tape_t *spec);
168 int istgt_lu_tape_media_lock(struct istgt_lu_tape_t *spec);
169 int istgt_lu_tape_load_media(struct istgt_lu_tape_t *spec);
170 int istgt_lu_tape_unload_media(struct istgt_lu_tape_t *spec);
171 int istgt_lu_tape_change_media(struct istgt_lu_tape_t *spec, char *type, char *flags, char *file, char *size);
172 int istgt_lu_tape_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
173 int istgt_lu_tape_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
174 int istgt_lu_tape_reset(ISTGT_LU_Ptr lu, int lun);
175 int istgt_lu_tape_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
176 
177 /* istgt_lu_pass.c */
178 int istgt_lu_pass_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
179 int istgt_lu_pass_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu);
180 int istgt_lu_pass_reset(ISTGT_LU_Ptr lu, int lun);
181 int istgt_lu_pass_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd);
182 
183 #ifdef USE_ATOMIC
184 static inline __attribute__((__always_inline__)) int
istgt_lu_get_state(ISTGT_LU_Ptr lu)185 istgt_lu_get_state(ISTGT_LU_Ptr lu)
186 {
187 	ISTGT_STATE state;
188 #if defined HAVE_ATOMIC_LOAD_ACQ_INT
189 	state = atomic_load_acq_int((unsigned int *)&lu->state);
190 #elif defined HAVE_ATOMIC_OR_UINT_NV
191 	state = (int)atomic_or_uint_nv((unsigned int *)&lu->state, 0);
192 #else
193 #error "no atomic operation"
194 #endif
195 	return state;
196 }
197 static inline __attribute__((__always_inline__)) void
istgt_lu_set_state(ISTGT_LU_Ptr lu,ISTGT_STATE state)198 istgt_lu_set_state(ISTGT_LU_Ptr lu, ISTGT_STATE state)
199 {
200 #if defined HAVE_ATOMIC_STORE_REL_INT
201 	atomic_store_rel_int((unsigned int *)&lu->state, state);
202 #elif defined HAVE_ATOMIC_SWAP_UINT
203 	(void)atomic_swap_uint((unsigned int *)&lu->state, state);
204 #if defined HAVE_MEMBAR_PRODUCER
205 	membar_producer();
206 #endif
207 #else
208 #error "no atomic operation"
209 #endif
210 }
211 #elif defined (USE_GCC_ATOMIC)
212 /* gcc >= 4.1 builtin functions */
213 static inline __attribute__((__always_inline__)) int
istgt_lu_get_state(ISTGT_LU_Ptr lu)214 istgt_lu_get_state(ISTGT_LU_Ptr lu)
215 {
216 	ISTGT_STATE state;
217 	state = __sync_fetch_and_add((unsigned int *)&lu->state, 0);
218 	return state;
219 }
220 static inline __attribute__((__always_inline__)) void
istgt_lu_set_state(ISTGT_LU_Ptr lu,ISTGT_STATE state)221 istgt_lu_set_state(ISTGT_LU_Ptr lu, ISTGT_STATE state)
222 {
223 	ISTGT_STATE state_old;
224 	do {
225 		state_old = __sync_fetch_and_add((unsigned int *)&lu->state, 0);
226 	} while (__sync_val_compare_and_swap((unsigned int *)&lu->state,
227 		state_old, state) != state_old);
228 #if defined (HAVE_GCC_ATOMIC_SYNCHRONIZE)
229 	__sync_synchronize();
230 #endif
231 }
232 #else /* !USE_ATOMIC && !USE_GCC_ATOMIC */
233 static inline __attribute__((__always_inline__)) int
istgt_lu_get_state(ISTGT_LU_Ptr lu)234 istgt_lu_get_state(ISTGT_LU_Ptr lu)
235 {
236 	ISTGT_STATE state;
237 	MTX_LOCK(&lu->state_mutex);
238 	state = lu->state;
239 	MTX_UNLOCK(&lu->state_mutex);
240 	return state;
241 }
242 
243 static inline __attribute__((__always_inline__)) void
istgt_lu_set_state(ISTGT_LU_Ptr lu,ISTGT_STATE state)244 istgt_lu_set_state(ISTGT_LU_Ptr lu, ISTGT_STATE state)
245 {
246 	MTX_LOCK(&lu->state_mutex);
247 	lu->state = state;
248 	MTX_UNLOCK(&lu->state_mutex);
249 }
250 #endif /* USE_ATOMIC */
251 
252 #endif /* ISTGT_PROTO_H */
253