iscsi: add .bdrv_get_block_status
[qemu/kevin.git] / block / iscsi.c
blobc377d21589f1a45abd265e357d515b3baec9ac85
1 /*
2 * QEMU Block driver for iSCSI images
4 * Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 #include "config-host.h"
27 #include <poll.h>
28 #include <arpa/inet.h>
29 #include "qemu-common.h"
30 #include "qemu/config-file.h"
31 #include "qemu/error-report.h"
32 #include "block/block_int.h"
33 #include "trace.h"
34 #include "block/scsi.h"
35 #include "qemu/iov.h"
36 #include "sysemu/sysemu.h"
37 #include "qmp-commands.h"
39 #include <iscsi/iscsi.h>
40 #include <iscsi/scsi-lowlevel.h>
42 #ifdef __linux__
43 #include <scsi/sg.h>
44 #include <block/scsi.h>
45 #endif
47 typedef struct IscsiLun {
48 struct iscsi_context *iscsi;
49 int lun;
50 enum scsi_inquiry_peripheral_device_type type;
51 int block_size;
52 uint64_t num_blocks;
53 int events;
54 QEMUTimer *nop_timer;
55 uint8_t lbpme;
56 uint8_t lbprz;
57 struct scsi_inquiry_logical_block_provisioning lbp;
58 struct scsi_inquiry_block_limits bl;
59 } IscsiLun;
61 typedef struct IscsiTask {
62 int status;
63 int complete;
64 int retries;
65 int do_retry;
66 struct scsi_task *task;
67 Coroutine *co;
68 } IscsiTask;
70 typedef struct IscsiAIOCB {
71 BlockDriverAIOCB common;
72 QEMUIOVector *qiov;
73 QEMUBH *bh;
74 IscsiLun *iscsilun;
75 struct scsi_task *task;
76 uint8_t *buf;
77 int status;
78 int canceled;
79 int retries;
80 int64_t sector_num;
81 int nb_sectors;
82 #ifdef __linux__
83 sg_io_hdr_t *ioh;
84 #endif
85 } IscsiAIOCB;
87 #define NOP_INTERVAL 5000
88 #define MAX_NOP_FAILURES 3
89 #define ISCSI_CMD_RETRIES 5
91 static void
92 iscsi_bh_cb(void *p)
94 IscsiAIOCB *acb = p;
96 qemu_bh_delete(acb->bh);
98 g_free(acb->buf);
99 acb->buf = NULL;
101 if (acb->canceled == 0) {
102 acb->common.cb(acb->common.opaque, acb->status);
105 if (acb->task != NULL) {
106 scsi_free_scsi_task(acb->task);
107 acb->task = NULL;
110 qemu_aio_release(acb);
113 static void
114 iscsi_schedule_bh(IscsiAIOCB *acb)
116 if (acb->bh) {
117 return;
119 acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
120 qemu_bh_schedule(acb->bh);
123 static void
124 iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
125 void *command_data, void *opaque)
127 struct IscsiTask *iTask = opaque;
128 struct scsi_task *task = command_data;
130 iTask->complete = 1;
131 iTask->status = status;
132 iTask->do_retry = 0;
133 iTask->task = task;
135 if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION
136 && task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
137 iTask->do_retry = 1;
138 goto out;
141 if (status != SCSI_STATUS_GOOD) {
142 error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi));
145 out:
146 if (iTask->co) {
147 qemu_coroutine_enter(iTask->co, NULL);
151 static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
153 *iTask = (struct IscsiTask) {
154 .co = qemu_coroutine_self(),
155 .retries = ISCSI_CMD_RETRIES,
159 static void
160 iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
161 void *private_data)
163 IscsiAIOCB *acb = private_data;
165 acb->status = -ECANCELED;
166 iscsi_schedule_bh(acb);
169 static void
170 iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
172 IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
173 IscsiLun *iscsilun = acb->iscsilun;
175 if (acb->status != -EINPROGRESS) {
176 return;
179 acb->canceled = 1;
181 /* send a task mgmt call to the target to cancel the task on the target */
182 iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
183 iscsi_abort_task_cb, acb);
185 while (acb->status == -EINPROGRESS) {
186 qemu_aio_wait();
190 static const AIOCBInfo iscsi_aiocb_info = {
191 .aiocb_size = sizeof(IscsiAIOCB),
192 .cancel = iscsi_aio_cancel,
196 static void iscsi_process_read(void *arg);
197 static void iscsi_process_write(void *arg);
199 static void
200 iscsi_set_events(IscsiLun *iscsilun)
202 struct iscsi_context *iscsi = iscsilun->iscsi;
203 int ev;
205 /* We always register a read handler. */
206 ev = POLLIN;
207 ev |= iscsi_which_events(iscsi);
208 if (ev != iscsilun->events) {
209 qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
210 iscsi_process_read,
211 (ev & POLLOUT) ? iscsi_process_write : NULL,
212 iscsilun);
216 iscsilun->events = ev;
219 static void
220 iscsi_process_read(void *arg)
222 IscsiLun *iscsilun = arg;
223 struct iscsi_context *iscsi = iscsilun->iscsi;
225 iscsi_service(iscsi, POLLIN);
226 iscsi_set_events(iscsilun);
229 static void
230 iscsi_process_write(void *arg)
232 IscsiLun *iscsilun = arg;
233 struct iscsi_context *iscsi = iscsilun->iscsi;
235 iscsi_service(iscsi, POLLOUT);
236 iscsi_set_events(iscsilun);
239 static int
240 iscsi_aio_writev_acb(IscsiAIOCB *acb);
242 static void
243 iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
244 void *command_data, void *opaque)
246 IscsiAIOCB *acb = opaque;
248 trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled);
250 g_free(acb->buf);
251 acb->buf = NULL;
253 if (acb->canceled != 0) {
254 return;
257 acb->status = 0;
258 if (status != 0) {
259 if (status == SCSI_STATUS_CHECK_CONDITION
260 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
261 && acb->retries-- > 0) {
262 scsi_free_scsi_task(acb->task);
263 acb->task = NULL;
264 if (iscsi_aio_writev_acb(acb) == 0) {
265 iscsi_set_events(acb->iscsilun);
266 return;
269 error_report("Failed to write16 data to iSCSI lun. %s",
270 iscsi_get_error(iscsi));
271 acb->status = -EIO;
274 iscsi_schedule_bh(acb);
277 static int64_t sector_lun2qemu(int64_t sector, IscsiLun *iscsilun)
279 return sector * iscsilun->block_size / BDRV_SECTOR_SIZE;
282 static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
284 return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
287 static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
288 IscsiLun *iscsilun)
290 if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
291 (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) {
292 error_report("iSCSI misaligned request: "
293 "iscsilun->block_size %u, sector_num %" PRIi64
294 ", nb_sectors %d",
295 iscsilun->block_size, sector_num, nb_sectors);
296 return 0;
298 return 1;
301 static int
302 iscsi_aio_writev_acb(IscsiAIOCB *acb)
304 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
305 size_t size;
306 uint32_t num_sectors;
307 uint64_t lba;
308 #if !defined(LIBISCSI_FEATURE_IOVECTOR)
309 struct iscsi_data data;
310 #endif
311 int ret;
313 acb->canceled = 0;
314 acb->bh = NULL;
315 acb->status = -EINPROGRESS;
316 acb->buf = NULL;
318 /* this will allow us to get rid of 'buf' completely */
319 size = acb->nb_sectors * BDRV_SECTOR_SIZE;
321 #if !defined(LIBISCSI_FEATURE_IOVECTOR)
322 data.size = MIN(size, acb->qiov->size);
324 /* if the iovec only contains one buffer we can pass it directly */
325 if (acb->qiov->niov == 1) {
326 data.data = acb->qiov->iov[0].iov_base;
327 } else {
328 acb->buf = g_malloc(data.size);
329 qemu_iovec_to_buf(acb->qiov, 0, acb->buf, data.size);
330 data.data = acb->buf;
332 #endif
334 acb->task = malloc(sizeof(struct scsi_task));
335 if (acb->task == NULL) {
336 error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
337 "command. %s", iscsi_get_error(iscsi));
338 return -1;
340 memset(acb->task, 0, sizeof(struct scsi_task));
342 acb->task->xfer_dir = SCSI_XFER_WRITE;
343 acb->task->cdb_size = 16;
344 acb->task->cdb[0] = 0x8a;
345 lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
346 *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32);
347 *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff);
348 num_sectors = sector_qemu2lun(acb->nb_sectors, acb->iscsilun);
349 *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
350 acb->task->expxferlen = size;
352 #if defined(LIBISCSI_FEATURE_IOVECTOR)
353 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
354 iscsi_aio_write16_cb,
355 NULL,
356 acb);
357 #else
358 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
359 iscsi_aio_write16_cb,
360 &data,
361 acb);
362 #endif
363 if (ret != 0) {
364 scsi_free_scsi_task(acb->task);
365 g_free(acb->buf);
366 return -1;
369 #if defined(LIBISCSI_FEATURE_IOVECTOR)
370 scsi_task_set_iov_out(acb->task, (struct scsi_iovec*) acb->qiov->iov, acb->qiov->niov);
371 #endif
373 return 0;
376 static BlockDriverAIOCB *
377 iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
378 QEMUIOVector *qiov, int nb_sectors,
379 BlockDriverCompletionFunc *cb,
380 void *opaque)
382 IscsiLun *iscsilun = bs->opaque;
383 IscsiAIOCB *acb;
385 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
386 return NULL;
389 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
390 trace_iscsi_aio_writev(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
392 acb->iscsilun = iscsilun;
393 acb->qiov = qiov;
394 acb->nb_sectors = nb_sectors;
395 acb->sector_num = sector_num;
396 acb->retries = ISCSI_CMD_RETRIES;
398 if (iscsi_aio_writev_acb(acb) != 0) {
399 qemu_aio_release(acb);
400 return NULL;
403 iscsi_set_events(iscsilun);
404 return &acb->common;
407 static int
408 iscsi_aio_readv_acb(IscsiAIOCB *acb);
410 static void
411 iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
412 void *command_data, void *opaque)
414 IscsiAIOCB *acb = opaque;
416 trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
418 if (acb->canceled != 0) {
419 return;
422 acb->status = 0;
423 if (status != 0) {
424 if (status == SCSI_STATUS_CHECK_CONDITION
425 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
426 && acb->retries-- > 0) {
427 scsi_free_scsi_task(acb->task);
428 acb->task = NULL;
429 if (iscsi_aio_readv_acb(acb) == 0) {
430 iscsi_set_events(acb->iscsilun);
431 return;
434 error_report("Failed to read16 data from iSCSI lun. %s",
435 iscsi_get_error(iscsi));
436 acb->status = -EIO;
439 iscsi_schedule_bh(acb);
442 static int
443 iscsi_aio_readv_acb(IscsiAIOCB *acb)
445 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
446 size_t size;
447 uint64_t lba;
448 uint32_t num_sectors;
449 int ret;
450 #if !defined(LIBISCSI_FEATURE_IOVECTOR)
451 int i;
452 #endif
454 acb->canceled = 0;
455 acb->bh = NULL;
456 acb->status = -EINPROGRESS;
457 acb->buf = NULL;
459 size = acb->nb_sectors * BDRV_SECTOR_SIZE;
461 acb->task = malloc(sizeof(struct scsi_task));
462 if (acb->task == NULL) {
463 error_report("iSCSI: Failed to allocate task for scsi READ16 "
464 "command. %s", iscsi_get_error(iscsi));
465 return -1;
467 memset(acb->task, 0, sizeof(struct scsi_task));
469 acb->task->xfer_dir = SCSI_XFER_READ;
470 acb->task->expxferlen = size;
471 lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
472 num_sectors = sector_qemu2lun(acb->nb_sectors, acb->iscsilun);
474 switch (acb->iscsilun->type) {
475 case TYPE_DISK:
476 acb->task->cdb_size = 16;
477 acb->task->cdb[0] = 0x88;
478 *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32);
479 *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff);
480 *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
481 break;
482 default:
483 acb->task->cdb_size = 10;
484 acb->task->cdb[0] = 0x28;
485 *(uint32_t *)&acb->task->cdb[2] = htonl(lba);
486 *(uint16_t *)&acb->task->cdb[7] = htons(num_sectors);
487 break;
490 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
491 iscsi_aio_read16_cb,
492 NULL,
493 acb);
494 if (ret != 0) {
495 scsi_free_scsi_task(acb->task);
496 return -1;
499 #if defined(LIBISCSI_FEATURE_IOVECTOR)
500 scsi_task_set_iov_in(acb->task, (struct scsi_iovec*) acb->qiov->iov, acb->qiov->niov);
501 #else
502 for (i = 0; i < acb->qiov->niov; i++) {
503 scsi_task_add_data_in_buffer(acb->task,
504 acb->qiov->iov[i].iov_len,
505 acb->qiov->iov[i].iov_base);
507 #endif
508 return 0;
511 static BlockDriverAIOCB *
512 iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
513 QEMUIOVector *qiov, int nb_sectors,
514 BlockDriverCompletionFunc *cb,
515 void *opaque)
517 IscsiLun *iscsilun = bs->opaque;
518 IscsiAIOCB *acb;
520 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
521 return NULL;
524 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
525 trace_iscsi_aio_readv(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
527 acb->nb_sectors = nb_sectors;
528 acb->sector_num = sector_num;
529 acb->iscsilun = iscsilun;
530 acb->qiov = qiov;
531 acb->retries = ISCSI_CMD_RETRIES;
533 if (iscsi_aio_readv_acb(acb) != 0) {
534 qemu_aio_release(acb);
535 return NULL;
538 iscsi_set_events(iscsilun);
539 return &acb->common;
542 static int
543 iscsi_aio_flush_acb(IscsiAIOCB *acb);
545 static void
546 iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
547 void *command_data, void *opaque)
549 IscsiAIOCB *acb = opaque;
551 if (acb->canceled != 0) {
552 return;
555 acb->status = 0;
556 if (status != 0) {
557 if (status == SCSI_STATUS_CHECK_CONDITION
558 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
559 && acb->retries-- > 0) {
560 scsi_free_scsi_task(acb->task);
561 acb->task = NULL;
562 if (iscsi_aio_flush_acb(acb) == 0) {
563 iscsi_set_events(acb->iscsilun);
564 return;
567 error_report("Failed to sync10 data on iSCSI lun. %s",
568 iscsi_get_error(iscsi));
569 acb->status = -EIO;
572 iscsi_schedule_bh(acb);
575 static int
576 iscsi_aio_flush_acb(IscsiAIOCB *acb)
578 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
580 acb->canceled = 0;
581 acb->bh = NULL;
582 acb->status = -EINPROGRESS;
583 acb->buf = NULL;
585 acb->task = iscsi_synchronizecache10_task(iscsi, acb->iscsilun->lun,
586 0, 0, 0, 0,
587 iscsi_synccache10_cb,
588 acb);
589 if (acb->task == NULL) {
590 error_report("iSCSI: Failed to send synchronizecache10 command. %s",
591 iscsi_get_error(iscsi));
592 return -1;
595 return 0;
598 static BlockDriverAIOCB *
599 iscsi_aio_flush(BlockDriverState *bs,
600 BlockDriverCompletionFunc *cb, void *opaque)
602 IscsiLun *iscsilun = bs->opaque;
604 IscsiAIOCB *acb;
606 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
608 acb->iscsilun = iscsilun;
609 acb->retries = ISCSI_CMD_RETRIES;
611 if (iscsi_aio_flush_acb(acb) != 0) {
612 qemu_aio_release(acb);
613 return NULL;
616 iscsi_set_events(iscsilun);
618 return &acb->common;
621 static int iscsi_aio_discard_acb(IscsiAIOCB *acb);
623 static void
624 iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
625 void *command_data, void *opaque)
627 IscsiAIOCB *acb = opaque;
629 if (acb->canceled != 0) {
630 return;
633 acb->status = 0;
634 if (status != 0) {
635 if (status == SCSI_STATUS_CHECK_CONDITION
636 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
637 && acb->retries-- > 0) {
638 scsi_free_scsi_task(acb->task);
639 acb->task = NULL;
640 if (iscsi_aio_discard_acb(acb) == 0) {
641 iscsi_set_events(acb->iscsilun);
642 return;
645 error_report("Failed to unmap data on iSCSI lun. %s",
646 iscsi_get_error(iscsi));
647 acb->status = -EIO;
650 iscsi_schedule_bh(acb);
653 static int iscsi_aio_discard_acb(IscsiAIOCB *acb) {
654 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
655 struct unmap_list list[1];
657 acb->canceled = 0;
658 acb->bh = NULL;
659 acb->status = -EINPROGRESS;
660 acb->buf = NULL;
662 list[0].lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
663 list[0].num = acb->nb_sectors * BDRV_SECTOR_SIZE / acb->iscsilun->block_size;
665 acb->task = iscsi_unmap_task(iscsi, acb->iscsilun->lun,
666 0, 0, &list[0], 1,
667 iscsi_unmap_cb,
668 acb);
669 if (acb->task == NULL) {
670 error_report("iSCSI: Failed to send unmap command. %s",
671 iscsi_get_error(iscsi));
672 return -1;
675 return 0;
678 static BlockDriverAIOCB *
679 iscsi_aio_discard(BlockDriverState *bs,
680 int64_t sector_num, int nb_sectors,
681 BlockDriverCompletionFunc *cb, void *opaque)
683 IscsiLun *iscsilun = bs->opaque;
684 IscsiAIOCB *acb;
686 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
688 acb->iscsilun = iscsilun;
689 acb->nb_sectors = nb_sectors;
690 acb->sector_num = sector_num;
691 acb->retries = ISCSI_CMD_RETRIES;
693 if (iscsi_aio_discard_acb(acb) != 0) {
694 qemu_aio_release(acb);
695 return NULL;
698 iscsi_set_events(iscsilun);
700 return &acb->common;
703 #ifdef __linux__
704 static void
705 iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
706 void *command_data, void *opaque)
708 IscsiAIOCB *acb = opaque;
710 g_free(acb->buf);
711 acb->buf = NULL;
713 if (acb->canceled != 0) {
714 return;
717 acb->status = 0;
718 if (status < 0) {
719 error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
720 iscsi_get_error(iscsi));
721 acb->status = -EIO;
724 acb->ioh->driver_status = 0;
725 acb->ioh->host_status = 0;
726 acb->ioh->resid = 0;
728 #define SG_ERR_DRIVER_SENSE 0x08
730 if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
731 int ss;
733 acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
735 acb->ioh->sb_len_wr = acb->task->datain.size - 2;
736 ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
737 acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
738 memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
741 iscsi_schedule_bh(acb);
744 static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
745 unsigned long int req, void *buf,
746 BlockDriverCompletionFunc *cb, void *opaque)
748 IscsiLun *iscsilun = bs->opaque;
749 struct iscsi_context *iscsi = iscsilun->iscsi;
750 struct iscsi_data data;
751 IscsiAIOCB *acb;
753 assert(req == SG_IO);
755 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
757 acb->iscsilun = iscsilun;
758 acb->canceled = 0;
759 acb->bh = NULL;
760 acb->status = -EINPROGRESS;
761 acb->buf = NULL;
762 acb->ioh = buf;
764 acb->task = malloc(sizeof(struct scsi_task));
765 if (acb->task == NULL) {
766 error_report("iSCSI: Failed to allocate task for scsi command. %s",
767 iscsi_get_error(iscsi));
768 qemu_aio_release(acb);
769 return NULL;
771 memset(acb->task, 0, sizeof(struct scsi_task));
773 switch (acb->ioh->dxfer_direction) {
774 case SG_DXFER_TO_DEV:
775 acb->task->xfer_dir = SCSI_XFER_WRITE;
776 break;
777 case SG_DXFER_FROM_DEV:
778 acb->task->xfer_dir = SCSI_XFER_READ;
779 break;
780 default:
781 acb->task->xfer_dir = SCSI_XFER_NONE;
782 break;
785 acb->task->cdb_size = acb->ioh->cmd_len;
786 memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
787 acb->task->expxferlen = acb->ioh->dxfer_len;
789 data.size = 0;
790 if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
791 if (acb->ioh->iovec_count == 0) {
792 data.data = acb->ioh->dxferp;
793 data.size = acb->ioh->dxfer_len;
794 } else {
795 #if defined(LIBISCSI_FEATURE_IOVECTOR)
796 scsi_task_set_iov_out(acb->task,
797 (struct scsi_iovec *) acb->ioh->dxferp,
798 acb->ioh->iovec_count);
799 #else
800 struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
802 acb->buf = g_malloc(acb->ioh->dxfer_len);
803 data.data = acb->buf;
804 data.size = iov_to_buf(iov, acb->ioh->iovec_count, 0,
805 acb->buf, acb->ioh->dxfer_len);
806 #endif
810 if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
811 iscsi_aio_ioctl_cb,
812 (data.size > 0) ? &data : NULL,
813 acb) != 0) {
814 scsi_free_scsi_task(acb->task);
815 qemu_aio_release(acb);
816 return NULL;
819 /* tell libiscsi to read straight into the buffer we got from ioctl */
820 if (acb->task->xfer_dir == SCSI_XFER_READ) {
821 if (acb->ioh->iovec_count == 0) {
822 scsi_task_add_data_in_buffer(acb->task,
823 acb->ioh->dxfer_len,
824 acb->ioh->dxferp);
825 } else {
826 #if defined(LIBISCSI_FEATURE_IOVECTOR)
827 scsi_task_set_iov_in(acb->task,
828 (struct scsi_iovec *) acb->ioh->dxferp,
829 acb->ioh->iovec_count);
830 #else
831 int i;
832 for (i = 0; i < acb->ioh->iovec_count; i++) {
833 struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
835 scsi_task_add_data_in_buffer(acb->task,
836 iov[i].iov_len,
837 iov[i].iov_base);
839 #endif
843 iscsi_set_events(iscsilun);
845 return &acb->common;
849 static void ioctl_cb(void *opaque, int status)
851 int *p_status = opaque;
852 *p_status = status;
855 static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
857 IscsiLun *iscsilun = bs->opaque;
858 int status;
860 switch (req) {
861 case SG_GET_VERSION_NUM:
862 *(int *)buf = 30000;
863 break;
864 case SG_GET_SCSI_ID:
865 ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
866 break;
867 case SG_IO:
868 status = -EINPROGRESS;
869 iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
871 while (status == -EINPROGRESS) {
872 qemu_aio_wait();
875 return 0;
876 default:
877 return -1;
879 return 0;
881 #endif
883 static int64_t
884 iscsi_getlength(BlockDriverState *bs)
886 IscsiLun *iscsilun = bs->opaque;
887 int64_t len;
889 len = iscsilun->num_blocks;
890 len *= iscsilun->block_size;
892 return len;
895 static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
896 int64_t sector_num,
897 int nb_sectors, int *pnum)
899 IscsiLun *iscsilun = bs->opaque;
900 struct scsi_get_lba_status *lbas = NULL;
901 struct scsi_lba_status_descriptor *lbasd = NULL;
902 struct IscsiTask iTask;
903 int64_t ret;
905 iscsi_co_init_iscsitask(iscsilun, &iTask);
907 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
908 ret = -EINVAL;
909 goto out;
912 /* default to all sectors allocated */
913 ret = BDRV_BLOCK_DATA;
914 ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
915 *pnum = nb_sectors;
917 /* LUN does not support logical block provisioning */
918 if (iscsilun->lbpme == 0) {
919 goto out;
922 retry:
923 if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
924 sector_qemu2lun(sector_num, iscsilun),
925 8 + 16, iscsi_co_generic_cb,
926 &iTask) == NULL) {
927 ret = -EIO;
928 goto out;
931 while (!iTask.complete) {
932 iscsi_set_events(iscsilun);
933 qemu_coroutine_yield();
936 if (iTask.do_retry) {
937 if (iTask.task != NULL) {
938 scsi_free_scsi_task(iTask.task);
939 iTask.task = NULL;
941 goto retry;
944 if (iTask.status != SCSI_STATUS_GOOD) {
945 /* in case the get_lba_status_callout fails (i.e.
946 * because the device is busy or the cmd is not
947 * supported) we pretend all blocks are allocated
948 * for backwards compatiblity */
949 goto out;
952 lbas = scsi_datain_unmarshall(iTask.task);
953 if (lbas == NULL) {
954 ret = -EIO;
955 goto out;
958 lbasd = &lbas->descriptors[0];
960 if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
961 ret = -EIO;
962 goto out;
965 *pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
966 if (*pnum > nb_sectors) {
967 *pnum = nb_sectors;
970 if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
971 lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
972 ret &= ~BDRV_BLOCK_DATA;
973 if (iscsilun->lbprz) {
974 ret |= BDRV_BLOCK_ZERO;
978 out:
979 if (iTask.task != NULL) {
980 scsi_free_scsi_task(iTask.task);
982 return ret;
985 static int parse_chap(struct iscsi_context *iscsi, const char *target)
987 QemuOptsList *list;
988 QemuOpts *opts;
989 const char *user = NULL;
990 const char *password = NULL;
992 list = qemu_find_opts("iscsi");
993 if (!list) {
994 return 0;
997 opts = qemu_opts_find(list, target);
998 if (opts == NULL) {
999 opts = QTAILQ_FIRST(&list->head);
1000 if (!opts) {
1001 return 0;
1005 user = qemu_opt_get(opts, "user");
1006 if (!user) {
1007 return 0;
1010 password = qemu_opt_get(opts, "password");
1011 if (!password) {
1012 error_report("CHAP username specified but no password was given");
1013 return -1;
1016 if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
1017 error_report("Failed to set initiator username and password");
1018 return -1;
1021 return 0;
1024 static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
1026 QemuOptsList *list;
1027 QemuOpts *opts;
1028 const char *digest = NULL;
1030 list = qemu_find_opts("iscsi");
1031 if (!list) {
1032 return;
1035 opts = qemu_opts_find(list, target);
1036 if (opts == NULL) {
1037 opts = QTAILQ_FIRST(&list->head);
1038 if (!opts) {
1039 return;
1043 digest = qemu_opt_get(opts, "header-digest");
1044 if (!digest) {
1045 return;
1048 if (!strcmp(digest, "CRC32C")) {
1049 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
1050 } else if (!strcmp(digest, "NONE")) {
1051 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
1052 } else if (!strcmp(digest, "CRC32C-NONE")) {
1053 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
1054 } else if (!strcmp(digest, "NONE-CRC32C")) {
1055 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
1056 } else {
1057 error_report("Invalid header-digest setting : %s", digest);
1061 static char *parse_initiator_name(const char *target)
1063 QemuOptsList *list;
1064 QemuOpts *opts;
1065 const char *name;
1066 char *iscsi_name;
1067 UuidInfo *uuid_info;
1069 list = qemu_find_opts("iscsi");
1070 if (list) {
1071 opts = qemu_opts_find(list, target);
1072 if (!opts) {
1073 opts = QTAILQ_FIRST(&list->head);
1075 if (opts) {
1076 name = qemu_opt_get(opts, "initiator-name");
1077 if (name) {
1078 return g_strdup(name);
1083 uuid_info = qmp_query_uuid(NULL);
1084 if (strcmp(uuid_info->UUID, UUID_NONE) == 0) {
1085 name = qemu_get_vm_name();
1086 } else {
1087 name = uuid_info->UUID;
1089 iscsi_name = g_strdup_printf("iqn.2008-11.org.linux-kvm%s%s",
1090 name ? ":" : "", name ? name : "");
1091 qapi_free_UuidInfo(uuid_info);
1092 return iscsi_name;
1095 #if defined(LIBISCSI_FEATURE_NOP_COUNTER)
1096 static void iscsi_nop_timed_event(void *opaque)
1098 IscsiLun *iscsilun = opaque;
1100 if (iscsi_get_nops_in_flight(iscsilun->iscsi) > MAX_NOP_FAILURES) {
1101 error_report("iSCSI: NOP timeout. Reconnecting...");
1102 iscsi_reconnect(iscsilun->iscsi);
1105 if (iscsi_nop_out_async(iscsilun->iscsi, NULL, NULL, 0, NULL) != 0) {
1106 error_report("iSCSI: failed to sent NOP-Out. Disabling NOP messages.");
1107 return;
1110 timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
1111 iscsi_set_events(iscsilun);
1113 #endif
1115 static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
1117 struct scsi_task *task = NULL;
1118 struct scsi_readcapacity10 *rc10 = NULL;
1119 struct scsi_readcapacity16 *rc16 = NULL;
1120 int ret = 0;
1121 int retries = ISCSI_CMD_RETRIES;
1123 do {
1124 if (task != NULL) {
1125 scsi_free_scsi_task(task);
1126 task = NULL;
1129 switch (iscsilun->type) {
1130 case TYPE_DISK:
1131 task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
1132 if (task != NULL && task->status == SCSI_STATUS_GOOD) {
1133 rc16 = scsi_datain_unmarshall(task);
1134 if (rc16 == NULL) {
1135 error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
1136 ret = -EINVAL;
1137 } else {
1138 iscsilun->block_size = rc16->block_length;
1139 iscsilun->num_blocks = rc16->returned_lba + 1;
1140 iscsilun->lbpme = rc16->lbpme;
1141 iscsilun->lbprz = rc16->lbprz;
1144 break;
1145 case TYPE_ROM:
1146 task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
1147 if (task != NULL && task->status == SCSI_STATUS_GOOD) {
1148 rc10 = scsi_datain_unmarshall(task);
1149 if (rc10 == NULL) {
1150 error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
1151 ret = -EINVAL;
1152 } else {
1153 iscsilun->block_size = rc10->block_size;
1154 if (rc10->lba == 0) {
1155 /* blank disk loaded */
1156 iscsilun->num_blocks = 0;
1157 } else {
1158 iscsilun->num_blocks = rc10->lba + 1;
1162 break;
1163 default:
1164 return 0;
1166 } while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
1167 && task->sense.key == SCSI_SENSE_UNIT_ATTENTION
1168 && retries-- > 0);
1170 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1171 error_report("iSCSI: failed to send readcapacity10 command.");
1172 ret = -EINVAL;
1174 if (task) {
1175 scsi_free_scsi_task(task);
1177 return ret;
1180 /* TODO Convert to fine grained options */
1181 static QemuOptsList runtime_opts = {
1182 .name = "iscsi",
1183 .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
1184 .desc = {
1186 .name = "filename",
1187 .type = QEMU_OPT_STRING,
1188 .help = "URL to the iscsi image",
1190 { /* end of list */ }
1194 static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi,
1195 int lun, int evpd, int pc) {
1196 int full_size;
1197 struct scsi_task *task = NULL;
1198 task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64);
1199 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1200 goto fail;
1202 full_size = scsi_datain_getfullsize(task);
1203 if (full_size > task->datain.size) {
1204 scsi_free_scsi_task(task);
1206 /* we need more data for the full list */
1207 task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size);
1208 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1209 goto fail;
1213 return task;
1215 fail:
1216 error_report("iSCSI: Inquiry command failed : %s",
1217 iscsi_get_error(iscsi));
1218 if (task) {
1219 scsi_free_scsi_task(task);
1220 return NULL;
1222 return NULL;
1226 * We support iscsi url's on the form
1227 * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
1229 static int iscsi_open(BlockDriverState *bs, QDict *options, int flags)
1231 IscsiLun *iscsilun = bs->opaque;
1232 struct iscsi_context *iscsi = NULL;
1233 struct iscsi_url *iscsi_url = NULL;
1234 struct scsi_task *task = NULL;
1235 struct scsi_inquiry_standard *inq = NULL;
1236 char *initiator_name = NULL;
1237 QemuOpts *opts;
1238 Error *local_err = NULL;
1239 const char *filename;
1240 int ret;
1242 if ((BDRV_SECTOR_SIZE % 512) != 0) {
1243 error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
1244 "BDRV_SECTOR_SIZE(%lld) is not a multiple "
1245 "of 512", BDRV_SECTOR_SIZE);
1246 return -EINVAL;
1249 opts = qemu_opts_create_nofail(&runtime_opts);
1250 qemu_opts_absorb_qdict(opts, options, &local_err);
1251 if (error_is_set(&local_err)) {
1252 qerror_report_err(local_err);
1253 error_free(local_err);
1254 ret = -EINVAL;
1255 goto out;
1258 filename = qemu_opt_get(opts, "filename");
1261 iscsi_url = iscsi_parse_full_url(iscsi, filename);
1262 if (iscsi_url == NULL) {
1263 error_report("Failed to parse URL : %s", filename);
1264 ret = -EINVAL;
1265 goto out;
1268 memset(iscsilun, 0, sizeof(IscsiLun));
1270 initiator_name = parse_initiator_name(iscsi_url->target);
1272 iscsi = iscsi_create_context(initiator_name);
1273 if (iscsi == NULL) {
1274 error_report("iSCSI: Failed to create iSCSI context.");
1275 ret = -ENOMEM;
1276 goto out;
1279 if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
1280 error_report("iSCSI: Failed to set target name.");
1281 ret = -EINVAL;
1282 goto out;
1285 if (iscsi_url->user != NULL) {
1286 ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
1287 iscsi_url->passwd);
1288 if (ret != 0) {
1289 error_report("Failed to set initiator username and password");
1290 ret = -EINVAL;
1291 goto out;
1295 /* check if we got CHAP username/password via the options */
1296 if (parse_chap(iscsi, iscsi_url->target) != 0) {
1297 error_report("iSCSI: Failed to set CHAP user/password");
1298 ret = -EINVAL;
1299 goto out;
1302 if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
1303 error_report("iSCSI: Failed to set session type to normal.");
1304 ret = -EINVAL;
1305 goto out;
1308 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
1310 /* check if we got HEADER_DIGEST via the options */
1311 parse_header_digest(iscsi, iscsi_url->target);
1313 if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
1314 error_report("iSCSI: Failed to connect to LUN : %s",
1315 iscsi_get_error(iscsi));
1316 ret = -EINVAL;
1317 goto out;
1320 iscsilun->iscsi = iscsi;
1321 iscsilun->lun = iscsi_url->lun;
1323 task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
1325 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1326 error_report("iSCSI: failed to send inquiry command.");
1327 ret = -EINVAL;
1328 goto out;
1331 inq = scsi_datain_unmarshall(task);
1332 if (inq == NULL) {
1333 error_report("iSCSI: Failed to unmarshall inquiry data.");
1334 ret = -EINVAL;
1335 goto out;
1338 iscsilun->type = inq->periperal_device_type;
1340 if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
1341 goto out;
1343 bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
1345 /* Medium changer or tape. We dont have any emulation for this so this must
1346 * be sg ioctl compatible. We force it to be sg, otherwise qemu will try
1347 * to read from the device to guess the image format.
1349 if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
1350 iscsilun->type == TYPE_TAPE) {
1351 bs->sg = 1;
1354 if (iscsilun->lbpme) {
1355 struct scsi_inquiry_logical_block_provisioning *inq_lbp;
1356 task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1357 SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING);
1358 if (task == NULL) {
1359 ret = -EINVAL;
1360 goto out;
1362 inq_lbp = scsi_datain_unmarshall(task);
1363 if (inq_lbp == NULL) {
1364 error_report("iSCSI: failed to unmarshall inquiry datain blob");
1365 ret = -EINVAL;
1366 goto out;
1368 memcpy(&iscsilun->lbp, inq_lbp,
1369 sizeof(struct scsi_inquiry_logical_block_provisioning));
1370 scsi_free_scsi_task(task);
1371 task = NULL;
1374 if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
1375 struct scsi_inquiry_block_limits *inq_bl;
1376 task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1377 SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS);
1378 if (task == NULL) {
1379 ret = -EINVAL;
1380 goto out;
1382 inq_bl = scsi_datain_unmarshall(task);
1383 if (inq_bl == NULL) {
1384 error_report("iSCSI: failed to unmarshall inquiry datain blob");
1385 ret = -EINVAL;
1386 goto out;
1388 memcpy(&iscsilun->bl, inq_bl,
1389 sizeof(struct scsi_inquiry_block_limits));
1390 scsi_free_scsi_task(task);
1391 task = NULL;
1394 #if defined(LIBISCSI_FEATURE_NOP_COUNTER)
1395 /* Set up a timer for sending out iSCSI NOPs */
1396 iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
1397 timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
1398 #endif
1400 out:
1401 qemu_opts_del(opts);
1402 if (initiator_name != NULL) {
1403 g_free(initiator_name);
1405 if (iscsi_url != NULL) {
1406 iscsi_destroy_url(iscsi_url);
1408 if (task != NULL) {
1409 scsi_free_scsi_task(task);
1412 if (ret) {
1413 if (iscsi != NULL) {
1414 iscsi_destroy_context(iscsi);
1416 memset(iscsilun, 0, sizeof(IscsiLun));
1418 return ret;
1421 static void iscsi_close(BlockDriverState *bs)
1423 IscsiLun *iscsilun = bs->opaque;
1424 struct iscsi_context *iscsi = iscsilun->iscsi;
1426 if (iscsilun->nop_timer) {
1427 timer_del(iscsilun->nop_timer);
1428 timer_free(iscsilun->nop_timer);
1430 qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
1431 iscsi_destroy_context(iscsi);
1432 memset(iscsilun, 0, sizeof(IscsiLun));
1435 static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
1437 IscsiLun *iscsilun = bs->opaque;
1438 int ret = 0;
1440 if (iscsilun->type != TYPE_DISK) {
1441 return -ENOTSUP;
1444 if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
1445 return ret;
1448 if (offset > iscsi_getlength(bs)) {
1449 return -EINVAL;
1452 return 0;
1455 static int iscsi_has_zero_init(BlockDriverState *bs)
1457 return 0;
1460 static int iscsi_create(const char *filename, QEMUOptionParameter *options)
1462 int ret = 0;
1463 int64_t total_size = 0;
1464 BlockDriverState *bs;
1465 IscsiLun *iscsilun = NULL;
1466 QDict *bs_options;
1468 bs = bdrv_new("");
1470 /* Read out options */
1471 while (options && options->name) {
1472 if (!strcmp(options->name, "size")) {
1473 total_size = options->value.n / BDRV_SECTOR_SIZE;
1475 options++;
1478 bs->opaque = g_malloc0(sizeof(struct IscsiLun));
1479 iscsilun = bs->opaque;
1481 bs_options = qdict_new();
1482 qdict_put(bs_options, "filename", qstring_from_str(filename));
1483 ret = iscsi_open(bs, bs_options, 0);
1484 QDECREF(bs_options);
1486 if (ret != 0) {
1487 goto out;
1489 if (iscsilun->nop_timer) {
1490 timer_del(iscsilun->nop_timer);
1491 timer_free(iscsilun->nop_timer);
1493 if (iscsilun->type != TYPE_DISK) {
1494 ret = -ENODEV;
1495 goto out;
1497 if (bs->total_sectors < total_size) {
1498 ret = -ENOSPC;
1499 goto out;
1502 ret = 0;
1503 out:
1504 if (iscsilun->iscsi != NULL) {
1505 iscsi_destroy_context(iscsilun->iscsi);
1507 g_free(bs->opaque);
1508 bs->opaque = NULL;
1509 bdrv_unref(bs);
1510 return ret;
1513 static QEMUOptionParameter iscsi_create_options[] = {
1515 .name = BLOCK_OPT_SIZE,
1516 .type = OPT_SIZE,
1517 .help = "Virtual disk size"
1519 { NULL }
1522 static BlockDriver bdrv_iscsi = {
1523 .format_name = "iscsi",
1524 .protocol_name = "iscsi",
1526 .instance_size = sizeof(IscsiLun),
1527 .bdrv_file_open = iscsi_open,
1528 .bdrv_close = iscsi_close,
1529 .bdrv_create = iscsi_create,
1530 .create_options = iscsi_create_options,
1532 .bdrv_getlength = iscsi_getlength,
1533 .bdrv_truncate = iscsi_truncate,
1535 .bdrv_co_get_block_status = iscsi_co_get_block_status,
1537 .bdrv_aio_readv = iscsi_aio_readv,
1538 .bdrv_aio_writev = iscsi_aio_writev,
1539 .bdrv_aio_flush = iscsi_aio_flush,
1541 .bdrv_aio_discard = iscsi_aio_discard,
1542 .bdrv_has_zero_init = iscsi_has_zero_init,
1544 #ifdef __linux__
1545 .bdrv_ioctl = iscsi_ioctl,
1546 .bdrv_aio_ioctl = iscsi_aio_ioctl,
1547 #endif
1550 static QemuOptsList qemu_iscsi_opts = {
1551 .name = "iscsi",
1552 .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head),
1553 .desc = {
1555 .name = "user",
1556 .type = QEMU_OPT_STRING,
1557 .help = "username for CHAP authentication to target",
1559 .name = "password",
1560 .type = QEMU_OPT_STRING,
1561 .help = "password for CHAP authentication to target",
1563 .name = "header-digest",
1564 .type = QEMU_OPT_STRING,
1565 .help = "HeaderDigest setting. "
1566 "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
1568 .name = "initiator-name",
1569 .type = QEMU_OPT_STRING,
1570 .help = "Initiator iqn name to use when connecting",
1572 { /* end of list */ }
1576 static void iscsi_block_init(void)
1578 bdrv_register(&bdrv_iscsi);
1579 qemu_add_opts(&qemu_iscsi_opts);
1582 block_init(iscsi_block_init);