1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk/bdev.h" 37 #include "spdk/env.h" 38 #include "spdk/fd.h" 39 #include "spdk/thread.h" 40 #include "spdk/json.h" 41 #include "spdk/util.h" 42 #include "spdk/rpc.h" 43 #include "spdk/string.h" 44 #include "spdk/iscsi_spec.h" 45 46 #include "spdk/log.h" 47 #include "spdk/bdev_module.h" 48 49 #include "iscsi/iscsi.h" 50 #include "iscsi/scsi-lowlevel.h" 51 52 #include "bdev_iscsi.h" 53 54 struct bdev_iscsi_lun; 55 56 #define BDEV_ISCSI_CONNECTION_POLL_US 500 /* 0.5 ms */ 57 #define BDEV_ISCSI_NO_MAIN_CH_POLL_US 10000 /* 10ms */ 58 59 #define DEFAULT_INITIATOR_NAME "iqn.2016-06.io.spdk:init" 60 61 /* MAXIMUM UNMAP LBA COUNT: 62 * indicates the maximum number of LBAs that may be unmapped 63 * by an UNMAP command. 64 */ 65 #define BDEV_ISCSI_DEFAULT_MAX_UNMAP_LBA_COUNT (32768) 66 67 /* MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT: 68 * indicates the maximum number of UNMAP block descriptors that 69 * shall be contained in the parameter data transferred to the 70 * device server for an UNMAP command. 71 */ 72 #define BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT (1) 73 74 static int bdev_iscsi_initialize(void); 75 static TAILQ_HEAD(, bdev_iscsi_conn_req) g_iscsi_conn_req = TAILQ_HEAD_INITIALIZER( 76 g_iscsi_conn_req); 77 static struct spdk_poller *g_conn_poller = NULL; 78 79 struct bdev_iscsi_io { 80 struct spdk_thread *submit_td; 81 enum spdk_bdev_io_status status; 82 int scsi_status; 83 enum spdk_scsi_sense sk; 84 uint8_t asc; 85 uint8_t ascq; 86 }; 87 88 struct bdev_iscsi_lun { 89 struct spdk_bdev bdev; 90 struct iscsi_context *context; 91 char *initiator_iqn; 92 int lun_id; 93 char *url; 94 pthread_mutex_t mutex; 95 uint32_t ch_count; 96 struct spdk_thread *main_td; 97 struct spdk_poller *no_main_ch_poller; 98 struct spdk_thread *no_main_ch_poller_td; 99 bool unmap_supported; 100 uint32_t max_unmap; 101 struct spdk_poller *poller; 102 }; 103 104 struct bdev_iscsi_io_channel { 105 struct bdev_iscsi_lun *lun; 106 }; 107 108 struct bdev_iscsi_conn_req { 109 char *url; 110 char *bdev_name; 111 char *initiator_iqn; 112 struct iscsi_context *context; 113 spdk_bdev_iscsi_create_cb create_cb; 114 void *create_cb_arg; 115 bool unmap_supported; 116 uint32_t max_unmap; 117 int lun; 118 int status; 119 TAILQ_ENTRY(bdev_iscsi_conn_req) link; 120 }; 121 122 static void 123 complete_conn_req(struct bdev_iscsi_conn_req *req, struct spdk_bdev *bdev, 124 int status) 125 { 126 TAILQ_REMOVE(&g_iscsi_conn_req, req, link); 127 req->create_cb(req->create_cb_arg, bdev, status); 128 129 /* 130 * we are still running in the context of iscsi_service() 131 * so do not tear down its data structures here 132 */ 133 req->status = status; 134 } 135 136 static int 137 bdev_iscsi_get_ctx_size(void) 138 { 139 return sizeof(struct bdev_iscsi_io); 140 } 141 142 static void 143 _iscsi_free_lun(void *arg) 144 { 145 struct bdev_iscsi_lun *lun = arg; 146 147 assert(lun != NULL); 148 iscsi_destroy_context(lun->context); 149 pthread_mutex_destroy(&lun->mutex); 150 free(lun->bdev.name); 151 free(lun->url); 152 free(lun->initiator_iqn); 153 154 spdk_bdev_destruct_done(&lun->bdev, 0); 155 free(lun); 156 } 157 158 static void 159 _bdev_iscsi_conn_req_free(struct bdev_iscsi_conn_req *req) 160 { 161 free(req->initiator_iqn); 162 free(req->bdev_name); 163 free(req->url); 164 /* destroy will call iscsi_disconnect() implicitly if connected */ 165 iscsi_destroy_context(req->context); 166 free(req); 167 } 168 169 static void 170 bdev_iscsi_finish(void) 171 { 172 struct bdev_iscsi_conn_req *req, *tmp; 173 174 /* clear out pending connection requests here. We cannot 175 * simply set the state to a non SCSI_STATUS_GOOD state as 176 * the connection poller wont run anymore 177 */ 178 TAILQ_FOREACH_SAFE(req, &g_iscsi_conn_req, link, tmp) { 179 _bdev_iscsi_conn_req_free(req); 180 } 181 182 if (g_conn_poller) { 183 spdk_poller_unregister(&g_conn_poller); 184 } 185 } 186 187 static struct spdk_bdev_module g_iscsi_bdev_module = { 188 .name = "iscsi", 189 .module_init = bdev_iscsi_initialize, 190 .module_fini = bdev_iscsi_finish, 191 .get_ctx_size = bdev_iscsi_get_ctx_size, 192 }; 193 194 SPDK_BDEV_MODULE_REGISTER(iscsi, &g_iscsi_bdev_module); 195 196 static void 197 _bdev_iscsi_io_complete(void *_iscsi_io) 198 { 199 struct bdev_iscsi_io *iscsi_io = _iscsi_io; 200 201 if (iscsi_io->status == SPDK_BDEV_IO_STATUS_SUCCESS) { 202 spdk_bdev_io_complete_scsi_status(spdk_bdev_io_from_ctx(iscsi_io), iscsi_io->scsi_status, 203 iscsi_io->sk, iscsi_io->asc, iscsi_io->ascq); 204 } else { 205 spdk_bdev_io_complete(spdk_bdev_io_from_ctx(iscsi_io), iscsi_io->status); 206 } 207 } 208 209 static void 210 bdev_iscsi_io_complete(struct bdev_iscsi_io *iscsi_io, enum spdk_bdev_io_status status) 211 { 212 iscsi_io->status = status; 213 if (iscsi_io->submit_td != NULL) { 214 spdk_thread_send_msg(iscsi_io->submit_td, _bdev_iscsi_io_complete, iscsi_io); 215 } else { 216 _bdev_iscsi_io_complete(iscsi_io); 217 } 218 } 219 220 /* Common call back function for read/write/flush command */ 221 static void 222 bdev_iscsi_command_cb(struct iscsi_context *context, int status, void *_task, void *_iscsi_io) 223 { 224 struct scsi_task *task = _task; 225 struct bdev_iscsi_io *iscsi_io = _iscsi_io; 226 227 iscsi_io->scsi_status = status; 228 iscsi_io->sk = (uint8_t)task->sense.key; 229 iscsi_io->asc = (task->sense.ascq >> 8) & 0xFF; 230 iscsi_io->ascq = task->sense.ascq & 0xFF; 231 232 scsi_free_scsi_task(task); 233 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_SUCCESS); 234 } 235 236 static void 237 bdev_iscsi_readv(struct bdev_iscsi_lun *lun, struct bdev_iscsi_io *iscsi_io, 238 struct iovec *iov, int iovcnt, uint64_t nbytes, uint64_t lba) 239 { 240 struct scsi_task *task; 241 242 SPDK_DEBUGLOG(iscsi_init, "read %d iovs size %lu to lba: %#lx\n", 243 iovcnt, nbytes, lba); 244 245 task = iscsi_read16_task(lun->context, lun->lun_id, lba, nbytes, lun->bdev.blocklen, 0, 0, 0, 0, 0, 246 bdev_iscsi_command_cb, iscsi_io); 247 if (task == NULL) { 248 SPDK_ERRLOG("failed to get read16_task\n"); 249 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 250 return; 251 } 252 253 #if defined(LIBISCSI_FEATURE_IOVECTOR) 254 scsi_task_set_iov_in(task, (struct scsi_iovec *)iov, iovcnt); 255 #else 256 int i; 257 for (i = 0; i < iovcnt; i++) { 258 scsi_task_add_data_in_buffer(task, iov[i].iov_len, iov[i].iov_base); 259 } 260 #endif 261 } 262 263 static void 264 bdev_iscsi_writev(struct bdev_iscsi_lun *lun, struct bdev_iscsi_io *iscsi_io, 265 struct iovec *iov, int iovcnt, uint64_t nbytes, uint64_t lba) 266 { 267 struct scsi_task *task; 268 269 SPDK_DEBUGLOG(iscsi_init, "write %d iovs size %lu to lba: %#lx\n", 270 iovcnt, nbytes, lba); 271 272 task = iscsi_write16_task(lun->context, lun->lun_id, lba, NULL, nbytes, lun->bdev.blocklen, 0, 0, 0, 273 0, 0, 274 bdev_iscsi_command_cb, iscsi_io); 275 if (task == NULL) { 276 SPDK_ERRLOG("failed to get write16_task\n"); 277 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 278 return; 279 } 280 281 #if defined(LIBISCSI_FEATURE_IOVECTOR) 282 scsi_task_set_iov_out(task, (struct scsi_iovec *)iov, iovcnt); 283 #else 284 int i; 285 for (i = 0; i < iovcnt; i++) { 286 scsi_task_add_data_in_buffer(task, iov[i].iov_len, iov[i].iov_base); 287 } 288 #endif 289 } 290 291 static void 292 bdev_iscsi_destruct_cb(void *ctx) 293 { 294 struct bdev_iscsi_lun *lun = ctx; 295 296 spdk_poller_unregister(&lun->no_main_ch_poller); 297 spdk_io_device_unregister(lun, _iscsi_free_lun); 298 } 299 300 static int 301 bdev_iscsi_destruct(void *ctx) 302 { 303 struct bdev_iscsi_lun *lun = ctx; 304 305 assert(lun->no_main_ch_poller_td); 306 spdk_thread_send_msg(lun->no_main_ch_poller_td, bdev_iscsi_destruct_cb, lun); 307 return 1; 308 } 309 310 static void 311 bdev_iscsi_flush(struct bdev_iscsi_lun *lun, struct bdev_iscsi_io *iscsi_io, uint32_t num_blocks, 312 int immed, uint64_t lba) 313 { 314 struct scsi_task *task; 315 316 task = iscsi_synchronizecache16_task(lun->context, lun->lun_id, lba, 317 num_blocks, 0, immed, bdev_iscsi_command_cb, iscsi_io); 318 if (task == NULL) { 319 SPDK_ERRLOG("failed to get sync16_task\n"); 320 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 321 return; 322 } 323 } 324 325 static void 326 bdev_iscsi_unmap(struct bdev_iscsi_lun *lun, struct bdev_iscsi_io *iscsi_io, 327 uint64_t lba, uint64_t num_blocks) 328 { 329 struct scsi_task *task; 330 struct unmap_list list[BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT] = {}; 331 struct unmap_list *entry; 332 uint32_t num_unmap_list; 333 uint64_t offset, remaining, unmap_blocks; 334 335 num_unmap_list = spdk_divide_round_up(num_blocks, lun->max_unmap); 336 if (num_unmap_list > BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT) { 337 SPDK_ERRLOG("Too many unmap entries\n"); 338 goto failed; 339 } 340 341 remaining = num_blocks; 342 offset = lba; 343 num_unmap_list = 0; 344 entry = &list[0]; 345 346 do { 347 unmap_blocks = spdk_min(remaining, lun->max_unmap); 348 entry->lba = offset; 349 entry->num = unmap_blocks; 350 num_unmap_list++; 351 remaining -= unmap_blocks; 352 offset += unmap_blocks; 353 entry++; 354 } while (remaining > 0); 355 356 task = iscsi_unmap_task(lun->context, 0, 0, 0, list, num_unmap_list, 357 bdev_iscsi_command_cb, iscsi_io); 358 if (task != NULL) { 359 return; 360 } 361 SPDK_ERRLOG("failed to get unmap_task\n"); 362 363 failed: 364 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 365 } 366 367 static void 368 bdev_iscsi_reset_cb(struct iscsi_context *context __attribute__((unused)), int status, 369 void *command_data, void *private_data) 370 { 371 uint32_t tmf_response; 372 struct bdev_iscsi_io *iscsi_io = private_data; 373 374 tmf_response = *(uint32_t *)command_data; 375 if (tmf_response == ISCSI_TASK_FUNC_RESP_COMPLETE) { 376 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_SUCCESS); 377 } else { 378 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 379 } 380 } 381 382 static void 383 _bdev_iscsi_reset(void *_bdev_io) 384 { 385 int rc; 386 struct spdk_bdev_io *bdev_io = _bdev_io; 387 struct bdev_iscsi_lun *lun = (struct bdev_iscsi_lun *)bdev_io->bdev->ctxt; 388 struct bdev_iscsi_io *iscsi_io = (struct bdev_iscsi_io *)bdev_io->driver_ctx; 389 struct iscsi_context *context = lun->context; 390 391 rc = iscsi_task_mgmt_lun_reset_async(context, lun->lun_id, 392 bdev_iscsi_reset_cb, iscsi_io); 393 if (rc != 0) { 394 SPDK_ERRLOG("failed to do iscsi reset\n"); 395 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 396 return; 397 } 398 } 399 400 static void 401 bdev_iscsi_reset(struct spdk_bdev_io *bdev_io) 402 { 403 struct bdev_iscsi_lun *lun = (struct bdev_iscsi_lun *)bdev_io->bdev->ctxt; 404 spdk_thread_send_msg(lun->main_td, _bdev_iscsi_reset, bdev_io); 405 } 406 407 static int 408 bdev_iscsi_poll_lun(void *_lun) 409 { 410 struct bdev_iscsi_lun *lun = _lun; 411 struct pollfd pfd = {}; 412 413 pfd.fd = iscsi_get_fd(lun->context); 414 pfd.events = iscsi_which_events(lun->context); 415 416 if (poll(&pfd, 1, 0) < 0) { 417 SPDK_ERRLOG("poll failed\n"); 418 return SPDK_POLLER_IDLE; 419 } 420 421 if (pfd.revents != 0) { 422 if (iscsi_service(lun->context, pfd.revents) < 0) { 423 SPDK_ERRLOG("iscsi_service failed: %s\n", iscsi_get_error(lun->context)); 424 } 425 426 return SPDK_POLLER_BUSY; 427 } 428 429 return SPDK_POLLER_IDLE; 430 } 431 432 static int 433 bdev_iscsi_no_main_ch_poll(void *arg) 434 { 435 struct bdev_iscsi_lun *lun = arg; 436 enum spdk_thread_poller_rc rc = SPDK_POLLER_IDLE; 437 438 if (pthread_mutex_trylock(&lun->mutex)) { 439 /* Don't care about the error code here. */ 440 return SPDK_POLLER_IDLE; 441 } 442 443 if (lun->ch_count == 0) { 444 rc = bdev_iscsi_poll_lun(arg); 445 } 446 447 pthread_mutex_unlock(&lun->mutex); 448 return rc; 449 } 450 451 static void 452 bdev_iscsi_get_buf_cb(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io, 453 bool success) 454 { 455 if (!success) { 456 spdk_bdev_io_complete(bdev_io, SPDK_BDEV_IO_STATUS_FAILED); 457 return; 458 } 459 460 bdev_iscsi_readv((struct bdev_iscsi_lun *)bdev_io->bdev->ctxt, 461 (struct bdev_iscsi_io *)bdev_io->driver_ctx, 462 bdev_io->u.bdev.iovs, 463 bdev_io->u.bdev.iovcnt, 464 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen, 465 bdev_io->u.bdev.offset_blocks); 466 } 467 468 static void _bdev_iscsi_submit_request(void *_bdev_io) 469 { 470 struct spdk_bdev_io *bdev_io = _bdev_io; 471 struct bdev_iscsi_io *iscsi_io = (struct bdev_iscsi_io *)bdev_io->driver_ctx; 472 struct bdev_iscsi_lun *lun = (struct bdev_iscsi_lun *)bdev_io->bdev->ctxt; 473 474 switch (bdev_io->type) { 475 case SPDK_BDEV_IO_TYPE_READ: 476 spdk_bdev_io_get_buf(bdev_io, bdev_iscsi_get_buf_cb, 477 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen); 478 break; 479 480 case SPDK_BDEV_IO_TYPE_WRITE: 481 bdev_iscsi_writev(lun, iscsi_io, 482 bdev_io->u.bdev.iovs, 483 bdev_io->u.bdev.iovcnt, 484 bdev_io->u.bdev.num_blocks * bdev_io->bdev->blocklen, 485 bdev_io->u.bdev.offset_blocks); 486 break; 487 case SPDK_BDEV_IO_TYPE_FLUSH: 488 bdev_iscsi_flush(lun, iscsi_io, 489 bdev_io->u.bdev.num_blocks, 490 ISCSI_IMMEDIATE_DATA_NO, 491 bdev_io->u.bdev.offset_blocks); 492 break; 493 case SPDK_BDEV_IO_TYPE_RESET: 494 bdev_iscsi_reset(bdev_io); 495 break; 496 case SPDK_BDEV_IO_TYPE_UNMAP: 497 bdev_iscsi_unmap(lun, iscsi_io, 498 bdev_io->u.bdev.offset_blocks, 499 bdev_io->u.bdev.num_blocks); 500 break; 501 default: 502 bdev_iscsi_io_complete(iscsi_io, SPDK_BDEV_IO_STATUS_FAILED); 503 break; 504 } 505 } 506 507 static void bdev_iscsi_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_io) 508 { 509 struct spdk_thread *submit_td = spdk_io_channel_get_thread(_ch); 510 struct bdev_iscsi_io *iscsi_io = (struct bdev_iscsi_io *)bdev_io->driver_ctx; 511 struct bdev_iscsi_lun *lun = (struct bdev_iscsi_lun *)bdev_io->bdev->ctxt; 512 513 if (lun->main_td != submit_td) { 514 iscsi_io->submit_td = submit_td; 515 spdk_thread_send_msg(lun->main_td, _bdev_iscsi_submit_request, bdev_io); 516 return; 517 } else { 518 iscsi_io->submit_td = NULL; 519 } 520 521 _bdev_iscsi_submit_request(bdev_io); 522 } 523 524 static bool 525 bdev_iscsi_io_type_supported(void *ctx, enum spdk_bdev_io_type io_type) 526 { 527 struct bdev_iscsi_lun *lun = ctx; 528 529 switch (io_type) { 530 case SPDK_BDEV_IO_TYPE_READ: 531 case SPDK_BDEV_IO_TYPE_WRITE: 532 case SPDK_BDEV_IO_TYPE_FLUSH: 533 case SPDK_BDEV_IO_TYPE_RESET: 534 return true; 535 536 case SPDK_BDEV_IO_TYPE_UNMAP: 537 return lun->unmap_supported; 538 default: 539 return false; 540 } 541 } 542 543 static int 544 bdev_iscsi_create_cb(void *io_device, void *ctx_buf) 545 { 546 struct bdev_iscsi_io_channel *ch = ctx_buf; 547 struct bdev_iscsi_lun *lun = io_device; 548 549 pthread_mutex_lock(&lun->mutex); 550 if (lun->ch_count == 0) { 551 assert(lun->main_td == NULL); 552 lun->main_td = spdk_get_thread(); 553 lun->poller = SPDK_POLLER_REGISTER(bdev_iscsi_poll_lun, lun, 0); 554 ch->lun = lun; 555 } 556 lun->ch_count++; 557 pthread_mutex_unlock(&lun->mutex); 558 559 return 0; 560 } 561 562 static void 563 _iscsi_destroy_cb(void *ctx) 564 { 565 struct bdev_iscsi_lun *lun = ctx; 566 567 pthread_mutex_lock(&lun->mutex); 568 569 assert(lun->main_td == spdk_get_thread()); 570 assert(lun->ch_count > 0); 571 572 lun->ch_count--; 573 if (lun->ch_count > 0) { 574 pthread_mutex_unlock(&lun->mutex); 575 return; 576 } 577 578 lun->main_td = NULL; 579 spdk_poller_unregister(&lun->poller); 580 581 pthread_mutex_unlock(&lun->mutex); 582 } 583 584 static void 585 bdev_iscsi_destroy_cb(void *io_device, void *ctx_buf) 586 { 587 struct bdev_iscsi_lun *lun = io_device; 588 struct spdk_thread *thread; 589 590 pthread_mutex_lock(&lun->mutex); 591 lun->ch_count--; 592 if (lun->ch_count == 0) { 593 assert(lun->main_td != NULL); 594 595 if (lun->main_td != spdk_get_thread()) { 596 /* The final channel was destroyed on a different thread 597 * than where the first channel was created. Pass a message 598 * to the main thread to unregister the poller. */ 599 lun->ch_count++; 600 thread = lun->main_td; 601 pthread_mutex_unlock(&lun->mutex); 602 spdk_thread_send_msg(thread, _iscsi_destroy_cb, lun); 603 return; 604 } 605 606 lun->main_td = NULL; 607 spdk_poller_unregister(&lun->poller); 608 } 609 pthread_mutex_unlock(&lun->mutex); 610 } 611 612 static struct spdk_io_channel * 613 bdev_iscsi_get_io_channel(void *ctx) 614 { 615 struct bdev_iscsi_lun *lun = ctx; 616 617 return spdk_get_io_channel(lun); 618 } 619 620 static int 621 bdev_iscsi_dump_info_json(void *ctx, struct spdk_json_write_ctx *w) 622 { 623 struct bdev_iscsi_lun *lun = ctx; 624 625 spdk_json_write_named_object_begin(w, "iscsi"); 626 spdk_json_write_named_string(w, "initiator_name", lun->initiator_iqn); 627 spdk_json_write_named_string(w, "url", lun->url); 628 spdk_json_write_object_end(w); 629 630 return 0; 631 } 632 633 static void 634 bdev_iscsi_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w) 635 { 636 struct bdev_iscsi_lun *lun = bdev->ctxt; 637 638 pthread_mutex_lock(&lun->mutex); 639 spdk_json_write_object_begin(w); 640 641 spdk_json_write_named_string(w, "method", "bdev_iscsi_create"); 642 643 spdk_json_write_named_object_begin(w, "params"); 644 spdk_json_write_named_string(w, "name", bdev->name); 645 spdk_json_write_named_string(w, "initiator_iqn", lun->initiator_iqn); 646 spdk_json_write_named_string(w, "url", lun->url); 647 spdk_json_write_object_end(w); 648 649 spdk_json_write_object_end(w); 650 pthread_mutex_unlock(&lun->mutex); 651 } 652 653 static const struct spdk_bdev_fn_table iscsi_fn_table = { 654 .destruct = bdev_iscsi_destruct, 655 .submit_request = bdev_iscsi_submit_request, 656 .io_type_supported = bdev_iscsi_io_type_supported, 657 .get_io_channel = bdev_iscsi_get_io_channel, 658 .dump_info_json = bdev_iscsi_dump_info_json, 659 .write_config_json = bdev_iscsi_write_config_json, 660 }; 661 662 static int 663 create_iscsi_lun(struct bdev_iscsi_conn_req *req, uint64_t num_blocks, 664 uint32_t block_size, struct spdk_bdev **bdev, uint8_t lbppbe) 665 { 666 struct bdev_iscsi_lun *lun; 667 int rc; 668 669 lun = calloc(sizeof(*lun), 1); 670 if (!lun) { 671 SPDK_ERRLOG("Unable to allocate enough memory for iscsi backend\n"); 672 return -ENOMEM; 673 } 674 675 lun->context = req->context; 676 lun->lun_id = req->lun; 677 lun->url = req->url; 678 lun->initiator_iqn = req->initiator_iqn; 679 680 pthread_mutex_init(&lun->mutex, NULL); 681 682 lun->bdev.name = req->bdev_name; 683 lun->bdev.product_name = "iSCSI LUN"; 684 lun->bdev.module = &g_iscsi_bdev_module; 685 lun->bdev.blocklen = block_size; 686 lun->bdev.phys_blocklen = block_size * (1 << lbppbe); 687 lun->bdev.blockcnt = num_blocks; 688 lun->bdev.ctxt = lun; 689 lun->unmap_supported = req->unmap_supported; 690 if (lun->unmap_supported) { 691 lun->max_unmap = req->max_unmap; 692 lun->bdev.max_unmap = req->max_unmap; 693 lun->bdev.max_unmap_segments = BDEV_ISCSI_MAX_UNMAP_BLOCK_DESCS_COUNT; 694 } 695 696 lun->bdev.fn_table = &iscsi_fn_table; 697 698 spdk_io_device_register(lun, bdev_iscsi_create_cb, bdev_iscsi_destroy_cb, 699 sizeof(struct bdev_iscsi_io_channel), 700 req->bdev_name); 701 rc = spdk_bdev_register(&lun->bdev); 702 if (rc) { 703 spdk_io_device_unregister(lun, NULL); 704 pthread_mutex_destroy(&lun->mutex); 705 free(lun); 706 return rc; 707 } 708 709 lun->no_main_ch_poller_td = spdk_get_thread(); 710 lun->no_main_ch_poller = SPDK_POLLER_REGISTER(bdev_iscsi_no_main_ch_poll, lun, 711 BDEV_ISCSI_NO_MAIN_CH_POLL_US); 712 713 *bdev = &lun->bdev; 714 return 0; 715 } 716 717 static void 718 iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status, 719 void *command_data, void *private_data) 720 { 721 struct bdev_iscsi_conn_req *req = private_data; 722 struct scsi_readcapacity16 *readcap16; 723 struct spdk_bdev *bdev = NULL; 724 struct scsi_task *task = command_data; 725 726 if (status != SPDK_SCSI_STATUS_GOOD) { 727 SPDK_ERRLOG("iSCSI error: %s\n", iscsi_get_error(iscsi)); 728 goto ret; 729 } 730 731 readcap16 = scsi_datain_unmarshall(task); 732 if (!readcap16) { 733 status = -ENOMEM; 734 goto ret; 735 } 736 737 status = create_iscsi_lun(req, readcap16->returned_lba + 1, readcap16->block_length, &bdev, 738 readcap16->lbppbe); 739 if (status) { 740 SPDK_ERRLOG("Unable to create iscsi bdev: %s (%d)\n", spdk_strerror(-status), status); 741 } 742 743 ret: 744 scsi_free_scsi_task(task); 745 complete_conn_req(req, bdev, status); 746 } 747 748 static void 749 bdev_iscsi_inquiry_bl_cb(struct iscsi_context *context, int status, void *_task, void *private_data) 750 { 751 struct scsi_task *task = _task; 752 struct scsi_inquiry_block_limits *bl_inq = NULL; 753 struct bdev_iscsi_conn_req *req = private_data; 754 755 if (status == SPDK_SCSI_STATUS_GOOD) { 756 bl_inq = scsi_datain_unmarshall(task); 757 if (bl_inq != NULL) { 758 if (!bl_inq->max_unmap) { 759 SPDK_ERRLOG("Invalid max_unmap, use the default\n"); 760 req->max_unmap = BDEV_ISCSI_DEFAULT_MAX_UNMAP_LBA_COUNT; 761 } else { 762 req->max_unmap = bl_inq->max_unmap; 763 } 764 } 765 } 766 767 scsi_free_scsi_task(task); 768 task = iscsi_readcapacity16_task(context, req->lun, iscsi_readcapacity16_cb, req); 769 if (task) { 770 return; 771 } 772 773 SPDK_ERRLOG("iSCSI error: %s\n", iscsi_get_error(req->context)); 774 complete_conn_req(req, NULL, status); 775 } 776 777 static void 778 bdev_iscsi_inquiry_lbp_cb(struct iscsi_context *context, int status, void *_task, 779 void *private_data) 780 { 781 struct scsi_task *task = _task; 782 struct scsi_inquiry_logical_block_provisioning *lbp_inq = NULL; 783 struct bdev_iscsi_conn_req *req = private_data; 784 785 if (status == SPDK_SCSI_STATUS_GOOD) { 786 lbp_inq = scsi_datain_unmarshall(task); 787 if (lbp_inq != NULL && lbp_inq->lbpu) { 788 req->unmap_supported = true; 789 scsi_free_scsi_task(task); 790 791 task = iscsi_inquiry_task(context, req->lun, 1, 792 SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 793 255, bdev_iscsi_inquiry_bl_cb, req); 794 if (task) { 795 return; 796 } 797 } 798 } else { 799 scsi_free_scsi_task(task); 800 } 801 802 task = iscsi_readcapacity16_task(context, req->lun, iscsi_readcapacity16_cb, req); 803 if (task) { 804 return; 805 } 806 807 SPDK_ERRLOG("iSCSI error: %s\n", iscsi_get_error(req->context)); 808 complete_conn_req(req, NULL, status); 809 } 810 811 static void 812 iscsi_connect_cb(struct iscsi_context *iscsi, int status, 813 void *command_data, void *private_data) 814 { 815 struct bdev_iscsi_conn_req *req = private_data; 816 struct scsi_task *task; 817 818 if (status != SPDK_SCSI_STATUS_GOOD) { 819 goto ret; 820 } 821 822 task = iscsi_inquiry_task(iscsi, req->lun, 1, 823 SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 824 255, bdev_iscsi_inquiry_lbp_cb, req); 825 if (task) { 826 return; 827 } 828 829 ret: 830 SPDK_ERRLOG("iSCSI error: %s\n", iscsi_get_error(req->context)); 831 complete_conn_req(req, NULL, status); 832 } 833 834 static int 835 iscsi_bdev_conn_poll(void *arg) 836 { 837 struct bdev_iscsi_conn_req *req, *tmp; 838 struct pollfd pfd; 839 struct iscsi_context *context; 840 841 if (TAILQ_EMPTY(&g_iscsi_conn_req)) { 842 return SPDK_POLLER_IDLE; 843 } 844 845 TAILQ_FOREACH_SAFE(req, &g_iscsi_conn_req, link, tmp) { 846 context = req->context; 847 pfd.fd = iscsi_get_fd(context); 848 pfd.events = iscsi_which_events(context); 849 pfd.revents = 0; 850 if (poll(&pfd, 1, 0) < 0) { 851 SPDK_ERRLOG("poll failed\n"); 852 return SPDK_POLLER_BUSY; 853 } 854 855 if (pfd.revents != 0) { 856 if (iscsi_service(context, pfd.revents) < 0) { 857 SPDK_ERRLOG("iscsi_service failed: %s\n", iscsi_get_error(context)); 858 } 859 } 860 861 if (req->status == 0) { 862 /* 863 * The request completed successfully. 864 */ 865 free(req); 866 } else if (req->status > 0) { 867 /* 868 * An error has occurred during connecting. This req has already 869 * been removed from the g_iscsi_conn_req list, but we needed to 870 * wait until iscsi_service unwound before we could free the req. 871 */ 872 _bdev_iscsi_conn_req_free(req); 873 } 874 } 875 return SPDK_POLLER_BUSY; 876 } 877 878 int 879 create_iscsi_disk(const char *bdev_name, const char *url, const char *initiator_iqn, 880 spdk_bdev_iscsi_create_cb cb_fn, void *cb_arg) 881 { 882 struct bdev_iscsi_conn_req *req; 883 struct iscsi_url *iscsi_url = NULL; 884 int rc; 885 886 if (!bdev_name || !url || !initiator_iqn || strlen(initiator_iqn) == 0 || !cb_fn) { 887 return -EINVAL; 888 } 889 890 req = calloc(1, sizeof(struct bdev_iscsi_conn_req)); 891 if (!req) { 892 SPDK_ERRLOG("Cannot allocate pointer of struct bdev_iscsi_conn_req\n"); 893 return -ENOMEM; 894 } 895 896 req->status = SCSI_STATUS_GOOD; 897 req->bdev_name = strdup(bdev_name); 898 req->url = strdup(url); 899 req->initiator_iqn = strdup(initiator_iqn); 900 req->context = iscsi_create_context(initiator_iqn); 901 if (!req->bdev_name || !req->url || !req->initiator_iqn || !req->context) { 902 SPDK_ERRLOG("Out of memory\n"); 903 rc = -ENOMEM; 904 goto err; 905 } 906 907 req->create_cb = cb_fn; 908 req->create_cb_arg = cb_arg; 909 910 iscsi_url = iscsi_parse_full_url(req->context, url); 911 if (iscsi_url == NULL) { 912 SPDK_ERRLOG("could not parse URL: %s\n", iscsi_get_error(req->context)); 913 rc = -EINVAL; 914 goto err; 915 } 916 917 req->lun = iscsi_url->lun; 918 rc = iscsi_set_session_type(req->context, ISCSI_SESSION_NORMAL); 919 rc = rc ? rc : iscsi_set_header_digest(req->context, ISCSI_HEADER_DIGEST_NONE); 920 rc = rc ? rc : iscsi_set_targetname(req->context, iscsi_url->target); 921 rc = rc ? rc : iscsi_full_connect_async(req->context, iscsi_url->portal, iscsi_url->lun, 922 iscsi_connect_cb, req); 923 if (rc == 0 && iscsi_url->user[0] != '\0') { 924 rc = iscsi_set_initiator_username_pwd(req->context, iscsi_url->user, iscsi_url->passwd); 925 } 926 927 if (rc < 0) { 928 SPDK_ERRLOG("Failed to connect provided URL=%s: %s\n", url, iscsi_get_error(req->context)); 929 goto err; 930 } 931 932 iscsi_destroy_url(iscsi_url); 933 req->status = -1; 934 TAILQ_INSERT_TAIL(&g_iscsi_conn_req, req, link); 935 if (!g_conn_poller) { 936 g_conn_poller = SPDK_POLLER_REGISTER(iscsi_bdev_conn_poll, NULL, BDEV_ISCSI_CONNECTION_POLL_US); 937 } 938 939 return 0; 940 941 err: 942 /* iscsi_destroy_url() is not NULL-proof */ 943 if (iscsi_url) { 944 iscsi_destroy_url(iscsi_url); 945 } 946 947 if (req->context) { 948 iscsi_destroy_context(req->context); 949 } 950 951 free(req->initiator_iqn); 952 free(req->bdev_name); 953 free(req->url); 954 free(req); 955 return rc; 956 } 957 958 void 959 delete_iscsi_disk(struct spdk_bdev *bdev, spdk_delete_iscsi_complete cb_fn, void *cb_arg) 960 { 961 if (!bdev || bdev->module != &g_iscsi_bdev_module) { 962 cb_fn(cb_arg, -ENODEV); 963 return; 964 } 965 966 spdk_bdev_unregister(bdev, cb_fn, cb_arg); 967 } 968 969 static int 970 bdev_iscsi_initialize(void) 971 { 972 return 0; 973 } 974 975 SPDK_LOG_REGISTER_COMPONENT(iscsi_init) 976