]> git.proxmox.com Git - mirror_qemu.git/blame - block/iscsi.c
iscsi: simplify iscsi_co_discard
[mirror_qemu.git] / block / iscsi.c
CommitLineData
c589b249
RS
1/*
2 * QEMU Block driver for iSCSI images
3 *
4 * Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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.
23 */
24
25#include "config-host.h"
26
27#include <poll.h>
f4dfa67f 28#include <arpa/inet.h>
c589b249 29#include "qemu-common.h"
1de7afc9
PB
30#include "qemu/config-file.h"
31#include "qemu/error-report.h"
737e150e 32#include "block/block_int.h"
c589b249 33#include "trace.h"
0d09e41a 34#include "block/scsi.h"
0a53f010 35#include "qemu/iov.h"
5accc840
PB
36#include "sysemu/sysemu.h"
37#include "qmp-commands.h"
c589b249
RS
38
39#include <iscsi/iscsi.h>
40#include <iscsi/scsi-lowlevel.h>
41
98392453
RS
42#ifdef __linux__
43#include <scsi/sg.h>
0d09e41a 44#include <block/scsi.h>
98392453 45#endif
c589b249
RS
46
47typedef struct IscsiLun {
48 struct iscsi_context *iscsi;
49 int lun;
dbfff6d7 50 enum scsi_inquiry_peripheral_device_type type;
c589b249 51 int block_size;
c7b4a952 52 uint64_t num_blocks;
c9b9f682 53 int events;
5b5d34ec 54 QEMUTimer *nop_timer;
f18a7cbb
PL
55 uint8_t lbpme;
56 uint8_t lbprz;
57 struct scsi_inquiry_logical_block_provisioning lbp;
58 struct scsi_inquiry_block_limits bl;
c589b249
RS
59} IscsiLun;
60
54a5c1d5
PL
61typedef 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;
69
c589b249
RS
70typedef 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;
1dde716e 79 int retries;
1dde716e
PL
80 int64_t sector_num;
81 int nb_sectors;
98392453
RS
82#ifdef __linux__
83 sg_io_hdr_t *ioh;
84#endif
c589b249
RS
85} IscsiAIOCB;
86
5b5d34ec
PL
87#define NOP_INTERVAL 5000
88#define MAX_NOP_FAILURES 3
1dde716e 89#define ISCSI_CMD_RETRIES 5
5b5d34ec 90
27cbd828 91static void
cfb3f506 92iscsi_bh_cb(void *p)
27cbd828
PB
93{
94 IscsiAIOCB *acb = p;
95
96 qemu_bh_delete(acb->bh);
97
4790b03d
PB
98 g_free(acb->buf);
99 acb->buf = NULL;
100
27cbd828
PB
101 if (acb->canceled == 0) {
102 acb->common.cb(acb->common.opaque, acb->status);
103 }
104
1bd075f2
PB
105 if (acb->task != NULL) {
106 scsi_free_scsi_task(acb->task);
107 acb->task = NULL;
108 }
109
27cbd828
PB
110 qemu_aio_release(acb);
111}
112
cfb3f506
PB
113static void
114iscsi_schedule_bh(IscsiAIOCB *acb)
27cbd828 115{
1bd075f2
PB
116 if (acb->bh) {
117 return;
118 }
cfb3f506 119 acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
27cbd828 120 qemu_bh_schedule(acb->bh);
27cbd828
PB
121}
122
54a5c1d5
PL
123static void
124iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
125 void *command_data, void *opaque)
126{
127 struct IscsiTask *iTask = opaque;
128 struct scsi_task *task = command_data;
129
130 iTask->complete = 1;
131 iTask->status = status;
132 iTask->do_retry = 0;
133 iTask->task = task;
134
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;
139 }
140
141 if (status != SCSI_STATUS_GOOD) {
142 error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi));
143 }
144
145out:
146 if (iTask->co) {
147 qemu_coroutine_enter(iTask->co, NULL);
148 }
149}
150
151static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
152{
153 *iTask = (struct IscsiTask) {
154 .co = qemu_coroutine_self(),
155 .retries = ISCSI_CMD_RETRIES,
156 };
157}
27cbd828 158
c589b249
RS
159static void
160iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
161 void *private_data)
162{
1bd075f2
PB
163 IscsiAIOCB *acb = private_data;
164
165 acb->status = -ECANCELED;
166 iscsi_schedule_bh(acb);
c589b249
RS
167}
168
169static void
170iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
171{
172 IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
173 IscsiLun *iscsilun = acb->iscsilun;
174
1bd075f2
PB
175 if (acb->status != -EINPROGRESS) {
176 return;
177 }
178
b2090919 179 acb->canceled = 1;
c589b249 180
b2090919 181 /* send a task mgmt call to the target to cancel the task on the target */
64e69e80 182 iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
1bd075f2 183 iscsi_abort_task_cb, acb);
b2090919 184
1bd075f2
PB
185 while (acb->status == -EINPROGRESS) {
186 qemu_aio_wait();
187 }
c589b249
RS
188}
189
d7331bed 190static const AIOCBInfo iscsi_aiocb_info = {
c589b249
RS
191 .aiocb_size = sizeof(IscsiAIOCB),
192 .cancel = iscsi_aio_cancel,
193};
194
195
196static void iscsi_process_read(void *arg);
197static void iscsi_process_write(void *arg);
198
c589b249
RS
199static void
200iscsi_set_events(IscsiLun *iscsilun)
201{
202 struct iscsi_context *iscsi = iscsilun->iscsi;
c9b9f682
RS
203 int ev;
204
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,
c9b9f682
RS
212 iscsilun);
213
214 }
215
c9b9f682 216 iscsilun->events = ev;
c589b249
RS
217}
218
219static void
220iscsi_process_read(void *arg)
221{
222 IscsiLun *iscsilun = arg;
223 struct iscsi_context *iscsi = iscsilun->iscsi;
224
225 iscsi_service(iscsi, POLLIN);
226 iscsi_set_events(iscsilun);
227}
228
229static void
230iscsi_process_write(void *arg)
231{
232 IscsiLun *iscsilun = arg;
233 struct iscsi_context *iscsi = iscsilun->iscsi;
234
235 iscsi_service(iscsi, POLLOUT);
236 iscsi_set_events(iscsilun);
237}
238
1dde716e
PL
239static int
240iscsi_aio_writev_acb(IscsiAIOCB *acb);
c589b249 241
c589b249 242static void
f4dfa67f 243iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
c589b249
RS
244 void *command_data, void *opaque)
245{
246 IscsiAIOCB *acb = opaque;
247
f4dfa67f 248 trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled);
c589b249
RS
249
250 g_free(acb->buf);
4790b03d 251 acb->buf = NULL;
c589b249 252
b2090919 253 if (acb->canceled != 0) {
c589b249
RS
254 return;
255 }
256
257 acb->status = 0;
1dde716e
PL
258 if (status != 0) {
259 if (status == SCSI_STATUS_CHECK_CONDITION
260 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
261 && acb->retries-- > 0) {
f0d2a4d4
PB
262 scsi_free_scsi_task(acb->task);
263 acb->task = NULL;
1dde716e
PL
264 if (iscsi_aio_writev_acb(acb) == 0) {
265 iscsi_set_events(acb->iscsilun);
266 return;
267 }
268 }
f4dfa67f 269 error_report("Failed to write16 data to iSCSI lun. %s",
c589b249
RS
270 iscsi_get_error(iscsi));
271 acb->status = -EIO;
272 }
273
cfb3f506 274 iscsi_schedule_bh(acb);
c589b249
RS
275}
276
0777b5dd
PL
277static int64_t sector_lun2qemu(int64_t sector, IscsiLun *iscsilun)
278{
279 return sector * iscsilun->block_size / BDRV_SECTOR_SIZE;
280}
281
c589b249
RS
282static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
283{
284 return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
285}
286
91bea4e2
PL
287static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
288 IscsiLun *iscsilun)
289{
290 if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
291 (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) {
f5075224
RJ
292 error_report("iSCSI misaligned request: "
293 "iscsilun->block_size %u, sector_num %" PRIi64
294 ", nb_sectors %d",
91bea4e2
PL
295 iscsilun->block_size, sector_num, nb_sectors);
296 return 0;
297 }
298 return 1;
299}
300
1dde716e
PL
301static int
302iscsi_aio_writev_acb(IscsiAIOCB *acb)
c589b249 303{
1dde716e 304 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
c589b249 305 size_t size;
f4dfa67f
RS
306 uint32_t num_sectors;
307 uint64_t lba;
7371d56f 308#if !defined(LIBISCSI_FEATURE_IOVECTOR)
f4dfa67f 309 struct iscsi_data data;
7371d56f
PL
310#endif
311 int ret;
c589b249 312
c589b249 313 acb->canceled = 0;
1bd075f2
PB
314 acb->bh = NULL;
315 acb->status = -EINPROGRESS;
4790b03d 316 acb->buf = NULL;
c589b249 317
c589b249 318 /* this will allow us to get rid of 'buf' completely */
1dde716e 319 size = acb->nb_sectors * BDRV_SECTOR_SIZE;
7371d56f
PL
320
321#if !defined(LIBISCSI_FEATURE_IOVECTOR)
4cc841b5
PL
322 data.size = MIN(size, acb->qiov->size);
323
324 /* if the iovec only contains one buffer we can pass it directly */
325 if (acb->qiov->niov == 1) {
4cc841b5
PL
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;
331 }
7371d56f 332#endif
f4dfa67f
RS
333
334 acb->task = malloc(sizeof(struct scsi_task));
c589b249 335 if (acb->task == NULL) {
f4dfa67f
RS
336 error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
337 "command. %s", iscsi_get_error(iscsi));
1dde716e 338 return -1;
f4dfa67f
RS
339 }
340 memset(acb->task, 0, sizeof(struct scsi_task));
341
342 acb->task->xfer_dir = SCSI_XFER_WRITE;
343 acb->task->cdb_size = 16;
344 acb->task->cdb[0] = 0x8a;
1dde716e 345 lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
f4dfa67f
RS
346 *(uint32_t *)&acb->task->cdb[2] = htonl(lba >> 32);
347 *(uint32_t *)&acb->task->cdb[6] = htonl(lba & 0xffffffff);
0777b5dd 348 num_sectors = sector_qemu2lun(acb->nb_sectors, acb->iscsilun);
f4dfa67f
RS
349 *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
350 acb->task->expxferlen = size;
351
7371d56f 352#if defined(LIBISCSI_FEATURE_IOVECTOR)
1dde716e 353 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
7371d56f
PL
354 iscsi_aio_write16_cb,
355 NULL,
356 acb);
357#else
1dde716e 358 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
7371d56f
PL
359 iscsi_aio_write16_cb,
360 &data,
361 acb);
362#endif
363 if (ret != 0) {
f0d2a4d4 364 scsi_free_scsi_task(acb->task);
c589b249 365 g_free(acb->buf);
1dde716e 366 return -1;
c589b249
RS
367 }
368
7371d56f
PL
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
372
1dde716e
PL
373 return 0;
374}
375
376static BlockDriverAIOCB *
377iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
378 QEMUIOVector *qiov, int nb_sectors,
379 BlockDriverCompletionFunc *cb,
380 void *opaque)
381{
382 IscsiLun *iscsilun = bs->opaque;
383 IscsiAIOCB *acb;
c589b249 384
91bea4e2
PL
385 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
386 return NULL;
387 }
388
1dde716e
PL
389 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
390 trace_iscsi_aio_writev(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
391
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;
397
398 if (iscsi_aio_writev_acb(acb) != 0) {
1dde716e
PL
399 qemu_aio_release(acb);
400 return NULL;
401 }
402
403 iscsi_set_events(iscsilun);
c589b249
RS
404 return &acb->common;
405}
406
1dde716e
PL
407static int
408iscsi_aio_readv_acb(IscsiAIOCB *acb);
409
c589b249 410static void
f4dfa67f 411iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
c589b249
RS
412 void *command_data, void *opaque)
413{
414 IscsiAIOCB *acb = opaque;
415
f4dfa67f 416 trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
c589b249 417
b2090919 418 if (acb->canceled != 0) {
c589b249
RS
419 return;
420 }
421
422 acb->status = 0;
423 if (status != 0) {
1dde716e
PL
424 if (status == SCSI_STATUS_CHECK_CONDITION
425 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
426 && acb->retries-- > 0) {
f0d2a4d4
PB
427 scsi_free_scsi_task(acb->task);
428 acb->task = NULL;
1dde716e
PL
429 if (iscsi_aio_readv_acb(acb) == 0) {
430 iscsi_set_events(acb->iscsilun);
431 return;
432 }
433 }
f4dfa67f 434 error_report("Failed to read16 data from iSCSI lun. %s",
c589b249
RS
435 iscsi_get_error(iscsi));
436 acb->status = -EIO;
437 }
438
cfb3f506 439 iscsi_schedule_bh(acb);
c589b249
RS
440}
441
1dde716e
PL
442static int
443iscsi_aio_readv_acb(IscsiAIOCB *acb)
c589b249 444{
1dde716e 445 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
7e4d5a9f 446 size_t size;
1dde716e
PL
447 uint64_t lba;
448 uint32_t num_sectors;
449 int ret;
7371d56f 450#if !defined(LIBISCSI_FEATURE_IOVECTOR)
c589b249 451 int i;
7371d56f 452#endif
c589b249
RS
453
454 acb->canceled = 0;
1bd075f2
PB
455 acb->bh = NULL;
456 acb->status = -EINPROGRESS;
c589b249
RS
457 acb->buf = NULL;
458
7e4d5a9f 459 size = acb->nb_sectors * BDRV_SECTOR_SIZE;
f4dfa67f
RS
460
461 acb->task = malloc(sizeof(struct scsi_task));
c589b249 462 if (acb->task == NULL) {
f4dfa67f
RS
463 error_report("iSCSI: Failed to allocate task for scsi READ16 "
464 "command. %s", iscsi_get_error(iscsi));
1dde716e 465 return -1;
f4dfa67f
RS
466 }
467 memset(acb->task, 0, sizeof(struct scsi_task));
468
469 acb->task->xfer_dir = SCSI_XFER_READ;
7e4d5a9f 470 acb->task->expxferlen = size;
1dde716e 471 lba = sector_qemu2lun(acb->sector_num, acb->iscsilun);
7e4d5a9f 472 num_sectors = sector_qemu2lun(acb->nb_sectors, acb->iscsilun);
f4dfa67f 473
1dde716e 474 switch (acb->iscsilun->type) {
f4dfa67f
RS
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;
488 }
e829b0bb 489
1dde716e 490 ret = iscsi_scsi_command_async(iscsi, acb->iscsilun->lun, acb->task,
7371d56f
PL
491 iscsi_aio_read16_cb,
492 NULL,
493 acb);
494 if (ret != 0) {
f0d2a4d4 495 scsi_free_scsi_task(acb->task);
1dde716e 496 return -1;
c589b249
RS
497 }
498
7371d56f
PL
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
c589b249
RS
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);
506 }
7371d56f 507#endif
1dde716e
PL
508 return 0;
509}
c589b249 510
1dde716e
PL
511static BlockDriverAIOCB *
512iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
513 QEMUIOVector *qiov, int nb_sectors,
514 BlockDriverCompletionFunc *cb,
515 void *opaque)
516{
517 IscsiLun *iscsilun = bs->opaque;
518 IscsiAIOCB *acb;
519
91bea4e2
PL
520 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
521 return NULL;
522 }
523
1dde716e
PL
524 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
525 trace_iscsi_aio_readv(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
526
527 acb->nb_sectors = nb_sectors;
528 acb->sector_num = sector_num;
529 acb->iscsilun = iscsilun;
530 acb->qiov = qiov;
1dde716e
PL
531 acb->retries = ISCSI_CMD_RETRIES;
532
533 if (iscsi_aio_readv_acb(acb) != 0) {
1dde716e
PL
534 qemu_aio_release(acb);
535 return NULL;
536 }
c589b249 537
1dde716e 538 iscsi_set_events(iscsilun);
c589b249
RS
539 return &acb->common;
540}
541
1dde716e
PL
542static int
543iscsi_aio_flush_acb(IscsiAIOCB *acb);
c589b249
RS
544
545static void
546iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
547 void *command_data, void *opaque)
548{
549 IscsiAIOCB *acb = opaque;
550
b2090919 551 if (acb->canceled != 0) {
c589b249
RS
552 return;
553 }
554
555 acb->status = 0;
1dde716e
PL
556 if (status != 0) {
557 if (status == SCSI_STATUS_CHECK_CONDITION
558 && acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
559 && acb->retries-- > 0) {
f0d2a4d4
PB
560 scsi_free_scsi_task(acb->task);
561 acb->task = NULL;
1dde716e
PL
562 if (iscsi_aio_flush_acb(acb) == 0) {
563 iscsi_set_events(acb->iscsilun);
564 return;
565 }
566 }
c589b249
RS
567 error_report("Failed to sync10 data on iSCSI lun. %s",
568 iscsi_get_error(iscsi));
569 acb->status = -EIO;
570 }
571
cfb3f506 572 iscsi_schedule_bh(acb);
c589b249
RS
573}
574
1dde716e
PL
575static int
576iscsi_aio_flush_acb(IscsiAIOCB *acb)
c589b249 577{
1dde716e 578 struct iscsi_context *iscsi = acb->iscsilun->iscsi;
c589b249 579
c589b249 580 acb->canceled = 0;
1bd075f2
PB
581 acb->bh = NULL;
582 acb->status = -EINPROGRESS;
4790b03d 583 acb->buf = NULL;
c589b249 584
1dde716e 585 acb->task = iscsi_synchronizecache10_task(iscsi, acb->iscsilun->lun,
c589b249
RS
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));
1dde716e
PL
592 return -1;
593 }
594
595 return 0;
596}
597
598static BlockDriverAIOCB *
599iscsi_aio_flush(BlockDriverState *bs,
600 BlockDriverCompletionFunc *cb, void *opaque)
601{
602 IscsiLun *iscsilun = bs->opaque;
603
604 IscsiAIOCB *acb;
605
606 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
607
608 acb->iscsilun = iscsilun;
609 acb->retries = ISCSI_CMD_RETRIES;
610
611 if (iscsi_aio_flush_acb(acb) != 0) {
c589b249
RS
612 qemu_aio_release(acb);
613 return NULL;
614 }
615
616 iscsi_set_events(iscsilun);
617
618 return &acb->common;
619}
620
98392453
RS
621#ifdef __linux__
622static void
623iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
624 void *command_data, void *opaque)
625{
626 IscsiAIOCB *acb = opaque;
627
0a53f010
RS
628 g_free(acb->buf);
629 acb->buf = NULL;
630
b2090919 631 if (acb->canceled != 0) {
98392453
RS
632 return;
633 }
634
635 acb->status = 0;
636 if (status < 0) {
637 error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
638 iscsi_get_error(iscsi));
639 acb->status = -EIO;
640 }
641
642 acb->ioh->driver_status = 0;
643 acb->ioh->host_status = 0;
644 acb->ioh->resid = 0;
645
646#define SG_ERR_DRIVER_SENSE 0x08
647
648 if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
649 int ss;
650
651 acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
652
653 acb->ioh->sb_len_wr = acb->task->datain.size - 2;
654 ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
655 acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
656 memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
657 }
658
cfb3f506 659 iscsi_schedule_bh(acb);
98392453
RS
660}
661
662static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
663 unsigned long int req, void *buf,
664 BlockDriverCompletionFunc *cb, void *opaque)
665{
666 IscsiLun *iscsilun = bs->opaque;
667 struct iscsi_context *iscsi = iscsilun->iscsi;
668 struct iscsi_data data;
669 IscsiAIOCB *acb;
670
671 assert(req == SG_IO);
672
d7331bed 673 acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
98392453
RS
674
675 acb->iscsilun = iscsilun;
676 acb->canceled = 0;
1bd075f2
PB
677 acb->bh = NULL;
678 acb->status = -EINPROGRESS;
98392453
RS
679 acb->buf = NULL;
680 acb->ioh = buf;
681
682 acb->task = malloc(sizeof(struct scsi_task));
683 if (acb->task == NULL) {
684 error_report("iSCSI: Failed to allocate task for scsi command. %s",
685 iscsi_get_error(iscsi));
686 qemu_aio_release(acb);
687 return NULL;
688 }
689 memset(acb->task, 0, sizeof(struct scsi_task));
690
691 switch (acb->ioh->dxfer_direction) {
692 case SG_DXFER_TO_DEV:
693 acb->task->xfer_dir = SCSI_XFER_WRITE;
694 break;
695 case SG_DXFER_FROM_DEV:
696 acb->task->xfer_dir = SCSI_XFER_READ;
697 break;
698 default:
699 acb->task->xfer_dir = SCSI_XFER_NONE;
700 break;
701 }
702
703 acb->task->cdb_size = acb->ioh->cmd_len;
704 memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
705 acb->task->expxferlen = acb->ioh->dxfer_len;
706
0a53f010 707 data.size = 0;
98392453 708 if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
0a53f010
RS
709 if (acb->ioh->iovec_count == 0) {
710 data.data = acb->ioh->dxferp;
711 data.size = acb->ioh->dxfer_len;
712 } else {
713#if defined(LIBISCSI_FEATURE_IOVECTOR)
714 scsi_task_set_iov_out(acb->task,
715 (struct scsi_iovec *) acb->ioh->dxferp,
716 acb->ioh->iovec_count);
717#else
718 struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
719
720 acb->buf = g_malloc(acb->ioh->dxfer_len);
721 data.data = acb->buf;
722 data.size = iov_to_buf(iov, acb->ioh->iovec_count, 0,
723 acb->buf, acb->ioh->dxfer_len);
724#endif
725 }
98392453 726 }
0a53f010 727
98392453
RS
728 if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
729 iscsi_aio_ioctl_cb,
0a53f010 730 (data.size > 0) ? &data : NULL,
98392453
RS
731 acb) != 0) {
732 scsi_free_scsi_task(acb->task);
733 qemu_aio_release(acb);
734 return NULL;
735 }
736
737 /* tell libiscsi to read straight into the buffer we got from ioctl */
738 if (acb->task->xfer_dir == SCSI_XFER_READ) {
0a53f010
RS
739 if (acb->ioh->iovec_count == 0) {
740 scsi_task_add_data_in_buffer(acb->task,
741 acb->ioh->dxfer_len,
742 acb->ioh->dxferp);
743 } else {
744#if defined(LIBISCSI_FEATURE_IOVECTOR)
745 scsi_task_set_iov_in(acb->task,
746 (struct scsi_iovec *) acb->ioh->dxferp,
747 acb->ioh->iovec_count);
748#else
749 int i;
750 for (i = 0; i < acb->ioh->iovec_count; i++) {
751 struct iovec *iov = (struct iovec *)acb->ioh->dxferp;
752
753 scsi_task_add_data_in_buffer(acb->task,
754 iov[i].iov_len,
755 iov[i].iov_base);
756 }
757#endif
758 }
98392453
RS
759 }
760
761 iscsi_set_events(iscsilun);
762
763 return &acb->common;
764}
765
f1a12821
RS
766
767static void ioctl_cb(void *opaque, int status)
768{
769 int *p_status = opaque;
770 *p_status = status;
771}
772
98392453
RS
773static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
774{
775 IscsiLun *iscsilun = bs->opaque;
f1a12821 776 int status;
98392453
RS
777
778 switch (req) {
779 case SG_GET_VERSION_NUM:
780 *(int *)buf = 30000;
781 break;
782 case SG_GET_SCSI_ID:
783 ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
784 break;
f1a12821
RS
785 case SG_IO:
786 status = -EINPROGRESS;
787 iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
788
789 while (status == -EINPROGRESS) {
790 qemu_aio_wait();
791 }
792
793 return 0;
98392453
RS
794 default:
795 return -1;
796 }
797 return 0;
798}
799#endif
800
c589b249
RS
801static int64_t
802iscsi_getlength(BlockDriverState *bs)
803{
804 IscsiLun *iscsilun = bs->opaque;
805 int64_t len;
806
807 len = iscsilun->num_blocks;
808 len *= iscsilun->block_size;
809
810 return len;
811}
812
24c7608a 813#if defined(LIBISCSI_FEATURE_IOVECTOR)
f35c934a 814
54a5c1d5
PL
815static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
816 int64_t sector_num,
817 int nb_sectors, int *pnum)
818{
819 IscsiLun *iscsilun = bs->opaque;
820 struct scsi_get_lba_status *lbas = NULL;
821 struct scsi_lba_status_descriptor *lbasd = NULL;
822 struct IscsiTask iTask;
823 int64_t ret;
824
825 iscsi_co_init_iscsitask(iscsilun, &iTask);
826
827 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
828 ret = -EINVAL;
829 goto out;
830 }
831
832 /* default to all sectors allocated */
833 ret = BDRV_BLOCK_DATA;
834 ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
835 *pnum = nb_sectors;
836
837 /* LUN does not support logical block provisioning */
838 if (iscsilun->lbpme == 0) {
839 goto out;
840 }
841
842retry:
843 if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
844 sector_qemu2lun(sector_num, iscsilun),
845 8 + 16, iscsi_co_generic_cb,
846 &iTask) == NULL) {
847 ret = -EIO;
848 goto out;
849 }
850
851 while (!iTask.complete) {
852 iscsi_set_events(iscsilun);
853 qemu_coroutine_yield();
854 }
855
856 if (iTask.do_retry) {
857 if (iTask.task != NULL) {
858 scsi_free_scsi_task(iTask.task);
859 iTask.task = NULL;
860 }
861 goto retry;
862 }
863
864 if (iTask.status != SCSI_STATUS_GOOD) {
865 /* in case the get_lba_status_callout fails (i.e.
866 * because the device is busy or the cmd is not
867 * supported) we pretend all blocks are allocated
73f395fa 868 * for backwards compatibility */
54a5c1d5
PL
869 goto out;
870 }
871
872 lbas = scsi_datain_unmarshall(iTask.task);
873 if (lbas == NULL) {
874 ret = -EIO;
875 goto out;
876 }
877
878 lbasd = &lbas->descriptors[0];
879
880 if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
881 ret = -EIO;
882 goto out;
883 }
884
885 *pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
886 if (*pnum > nb_sectors) {
887 *pnum = nb_sectors;
888 }
889
890 if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
891 lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
892 ret &= ~BDRV_BLOCK_DATA;
893 if (iscsilun->lbprz) {
894 ret |= BDRV_BLOCK_ZERO;
895 }
896 }
897
898out:
899 if (iTask.task != NULL) {
900 scsi_free_scsi_task(iTask.task);
901 }
902 return ret;
903}
904
24c7608a 905#endif /* LIBISCSI_FEATURE_IOVECTOR */
f35c934a 906
65f3e339
PL
907static int
908coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num,
909 int nb_sectors)
910{
911 IscsiLun *iscsilun = bs->opaque;
912 struct IscsiTask iTask;
913 struct unmap_list list;
65f3e339
PL
914
915 if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
916 return -EINVAL;
917 }
918
919 if (!iscsilun->lbp.lbpu) {
920 /* UNMAP is not supported by the target */
921 return 0;
922 }
923
924 list.lba = sector_qemu2lun(sector_num, iscsilun);
01a6a238 925 list.num = sector_qemu2lun(nb_sectors, iscsilun);
65f3e339 926
01a6a238 927 iscsi_co_init_iscsitask(iscsilun, &iTask);
65f3e339 928retry:
01a6a238
PL
929 if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1,
930 iscsi_co_generic_cb, &iTask) == NULL) {
931 return -EIO;
932 }
65f3e339 933
01a6a238
PL
934 while (!iTask.complete) {
935 iscsi_set_events(iscsilun);
936 qemu_coroutine_yield();
937 }
65f3e339 938
01a6a238
PL
939 if (iTask.task != NULL) {
940 scsi_free_scsi_task(iTask.task);
941 iTask.task = NULL;
942 }
65f3e339 943
01a6a238
PL
944 if (iTask.do_retry) {
945 goto retry;
946 }
65f3e339 947
01a6a238
PL
948 if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {
949 /* the target might fail with a check condition if it
950 is not happy with the alignment of the UNMAP request
951 we silently fail in this case */
952 return 0;
953 }
65f3e339 954
01a6a238
PL
955 if (iTask.status != SCSI_STATUS_GOOD) {
956 return -EIO;
65f3e339
PL
957 }
958
959 return 0;
960}
961
f9dadc98
RS
962static int parse_chap(struct iscsi_context *iscsi, const char *target)
963{
964 QemuOptsList *list;
965 QemuOpts *opts;
966 const char *user = NULL;
967 const char *password = NULL;
968
969 list = qemu_find_opts("iscsi");
970 if (!list) {
971 return 0;
972 }
973
974 opts = qemu_opts_find(list, target);
975 if (opts == NULL) {
976 opts = QTAILQ_FIRST(&list->head);
977 if (!opts) {
978 return 0;
979 }
980 }
981
982 user = qemu_opt_get(opts, "user");
983 if (!user) {
984 return 0;
985 }
986
987 password = qemu_opt_get(opts, "password");
988 if (!password) {
989 error_report("CHAP username specified but no password was given");
990 return -1;
991 }
992
993 if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
994 error_report("Failed to set initiator username and password");
995 return -1;
996 }
997
998 return 0;
999}
1000
1001static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
1002{
1003 QemuOptsList *list;
1004 QemuOpts *opts;
1005 const char *digest = NULL;
1006
1007 list = qemu_find_opts("iscsi");
1008 if (!list) {
1009 return;
1010 }
1011
1012 opts = qemu_opts_find(list, target);
1013 if (opts == NULL) {
1014 opts = QTAILQ_FIRST(&list->head);
1015 if (!opts) {
1016 return;
1017 }
1018 }
1019
1020 digest = qemu_opt_get(opts, "header-digest");
1021 if (!digest) {
1022 return;
1023 }
1024
1025 if (!strcmp(digest, "CRC32C")) {
1026 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
1027 } else if (!strcmp(digest, "NONE")) {
1028 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
1029 } else if (!strcmp(digest, "CRC32C-NONE")) {
1030 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
1031 } else if (!strcmp(digest, "NONE-CRC32C")) {
1032 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
1033 } else {
1034 error_report("Invalid header-digest setting : %s", digest);
1035 }
1036}
1037
1038static char *parse_initiator_name(const char *target)
1039{
1040 QemuOptsList *list;
1041 QemuOpts *opts;
5accc840
PB
1042 const char *name;
1043 char *iscsi_name;
1044 UuidInfo *uuid_info;
f9dadc98
RS
1045
1046 list = qemu_find_opts("iscsi");
f2ef4a6d
PB
1047 if (list) {
1048 opts = qemu_opts_find(list, target);
f9dadc98 1049 if (!opts) {
f2ef4a6d
PB
1050 opts = QTAILQ_FIRST(&list->head);
1051 }
1052 if (opts) {
1053 name = qemu_opt_get(opts, "initiator-name");
5accc840
PB
1054 if (name) {
1055 return g_strdup(name);
1056 }
f9dadc98
RS
1057 }
1058 }
1059
5accc840
PB
1060 uuid_info = qmp_query_uuid(NULL);
1061 if (strcmp(uuid_info->UUID, UUID_NONE) == 0) {
1062 name = qemu_get_vm_name();
f2ef4a6d 1063 } else {
5accc840 1064 name = uuid_info->UUID;
f9dadc98 1065 }
5accc840
PB
1066 iscsi_name = g_strdup_printf("iqn.2008-11.org.linux-kvm%s%s",
1067 name ? ":" : "", name ? name : "");
1068 qapi_free_UuidInfo(uuid_info);
1069 return iscsi_name;
f9dadc98
RS
1070}
1071
5b5d34ec
PL
1072#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
1073static void iscsi_nop_timed_event(void *opaque)
1074{
1075 IscsiLun *iscsilun = opaque;
1076
1077 if (iscsi_get_nops_in_flight(iscsilun->iscsi) > MAX_NOP_FAILURES) {
1078 error_report("iSCSI: NOP timeout. Reconnecting...");
1079 iscsi_reconnect(iscsilun->iscsi);
1080 }
1081
1082 if (iscsi_nop_out_async(iscsilun->iscsi, NULL, NULL, 0, NULL) != 0) {
1083 error_report("iSCSI: failed to sent NOP-Out. Disabling NOP messages.");
1084 return;
1085 }
1086
bc72ad67 1087 timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
5b5d34ec
PL
1088 iscsi_set_events(iscsilun);
1089}
1090#endif
1091
cb1b83e7
PL
1092static int iscsi_readcapacity_sync(IscsiLun *iscsilun)
1093{
1094 struct scsi_task *task = NULL;
1095 struct scsi_readcapacity10 *rc10 = NULL;
1096 struct scsi_readcapacity16 *rc16 = NULL;
1097 int ret = 0;
1098 int retries = ISCSI_CMD_RETRIES;
1099
1288844e
PB
1100 do {
1101 if (task != NULL) {
1102 scsi_free_scsi_task(task);
1103 task = NULL;
cb1b83e7 1104 }
1288844e
PB
1105
1106 switch (iscsilun->type) {
1107 case TYPE_DISK:
1108 task = iscsi_readcapacity16_sync(iscsilun->iscsi, iscsilun->lun);
1109 if (task != NULL && task->status == SCSI_STATUS_GOOD) {
1110 rc16 = scsi_datain_unmarshall(task);
1111 if (rc16 == NULL) {
1112 error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
1113 ret = -EINVAL;
1114 } else {
1115 iscsilun->block_size = rc16->block_length;
1116 iscsilun->num_blocks = rc16->returned_lba + 1;
f18a7cbb
PL
1117 iscsilun->lbpme = rc16->lbpme;
1118 iscsilun->lbprz = rc16->lbprz;
1288844e
PB
1119 }
1120 }
1121 break;
1122 case TYPE_ROM:
1123 task = iscsi_readcapacity10_sync(iscsilun->iscsi, iscsilun->lun, 0, 0);
1124 if (task != NULL && task->status == SCSI_STATUS_GOOD) {
1125 rc10 = scsi_datain_unmarshall(task);
1126 if (rc10 == NULL) {
1127 error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
1128 ret = -EINVAL;
1129 } else {
1130 iscsilun->block_size = rc10->block_size;
1131 if (rc10->lba == 0) {
1132 /* blank disk loaded */
1133 iscsilun->num_blocks = 0;
1134 } else {
1135 iscsilun->num_blocks = rc10->lba + 1;
1136 }
1137 }
1138 }
1139 break;
1140 default:
1141 return 0;
cb1b83e7 1142 }
1288844e
PB
1143 } while (task != NULL && task->status == SCSI_STATUS_CHECK_CONDITION
1144 && task->sense.key == SCSI_SENSE_UNIT_ATTENTION
1145 && retries-- > 0);
cb1b83e7 1146
1288844e
PB
1147 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1148 error_report("iSCSI: failed to send readcapacity10 command.");
1149 ret = -EINVAL;
1150 }
cb1b83e7
PL
1151 if (task) {
1152 scsi_free_scsi_task(task);
1153 }
cb1b83e7
PL
1154 return ret;
1155}
1156
60beb341
KW
1157/* TODO Convert to fine grained options */
1158static QemuOptsList runtime_opts = {
1159 .name = "iscsi",
1160 .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
1161 .desc = {
1162 {
1163 .name = "filename",
1164 .type = QEMU_OPT_STRING,
1165 .help = "URL to the iscsi image",
1166 },
1167 { /* end of list */ }
1168 },
1169};
1170
f18a7cbb
PL
1171static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi,
1172 int lun, int evpd, int pc) {
1173 int full_size;
1174 struct scsi_task *task = NULL;
1175 task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64);
1176 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1177 goto fail;
1178 }
1179 full_size = scsi_datain_getfullsize(task);
1180 if (full_size > task->datain.size) {
1181 scsi_free_scsi_task(task);
1182
1183 /* we need more data for the full list */
1184 task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size);
1185 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1186 goto fail;
1187 }
1188 }
1189
1190 return task;
1191
1192fail:
1193 error_report("iSCSI: Inquiry command failed : %s",
1194 iscsi_get_error(iscsi));
1195 if (task) {
1196 scsi_free_scsi_task(task);
1197 return NULL;
1198 }
1199 return NULL;
1200}
1201
c589b249
RS
1202/*
1203 * We support iscsi url's on the form
1204 * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
1205 */
015a1036
HR
1206static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
1207 Error **errp)
c589b249
RS
1208{
1209 IscsiLun *iscsilun = bs->opaque;
1210 struct iscsi_context *iscsi = NULL;
1211 struct iscsi_url *iscsi_url = NULL;
e829b0bb
PL
1212 struct scsi_task *task = NULL;
1213 struct scsi_inquiry_standard *inq = NULL;
f9dadc98 1214 char *initiator_name = NULL;
60beb341
KW
1215 QemuOpts *opts;
1216 Error *local_err = NULL;
1217 const char *filename;
c589b249
RS
1218 int ret;
1219
1220 if ((BDRV_SECTOR_SIZE % 512) != 0) {
1221 error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
1222 "BDRV_SECTOR_SIZE(%lld) is not a multiple "
1223 "of 512", BDRV_SECTOR_SIZE);
1224 return -EINVAL;
1225 }
1226
60beb341
KW
1227 opts = qemu_opts_create_nofail(&runtime_opts);
1228 qemu_opts_absorb_qdict(opts, options, &local_err);
1229 if (error_is_set(&local_err)) {
1230 qerror_report_err(local_err);
1231 error_free(local_err);
1232 ret = -EINVAL;
1233 goto out;
1234 }
1235
1236 filename = qemu_opt_get(opts, "filename");
1237
1238
c589b249
RS
1239 iscsi_url = iscsi_parse_full_url(iscsi, filename);
1240 if (iscsi_url == NULL) {
8da1e18b 1241 error_report("Failed to parse URL : %s", filename);
c589b249 1242 ret = -EINVAL;
b93c94f7 1243 goto out;
c589b249
RS
1244 }
1245
f9dadc98
RS
1246 memset(iscsilun, 0, sizeof(IscsiLun));
1247
1248 initiator_name = parse_initiator_name(iscsi_url->target);
1249
1250 iscsi = iscsi_create_context(initiator_name);
1251 if (iscsi == NULL) {
1252 error_report("iSCSI: Failed to create iSCSI context.");
1253 ret = -ENOMEM;
b93c94f7 1254 goto out;
f9dadc98
RS
1255 }
1256
c589b249
RS
1257 if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
1258 error_report("iSCSI: Failed to set target name.");
1259 ret = -EINVAL;
b93c94f7 1260 goto out;
c589b249
RS
1261 }
1262
1263 if (iscsi_url->user != NULL) {
1264 ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
1265 iscsi_url->passwd);
1266 if (ret != 0) {
1267 error_report("Failed to set initiator username and password");
1268 ret = -EINVAL;
b93c94f7 1269 goto out;
c589b249
RS
1270 }
1271 }
f9dadc98
RS
1272
1273 /* check if we got CHAP username/password via the options */
1274 if (parse_chap(iscsi, iscsi_url->target) != 0) {
1275 error_report("iSCSI: Failed to set CHAP user/password");
1276 ret = -EINVAL;
b93c94f7 1277 goto out;
f9dadc98
RS
1278 }
1279
c589b249
RS
1280 if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
1281 error_report("iSCSI: Failed to set session type to normal.");
1282 ret = -EINVAL;
b93c94f7 1283 goto out;
c589b249
RS
1284 }
1285
1286 iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
1287
f9dadc98
RS
1288 /* check if we got HEADER_DIGEST via the options */
1289 parse_header_digest(iscsi, iscsi_url->target);
1290
e829b0bb
PL
1291 if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
1292 error_report("iSCSI: Failed to connect to LUN : %s",
1293 iscsi_get_error(iscsi));
1294 ret = -EINVAL;
1295 goto out;
1296 }
c589b249
RS
1297
1298 iscsilun->iscsi = iscsi;
1299 iscsilun->lun = iscsi_url->lun;
1300
e829b0bb
PL
1301 task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
1302
1303 if (task == NULL || task->status != SCSI_STATUS_GOOD) {
1304 error_report("iSCSI: failed to send inquiry command.");
c589b249 1305 ret = -EINVAL;
b93c94f7 1306 goto out;
c589b249
RS
1307 }
1308
e829b0bb
PL
1309 inq = scsi_datain_unmarshall(task);
1310 if (inq == NULL) {
1311 error_report("iSCSI: Failed to unmarshall inquiry data.");
c589b249 1312 ret = -EINVAL;
b93c94f7 1313 goto out;
c589b249 1314 }
622695a4 1315
e829b0bb
PL
1316 iscsilun->type = inq->periperal_device_type;
1317
cb1b83e7
PL
1318 if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
1319 goto out;
e829b0bb 1320 }
0777b5dd 1321 bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
e829b0bb 1322
622695a4
RS
1323 /* Medium changer or tape. We dont have any emulation for this so this must
1324 * be sg ioctl compatible. We force it to be sg, otherwise qemu will try
1325 * to read from the device to guess the image format.
1326 */
1327 if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
1328 iscsilun->type == TYPE_TAPE) {
1329 bs->sg = 1;
1330 }
1331
f18a7cbb
PL
1332 if (iscsilun->lbpme) {
1333 struct scsi_inquiry_logical_block_provisioning *inq_lbp;
1334 task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1335 SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING);
1336 if (task == NULL) {
1337 ret = -EINVAL;
1338 goto out;
1339 }
1340 inq_lbp = scsi_datain_unmarshall(task);
1341 if (inq_lbp == NULL) {
1342 error_report("iSCSI: failed to unmarshall inquiry datain blob");
1343 ret = -EINVAL;
1344 goto out;
1345 }
1346 memcpy(&iscsilun->lbp, inq_lbp,
1347 sizeof(struct scsi_inquiry_logical_block_provisioning));
1348 scsi_free_scsi_task(task);
1349 task = NULL;
1350 }
1351
1352 if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
1353 struct scsi_inquiry_block_limits *inq_bl;
1354 task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
1355 SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS);
1356 if (task == NULL) {
1357 ret = -EINVAL;
1358 goto out;
1359 }
1360 inq_bl = scsi_datain_unmarshall(task);
1361 if (inq_bl == NULL) {
1362 error_report("iSCSI: failed to unmarshall inquiry datain blob");
1363 ret = -EINVAL;
1364 goto out;
1365 }
1366 memcpy(&iscsilun->bl, inq_bl,
1367 sizeof(struct scsi_inquiry_block_limits));
1368 scsi_free_scsi_task(task);
1369 task = NULL;
ba6c5919
PL
1370
1371 if (iscsilun->bl.max_unmap < 0xffffffff) {
1372 bs->bl.max_discard = sector_lun2qemu(iscsilun->bl.max_unmap,
1373 iscsilun);
1374 }
1375 bs->bl.discard_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,
1376 iscsilun);
1377
1378 if (iscsilun->bl.max_ws_len < 0xffffffff) {
1379 bs->bl.max_write_zeroes = sector_lun2qemu(iscsilun->bl.max_ws_len,
1380 iscsilun);
1381 }
1382 bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,
1383 iscsilun);
f18a7cbb
PL
1384 }
1385
5b5d34ec
PL
1386#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
1387 /* Set up a timer for sending out iSCSI NOPs */
bc72ad67
AB
1388 iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
1389 timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
5b5d34ec
PL
1390#endif
1391
b93c94f7 1392out:
60beb341 1393 qemu_opts_del(opts);
f9dadc98
RS
1394 if (initiator_name != NULL) {
1395 g_free(initiator_name);
1396 }
c589b249
RS
1397 if (iscsi_url != NULL) {
1398 iscsi_destroy_url(iscsi_url);
1399 }
e829b0bb
PL
1400 if (task != NULL) {
1401 scsi_free_scsi_task(task);
1402 }
b93c94f7
PB
1403
1404 if (ret) {
1405 if (iscsi != NULL) {
1406 iscsi_destroy_context(iscsi);
1407 }
1408 memset(iscsilun, 0, sizeof(IscsiLun));
c589b249 1409 }
c589b249
RS
1410 return ret;
1411}
1412
1413static void iscsi_close(BlockDriverState *bs)
1414{
1415 IscsiLun *iscsilun = bs->opaque;
1416 struct iscsi_context *iscsi = iscsilun->iscsi;
1417
5b5d34ec 1418 if (iscsilun->nop_timer) {
bc72ad67
AB
1419 timer_del(iscsilun->nop_timer);
1420 timer_free(iscsilun->nop_timer);
5b5d34ec 1421 }
f2e5dca4 1422 qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
c589b249
RS
1423 iscsi_destroy_context(iscsi);
1424 memset(iscsilun, 0, sizeof(IscsiLun));
1425}
1426
cb1b83e7
PL
1427static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
1428{
1429 IscsiLun *iscsilun = bs->opaque;
1430 int ret = 0;
1431
1432 if (iscsilun->type != TYPE_DISK) {
1433 return -ENOTSUP;
1434 }
1435
1436 if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) {
1437 return ret;
1438 }
1439
1440 if (offset > iscsi_getlength(bs)) {
1441 return -EINVAL;
1442 }
1443
1444 return 0;
1445}
1446
f807ecd5
PL
1447static int iscsi_has_zero_init(BlockDriverState *bs)
1448{
1449 return 0;
1450}
1451
d5124c00
HR
1452static int iscsi_create(const char *filename, QEMUOptionParameter *options,
1453 Error **errp)
de8864e5
PL
1454{
1455 int ret = 0;
1456 int64_t total_size = 0;
13c91cb7 1457 BlockDriverState *bs;
de8864e5 1458 IscsiLun *iscsilun = NULL;
60beb341 1459 QDict *bs_options;
de8864e5 1460
13c91cb7 1461 bs = bdrv_new("");
de8864e5
PL
1462
1463 /* Read out options */
1464 while (options && options->name) {
1465 if (!strcmp(options->name, "size")) {
1466 total_size = options->value.n / BDRV_SECTOR_SIZE;
1467 }
1468 options++;
1469 }
1470
13c91cb7
FZ
1471 bs->opaque = g_malloc0(sizeof(struct IscsiLun));
1472 iscsilun = bs->opaque;
de8864e5 1473
60beb341
KW
1474 bs_options = qdict_new();
1475 qdict_put(bs_options, "filename", qstring_from_str(filename));
015a1036 1476 ret = iscsi_open(bs, bs_options, 0, NULL);
60beb341
KW
1477 QDECREF(bs_options);
1478
de8864e5
PL
1479 if (ret != 0) {
1480 goto out;
1481 }
5b5d34ec 1482 if (iscsilun->nop_timer) {
bc72ad67
AB
1483 timer_del(iscsilun->nop_timer);
1484 timer_free(iscsilun->nop_timer);
5b5d34ec 1485 }
de8864e5
PL
1486 if (iscsilun->type != TYPE_DISK) {
1487 ret = -ENODEV;
1488 goto out;
1489 }
13c91cb7 1490 if (bs->total_sectors < total_size) {
de8864e5 1491 ret = -ENOSPC;
d3bda7bc 1492 goto out;
de8864e5
PL
1493 }
1494
1495 ret = 0;
1496out:
1497 if (iscsilun->iscsi != NULL) {
1498 iscsi_destroy_context(iscsilun->iscsi);
1499 }
13c91cb7
FZ
1500 g_free(bs->opaque);
1501 bs->opaque = NULL;
4f6fd349 1502 bdrv_unref(bs);
de8864e5
PL
1503 return ret;
1504}
1505
186d4f2b
PL
1506static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1507{
1508 IscsiLun *iscsilun = bs->opaque;
1509 bdi->unallocated_blocks_are_zero = !!iscsilun->lbprz;
1510 bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws;
1511 return 0;
1512}
1513
de8864e5
PL
1514static QEMUOptionParameter iscsi_create_options[] = {
1515 {
1516 .name = BLOCK_OPT_SIZE,
1517 .type = OPT_SIZE,
1518 .help = "Virtual disk size"
1519 },
1520 { NULL }
1521};
1522
c589b249
RS
1523static BlockDriver bdrv_iscsi = {
1524 .format_name = "iscsi",
1525 .protocol_name = "iscsi",
1526
1527 .instance_size = sizeof(IscsiLun),
030be321 1528 .bdrv_needs_filename = true,
c589b249
RS
1529 .bdrv_file_open = iscsi_open,
1530 .bdrv_close = iscsi_close,
de8864e5
PL
1531 .bdrv_create = iscsi_create,
1532 .create_options = iscsi_create_options,
c589b249
RS
1533
1534 .bdrv_getlength = iscsi_getlength,
186d4f2b 1535 .bdrv_get_info = iscsi_get_info,
cb1b83e7 1536 .bdrv_truncate = iscsi_truncate,
c589b249 1537
24c7608a 1538#if defined(LIBISCSI_FEATURE_IOVECTOR)
54a5c1d5 1539 .bdrv_co_get_block_status = iscsi_co_get_block_status,
f35c934a 1540#endif
65f3e339 1541 .bdrv_co_discard = iscsi_co_discard,
54a5c1d5 1542
c589b249
RS
1543 .bdrv_aio_readv = iscsi_aio_readv,
1544 .bdrv_aio_writev = iscsi_aio_writev,
1545 .bdrv_aio_flush = iscsi_aio_flush,
fa6acb0c 1546
f807ecd5 1547 .bdrv_has_zero_init = iscsi_has_zero_init,
98392453
RS
1548
1549#ifdef __linux__
1550 .bdrv_ioctl = iscsi_ioctl,
1551 .bdrv_aio_ioctl = iscsi_aio_ioctl,
1552#endif
c589b249
RS
1553};
1554
4d454574
PB
1555static QemuOptsList qemu_iscsi_opts = {
1556 .name = "iscsi",
1557 .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head),
1558 .desc = {
1559 {
1560 .name = "user",
1561 .type = QEMU_OPT_STRING,
1562 .help = "username for CHAP authentication to target",
1563 },{
1564 .name = "password",
1565 .type = QEMU_OPT_STRING,
1566 .help = "password for CHAP authentication to target",
1567 },{
1568 .name = "header-digest",
1569 .type = QEMU_OPT_STRING,
1570 .help = "HeaderDigest setting. "
1571 "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
1572 },{
1573 .name = "initiator-name",
1574 .type = QEMU_OPT_STRING,
1575 .help = "Initiator iqn name to use when connecting",
1576 },
1577 { /* end of list */ }
1578 },
1579};
1580
c589b249
RS
1581static void iscsi_block_init(void)
1582{
1583 bdrv_register(&bdrv_iscsi);
4d454574 1584 qemu_add_opts(&qemu_iscsi_opts);
c589b249
RS
1585}
1586
1587block_init(iscsi_block_init);