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_LU_H 29 #define ISTGT_LU_H 30 31 #include <pthread.h> 32 #include <time.h> 33 #ifdef HAVE_UUID_H 34 #include <uuid.h> 35 #endif 36 #include "istgt.h" 37 #include "istgt_queue.h" 38 39 #define MAX_LU_LUN 64 40 #define MAX_LU_LUN_SLOT 8 41 #define MAX_LU_TSIH 256 42 #define MAX_LU_MAP 256 43 #define MAX_LU_SERIAL_STRING 32 44 #define MAX_LU_RESERVE 256 45 #define MAX_LU_RESERVE_IPT 256 46 #define MAX_LU_QUEUE_DEPTH 256 47 48 #define USE_LU_TAPE_DLT8000 49 50 #define DEFAULT_LU_BLOCKLEN 512 51 #define DEFAULT_LU_BLOCKLEN_DISK DEFAULT_LU_BLOCKLEN 52 #define DEFAULT_LU_BLOCKLEN_DVD 2048 53 #define DEFAULT_LU_BLOCKLEN_TAPE DEFAULT_LU_BLOCKLEN 54 #define DEFAULT_LU_QUEUE_DEPTH 32 55 #define DEFAULT_LU_ROTATIONRATE 7200 /* 7200 rpm */ 56 #define DEFAULT_LU_FORMFACTOR 0x02 /* 3.5 inch */ 57 58 #if defined (__FreeBSD__) 59 #define DEFAULT_LU_VENDOR "FreeBSD" 60 #elif defined (__NetBSD__) 61 #define DEFAULT_LU_VENDOR "NetBSD" 62 #elif defined (__OpenBSD__) 63 #define DEFAULT_LU_VENDOR "OpenBSD" 64 #else 65 //#define DEFAULT_LU_VENDOR "PEACHNW" 66 #define DEFAULT_LU_VENDOR "FreeBSD" 67 #endif 68 69 #define DEFAULT_LU_VENDOR_DISK DEFAULT_LU_VENDOR 70 #define DEFAULT_LU_VENDOR_DVD DEFAULT_LU_VENDOR 71 #ifndef USE_LU_TAPE_DLT8000 72 #define DEFAULT_LU_VENDOR_TAPE DEFAULT_LU_VENDOR 73 #else 74 #define DEFAULT_LU_VENDOR_TAPE "QUANTUM" 75 #endif /* !USE_LU_TAPE_DLT8000 */ 76 #define DEFAULT_LU_PRODUCT "iSCSI UNIT" 77 #define DEFAULT_LU_PRODUCT_DISK "iSCSI DISK" 78 #define DEFAULT_LU_PRODUCT_DVD "iSCSI DVD" 79 #ifndef USE_LU_TAPE_DLT8000 80 #define DEFAULT_LU_PRODUCT_TAPE "iSCSI TAPE" 81 #else 82 #define DEFAULT_LU_PRODUCT_TAPE "DLT8000" 83 #endif /* !USE_LU_TAPE_DLT8000 */ 84 #define DEFAULT_LU_REVISION "0001" 85 #define DEFAULT_LU_REVISION_DISK DEFAULT_LU_REVISION 86 #define DEFAULT_LU_REVISION_DVD DEFAULT_LU_REVISION 87 #ifndef USE_LU_TAPE_DLT8000 88 #define DEFAULT_LU_REVISION_TAPE DEFAULT_LU_REVISION 89 #else 90 #define DEFAULT_LU_REVISION_TAPE "C001" 91 #endif /* !USE_LU_TAPE_DLT8000 */ 92 #define MAX_INQUIRY_SERIAL 16 93 94 #define ISTGT_LU_WORK_BLOCK_SIZE (1ULL * 1024ULL * 1024ULL) 95 #define ISTGT_LU_WORK_ATS_BLOCK_SIZE (1ULL * 1024ULL * 1024ULL) 96 #define ISTGT_LU_MAX_WRITE_CACHE_SIZE (8ULL * 1024ULL * 1024ULL) 97 #define ISTGT_LU_MEDIA_SIZE_MIN (1ULL * 1024ULL * 1024ULL) 98 #define ISTGT_LU_MEDIA_EXTEND_UNIT (256ULL * 1024ULL * 1024ULL) 99 #define ISTGT_LU_1GB (1ULL * 1024ULL * 1024ULL * 1024ULL) 100 #define ISTGT_LU_1MB (1ULL * 1024ULL * 1024ULL) 101 102 typedef enum { 103 ISTGT_LU_FLAG_MEDIA_READONLY = 0x00000001, 104 ISTGT_LU_FLAG_MEDIA_AUTOSIZE = 0x00000002, 105 ISTGT_LU_FLAG_MEDIA_EXTEND = 0x00000010, 106 ISTGT_LU_FLAG_MEDIA_DYNAMIC = 0x00000020, 107 } ISTGT_LU_FLAG; 108 109 typedef enum { 110 ISTGT_LU_TYPE_NONE = 0, 111 ISTGT_LU_TYPE_PASS = 1, 112 ISTGT_LU_TYPE_DISK = 2, 113 ISTGT_LU_TYPE_DVD = 3, 114 ISTGT_LU_TYPE_TAPE = 4, 115 } ISTGT_LU_TYPE; 116 117 typedef enum { 118 ISTGT_LU_LUN_TYPE_NONE = 0, 119 ISTGT_LU_LUN_TYPE_DEVICE = 1, 120 ISTGT_LU_LUN_TYPE_STORAGE = 2, 121 ISTGT_LU_LUN_TYPE_REMOVABLE = 3, 122 ISTGT_LU_LUN_TYPE_SLOT = 4, 123 } ISTGT_LU_LUN_TYPE; 124 125 typedef struct istgt_lu_device_t { 126 char *file; 127 } ISTGT_LU_DEVICE; 128 129 typedef struct istgt_lu_storage_t { 130 int fd; 131 char *file; 132 uint64_t size; 133 } ISTGT_LU_STORAGE; 134 135 typedef struct istgt_lu_removable_t { 136 int type; 137 int id; 138 int flags; 139 int fd; 140 char *file; 141 uint64_t size; 142 } ISTGT_LU_REMOVABLE; 143 144 typedef struct istgt_lu_slot_t { 145 int maxslot; 146 int present[MAX_LU_LUN_SLOT]; 147 int flags[MAX_LU_LUN_SLOT]; 148 char *file[MAX_LU_LUN_SLOT]; 149 uint64_t size[MAX_LU_LUN_SLOT]; 150 } ISTGT_LU_SLOT; 151 152 typedef struct istgt_lu_lun_t { 153 int type; 154 union { 155 ISTGT_LU_DEVICE device; 156 ISTGT_LU_STORAGE storage; 157 ISTGT_LU_REMOVABLE removable; 158 ISTGT_LU_SLOT slot; 159 } u; 160 int rotationrate; 161 int formfactor; 162 int readcache; 163 int writecache; 164 char *serial; 165 void *spec; 166 } ISTGT_LU_LUN; 167 typedef ISTGT_LU_LUN *ISTGT_LU_LUN_Ptr; 168 169 typedef struct istgt_lu_tsih_t { 170 int tag; 171 uint16_t tsih; 172 char *initiator_port; 173 } ISTGT_LU_TSIH; 174 175 typedef enum { 176 AAS_ACTIVE_OPTIMIZED = 0x00, 177 AAS_ACTIVE_NON_OPTIMIZED = 0x01, 178 AAS_STANDBY = 0x02, 179 AAS_UNAVAILABLE = 0x03, 180 AAS_TRANSITIONING = 0x0F, 181 182 AAS_STATUS_NO = 0x0000, 183 AAS_STATUS_STPG = 0x0100, 184 AAS_STATUS_IMPLICIT = 0x0200, 185 } ISTGT_LU_AAS; 186 187 typedef struct istgt_lu_map_t { 188 int pg_tag; 189 int pg_aas; 190 int ig_tag; 191 } ISTGT_LU_MAP; 192 193 typedef struct istgt_lu_t { 194 int num; 195 char *name; 196 char *alias; 197 198 char *inq_vendor; 199 char *inq_product; 200 char *inq_revision; 201 char *inq_serial; 202 203 ISTGT_Ptr istgt; 204 ISTGT_STATE state; 205 pthread_mutex_t mutex; 206 pthread_mutex_t state_mutex; 207 pthread_mutex_t queue_mutex; 208 pthread_cond_t queue_cond; 209 pthread_t thread; 210 211 uint16_t last_tsih; 212 213 int no_auth_chap; 214 int auth_chap; 215 int auth_chap_mutual; 216 int auth_group; 217 int header_digest; 218 int data_digest; 219 220 int MaxOutstandingR2T; 221 int DefaultTime2Wait; 222 int DefaultTime2Retain; 223 int FirstBurstLength; 224 int MaxBurstLength; 225 int MaxRecvDataSegmentLength; 226 int InitialR2T; 227 int ImmediateData; 228 int DataPDUInOrder; 229 int DataSequenceInOrder; 230 int ErrorRecoveryLevel; 231 232 int type; 233 int online; 234 int readonly; 235 int blocklen; 236 int queue_depth; 237 int queue_check; 238 239 int maxlun; 240 ISTGT_LU_LUN lun[MAX_LU_LUN]; 241 int maxtsih; 242 ISTGT_LU_TSIH tsih[MAX_LU_TSIH]; 243 int maxmap; 244 ISTGT_LU_MAP map[MAX_LU_MAP]; 245 } ISTGT_LU; 246 typedef ISTGT_LU *ISTGT_LU_Ptr; 247 248 typedef struct istgt_lu_cmd_t { 249 struct iscsi_pdu_t *pdu; 250 ISTGT_LU_Ptr lu; 251 252 int I_bit; 253 int F_bit; 254 int R_bit; 255 int W_bit; 256 int Attr_bit; 257 uint64_t lun; 258 uint32_t task_tag; 259 uint32_t transfer_len; 260 uint32_t CmdSN; 261 uint8_t *cdb; 262 263 uint8_t *iobuf; 264 size_t iobufsize; 265 uint8_t *data; 266 size_t data_len; 267 size_t alloc_len; 268 269 int status; 270 uint8_t *sense_data; 271 size_t sense_data_len; 272 size_t sense_alloc_len; 273 } ISTGT_LU_CMD; 274 typedef ISTGT_LU_CMD *ISTGT_LU_CMD_Ptr; 275 276 enum { 277 ISTGT_LU_TASK_RESULT_IMMEDIATE = 0, 278 ISTGT_LU_TASK_RESULT_QUEUE_OK = 1, 279 ISTGT_LU_TASK_RESULT_QUEUE_FULL = 2, 280 } /* ISTGT_LU_TASK_RESULT */; 281 282 enum { 283 ISTGT_LU_TASK_RESPONSE = 0, 284 ISTGT_LU_TASK_REQPDU = 1, 285 ISTGT_LU_TASK_REQUPDPDU = 2, 286 } /* ISTGT_LU_TASK_TYPE */; 287 288 typedef struct istgt_lu_task_t { 289 int type; 290 291 struct istgt_conn_t *conn; 292 char initiator_name[MAX_INITIATOR_NAME]; 293 char initiator_port[MAX_INITIATOR_NAME]; 294 ISTGT_LU_CMD lu_cmd; 295 int lun; 296 pthread_t thread; 297 int use_cond; 298 pthread_mutex_t trans_mutex; 299 pthread_cond_t trans_cond; 300 pthread_cond_t exec_cond; 301 302 time_t create_time; 303 int condwait; 304 305 int dup_iobuf; 306 uint8_t *iobuf; 307 uint8_t *data; 308 uint8_t *sense_data; 309 size_t alloc_len; 310 311 int offset; 312 int req_execute; 313 int req_transfer_out; 314 int error; 315 int abort; 316 int execute; 317 int complete; 318 int lock; 319 } ISTGT_LU_TASK; 320 typedef ISTGT_LU_TASK *ISTGT_LU_TASK_Ptr; 321 322 /* lu_disk.c */ 323 typedef struct istgt_lu_pr_key_t { 324 uint64_t key; 325 326 /* transport IDs */ 327 char *registered_initiator_port; 328 char *registered_target_port; 329 /* PERSISTENT RESERVE OUT received from */ 330 int pg_idx; /* relative target port */ 331 int pg_tag; /* target port group */ 332 333 int ninitiator_ports; 334 char **initiator_ports; 335 int all_tpg; 336 } ISTGT_LU_PR_KEY; 337 338 typedef struct istgt_lu_disk_t { 339 ISTGT_LU_Ptr lu; 340 int num; 341 int lun; 342 343 int fd; 344 const char *file; 345 const char *disktype; 346 void *exspec; 347 uint64_t fsize; 348 uint64_t foffset; 349 uint64_t size; 350 uint64_t blocklen; 351 uint64_t blockcnt; 352 353 #ifdef HAVE_UUID_H 354 uuid_t uuid; 355 #endif /* HAVE_UUID_H */ 356 357 /* cache flags */ 358 int read_cache; 359 int write_cache; 360 /* parts for cache */ 361 int wbufsize; 362 uint8_t *wbuf; 363 uint64_t woffset; 364 uint64_t wnbytes; 365 int req_write_cache; 366 int err_write_cache; 367 368 /* thin provisioning */ 369 int thin_provisioning; 370 371 /* for ats */ 372 pthread_mutex_t ats_mutex; 373 int watssize; 374 uint8_t *watsbuf; 375 376 int queue_depth; 377 pthread_mutex_t cmd_queue_mutex; 378 ISTGT_QUEUE cmd_queue; 379 pthread_mutex_t wait_lu_task_mutex; 380 ISTGT_LU_TASK_Ptr wait_lu_task; 381 382 /* PERSISTENT RESERVE */ 383 int npr_keys; 384 ISTGT_LU_PR_KEY pr_keys[MAX_LU_RESERVE]; 385 uint32_t pr_generation; 386 387 char *rsv_port; 388 uint64_t rsv_key; 389 int rsv_scope; 390 int rsv_type; 391 392 /* SCSI sense code */ 393 volatile int sense; 394 395 /* entry */ 396 int (*open)(struct istgt_lu_disk_t *spec, int flags, int mode); 397 int (*close)(struct istgt_lu_disk_t *spec); 398 int64_t (*seek)(struct istgt_lu_disk_t *spec, uint64_t offset); 399 int64_t (*read)(struct istgt_lu_disk_t *spec, void *buf, uint64_t nbytes); 400 int64_t (*write)(struct istgt_lu_disk_t *spec, const void *buf, uint64_t nbytes); 401 int64_t (*sync)(struct istgt_lu_disk_t *spec, uint64_t offset, uint64_t nbytes); 402 int (*allocate)(struct istgt_lu_disk_t *spec); 403 int (*setcache)(struct istgt_lu_disk_t *spec); 404 } ISTGT_LU_DISK; 405 406 #endif /* ISTGT_LU_H */ 407