xref: /openbmc/qemu/block/iscsi.c (revision c73e3771ea79ab3898da3ba51ff6fc5b05948d85)
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>
28 #include <arpa/inet.h>
29 #include "qemu-common.h"
30 #include "qemu-error.h"
31 #include "block_int.h"
32 #include "trace.h"
33 #include "hw/scsi-defs.h"
34 
35 #include <iscsi/iscsi.h>
36 #include <iscsi/scsi-lowlevel.h>
37 
38 
39 typedef struct IscsiLun {
40     struct iscsi_context *iscsi;
41     int lun;
42     enum scsi_inquiry_peripheral_device_type type;
43     int block_size;
44     uint64_t num_blocks;
45     int events;
46 } IscsiLun;
47 
48 typedef struct IscsiAIOCB {
49     BlockDriverAIOCB common;
50     QEMUIOVector *qiov;
51     QEMUBH *bh;
52     IscsiLun *iscsilun;
53     struct scsi_task *task;
54     uint8_t *buf;
55     int status;
56     int canceled;
57     size_t read_size;
58     size_t read_offset;
59 } IscsiAIOCB;
60 
61 struct IscsiTask {
62     IscsiLun *iscsilun;
63     BlockDriverState *bs;
64     int status;
65     int complete;
66 };
67 
68 static void
69 iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
70                     void *private_data)
71 {
72 }
73 
74 static void
75 iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
76 {
77     IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
78     IscsiLun *iscsilun = acb->iscsilun;
79 
80     acb->common.cb(acb->common.opaque, -ECANCELED);
81     acb->canceled = 1;
82 
83     /* send a task mgmt call to the target to cancel the task on the target */
84     iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
85                                      iscsi_abort_task_cb, NULL);
86 
87     /* then also cancel the task locally in libiscsi */
88     iscsi_scsi_task_cancel(iscsilun->iscsi, acb->task);
89 }
90 
91 static AIOPool iscsi_aio_pool = {
92     .aiocb_size         = sizeof(IscsiAIOCB),
93     .cancel             = iscsi_aio_cancel,
94 };
95 
96 
97 static void iscsi_process_read(void *arg);
98 static void iscsi_process_write(void *arg);
99 
100 static int iscsi_process_flush(void *arg)
101 {
102     IscsiLun *iscsilun = arg;
103 
104     return iscsi_queue_length(iscsilun->iscsi) > 0;
105 }
106 
107 static void
108 iscsi_set_events(IscsiLun *iscsilun)
109 {
110     struct iscsi_context *iscsi = iscsilun->iscsi;
111     int ev;
112 
113     /* We always register a read handler.  */
114     ev = POLLIN;
115     ev |= iscsi_which_events(iscsi);
116     if (ev != iscsilun->events) {
117         qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
118                       iscsi_process_read,
119                       (ev & POLLOUT) ? iscsi_process_write : NULL,
120                       iscsi_process_flush,
121                       iscsilun);
122 
123     }
124 
125     /* If we just added an event, the callback might be delayed
126      * unless we call qemu_notify_event().
127      */
128     if (ev & ~iscsilun->events) {
129         qemu_notify_event();
130     }
131     iscsilun->events = ev;
132 }
133 
134 static void
135 iscsi_process_read(void *arg)
136 {
137     IscsiLun *iscsilun = arg;
138     struct iscsi_context *iscsi = iscsilun->iscsi;
139 
140     iscsi_service(iscsi, POLLIN);
141     iscsi_set_events(iscsilun);
142 }
143 
144 static void
145 iscsi_process_write(void *arg)
146 {
147     IscsiLun *iscsilun = arg;
148     struct iscsi_context *iscsi = iscsilun->iscsi;
149 
150     iscsi_service(iscsi, POLLOUT);
151     iscsi_set_events(iscsilun);
152 }
153 
154 
155 static int
156 iscsi_schedule_bh(QEMUBHFunc *cb, IscsiAIOCB *acb)
157 {
158     acb->bh = qemu_bh_new(cb, acb);
159     if (!acb->bh) {
160         error_report("oom: could not create iscsi bh");
161         return -EIO;
162     }
163 
164     qemu_bh_schedule(acb->bh);
165     return 0;
166 }
167 
168 static void
169 iscsi_readv_writev_bh_cb(void *p)
170 {
171     IscsiAIOCB *acb = p;
172 
173     qemu_bh_delete(acb->bh);
174 
175     if (acb->canceled == 0) {
176         acb->common.cb(acb->common.opaque, acb->status);
177     }
178 
179     qemu_aio_release(acb);
180 }
181 
182 
183 static void
184 iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
185                      void *command_data, void *opaque)
186 {
187     IscsiAIOCB *acb = opaque;
188 
189     trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled);
190 
191     g_free(acb->buf);
192 
193     if (acb->canceled != 0) {
194         qemu_aio_release(acb);
195         scsi_free_scsi_task(acb->task);
196         acb->task = NULL;
197         return;
198     }
199 
200     acb->status = 0;
201     if (status < 0) {
202         error_report("Failed to write16 data to iSCSI lun. %s",
203                      iscsi_get_error(iscsi));
204         acb->status = -EIO;
205     }
206 
207     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
208     scsi_free_scsi_task(acb->task);
209     acb->task = NULL;
210 }
211 
212 static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
213 {
214     return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
215 }
216 
217 static BlockDriverAIOCB *
218 iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
219                  QEMUIOVector *qiov, int nb_sectors,
220                  BlockDriverCompletionFunc *cb,
221                  void *opaque)
222 {
223     IscsiLun *iscsilun = bs->opaque;
224     struct iscsi_context *iscsi = iscsilun->iscsi;
225     IscsiAIOCB *acb;
226     size_t size;
227     uint32_t num_sectors;
228     uint64_t lba;
229     struct iscsi_data data;
230 
231     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
232     trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);
233 
234     acb->iscsilun = iscsilun;
235     acb->qiov     = qiov;
236 
237     acb->canceled   = 0;
238 
239     /* XXX we should pass the iovec to write16 to avoid the extra copy */
240     /* this will allow us to get rid of 'buf' completely */
241     size = nb_sectors * BDRV_SECTOR_SIZE;
242     acb->buf = g_malloc(size);
243     qemu_iovec_to_buffer(acb->qiov, acb->buf);
244 
245 
246     acb->task = malloc(sizeof(struct scsi_task));
247     if (acb->task == NULL) {
248         error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
249                      "command. %s", iscsi_get_error(iscsi));
250         qemu_aio_release(acb);
251         return NULL;
252     }
253     memset(acb->task, 0, sizeof(struct scsi_task));
254 
255     acb->task->xfer_dir = SCSI_XFER_WRITE;
256     acb->task->cdb_size = 16;
257     acb->task->cdb[0] = 0x8a;
258     if (!(bs->open_flags & BDRV_O_CACHE_WB)) {
259         /* set FUA on writes when cache mode is write through */
260         acb->task->cdb[1] |= 0x04;
261     }
262     lba = sector_qemu2lun(sector_num, iscsilun);
263     *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
264     *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
265     num_sectors = size / iscsilun->block_size;
266     *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
267     acb->task->expxferlen = size;
268 
269     data.data = acb->buf;
270     data.size = size;
271 
272     if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
273                                  iscsi_aio_write16_cb,
274                                  &data,
275                                  acb) != 0) {
276         scsi_free_scsi_task(acb->task);
277         g_free(acb->buf);
278         qemu_aio_release(acb);
279         return NULL;
280     }
281 
282     iscsi_set_events(iscsilun);
283 
284     return &acb->common;
285 }
286 
287 static void
288 iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
289                     void *command_data, void *opaque)
290 {
291     IscsiAIOCB *acb = opaque;
292 
293     trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
294 
295     if (acb->canceled != 0) {
296         qemu_aio_release(acb);
297         scsi_free_scsi_task(acb->task);
298         acb->task = NULL;
299         return;
300     }
301 
302     acb->status = 0;
303     if (status != 0) {
304         error_report("Failed to read16 data from iSCSI lun. %s",
305                      iscsi_get_error(iscsi));
306         acb->status = -EIO;
307     }
308 
309     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
310     scsi_free_scsi_task(acb->task);
311     acb->task = NULL;
312 }
313 
314 static BlockDriverAIOCB *
315 iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
316                 QEMUIOVector *qiov, int nb_sectors,
317                 BlockDriverCompletionFunc *cb,
318                 void *opaque)
319 {
320     IscsiLun *iscsilun = bs->opaque;
321     struct iscsi_context *iscsi = iscsilun->iscsi;
322     IscsiAIOCB *acb;
323     size_t qemu_read_size;
324     int i;
325     uint64_t lba;
326     uint32_t num_sectors;
327 
328     qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
329 
330     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
331     trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
332 
333     acb->iscsilun = iscsilun;
334     acb->qiov     = qiov;
335 
336     acb->canceled    = 0;
337     acb->read_size   = qemu_read_size;
338     acb->buf         = NULL;
339 
340     /* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU
341      * may be misaligned to the LUN, so we may need to read some extra
342      * data.
343      */
344     acb->read_offset = 0;
345     if (iscsilun->block_size > BDRV_SECTOR_SIZE) {
346         uint64_t bdrv_offset = BDRV_SECTOR_SIZE * sector_num;
347 
348         acb->read_offset  = bdrv_offset % iscsilun->block_size;
349     }
350 
351     num_sectors  = (qemu_read_size + iscsilun->block_size
352                     + acb->read_offset - 1)
353                     / iscsilun->block_size;
354 
355     acb->task = malloc(sizeof(struct scsi_task));
356     if (acb->task == NULL) {
357         error_report("iSCSI: Failed to allocate task for scsi READ16 "
358                      "command. %s", iscsi_get_error(iscsi));
359         qemu_aio_release(acb);
360         return NULL;
361     }
362     memset(acb->task, 0, sizeof(struct scsi_task));
363 
364     acb->task->xfer_dir = SCSI_XFER_READ;
365     lba = sector_qemu2lun(sector_num, iscsilun);
366     acb->task->expxferlen = qemu_read_size;
367 
368     switch (iscsilun->type) {
369     case TYPE_DISK:
370         acb->task->cdb_size = 16;
371         acb->task->cdb[0]  = 0x88;
372         *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
373         *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
374         *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
375         break;
376     default:
377         acb->task->cdb_size = 10;
378         acb->task->cdb[0]  = 0x28;
379         *(uint32_t *)&acb->task->cdb[2] = htonl(lba);
380         *(uint16_t *)&acb->task->cdb[7] = htons(num_sectors);
381         break;
382     }
383 
384     if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
385                                  iscsi_aio_read16_cb,
386                                  NULL,
387                                  acb) != 0) {
388         scsi_free_scsi_task(acb->task);
389         qemu_aio_release(acb);
390         return NULL;
391     }
392 
393     for (i = 0; i < acb->qiov->niov; i++) {
394         scsi_task_add_data_in_buffer(acb->task,
395                 acb->qiov->iov[i].iov_len,
396                 acb->qiov->iov[i].iov_base);
397     }
398 
399     iscsi_set_events(iscsilun);
400 
401     return &acb->common;
402 }
403 
404 
405 static void
406 iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
407                      void *command_data, void *opaque)
408 {
409     IscsiAIOCB *acb = opaque;
410 
411     if (acb->canceled != 0) {
412         qemu_aio_release(acb);
413         scsi_free_scsi_task(acb->task);
414         acb->task = NULL;
415         return;
416     }
417 
418     acb->status = 0;
419     if (status < 0) {
420         error_report("Failed to sync10 data on iSCSI lun. %s",
421                      iscsi_get_error(iscsi));
422         acb->status = -EIO;
423     }
424 
425     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
426     scsi_free_scsi_task(acb->task);
427     acb->task = NULL;
428 }
429 
430 static BlockDriverAIOCB *
431 iscsi_aio_flush(BlockDriverState *bs,
432                 BlockDriverCompletionFunc *cb, void *opaque)
433 {
434     IscsiLun *iscsilun = bs->opaque;
435     struct iscsi_context *iscsi = iscsilun->iscsi;
436     IscsiAIOCB *acb;
437 
438     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
439 
440     acb->iscsilun = iscsilun;
441     acb->canceled   = 0;
442 
443     acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
444                                          0, 0, 0, 0,
445                                          iscsi_synccache10_cb,
446                                          acb);
447     if (acb->task == NULL) {
448         error_report("iSCSI: Failed to send synchronizecache10 command. %s",
449                      iscsi_get_error(iscsi));
450         qemu_aio_release(acb);
451         return NULL;
452     }
453 
454     iscsi_set_events(iscsilun);
455 
456     return &acb->common;
457 }
458 
459 static void
460 iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
461                      void *command_data, void *opaque)
462 {
463     IscsiAIOCB *acb = opaque;
464 
465     if (acb->canceled != 0) {
466         qemu_aio_release(acb);
467         scsi_free_scsi_task(acb->task);
468         acb->task = NULL;
469         return;
470     }
471 
472     acb->status = 0;
473     if (status < 0) {
474         error_report("Failed to unmap data on iSCSI lun. %s",
475                      iscsi_get_error(iscsi));
476         acb->status = -EIO;
477     }
478 
479     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
480     scsi_free_scsi_task(acb->task);
481     acb->task = NULL;
482 }
483 
484 static BlockDriverAIOCB *
485 iscsi_aio_discard(BlockDriverState *bs,
486                   int64_t sector_num, int nb_sectors,
487                   BlockDriverCompletionFunc *cb, void *opaque)
488 {
489     IscsiLun *iscsilun = bs->opaque;
490     struct iscsi_context *iscsi = iscsilun->iscsi;
491     IscsiAIOCB *acb;
492     struct unmap_list list[1];
493 
494     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
495 
496     acb->iscsilun = iscsilun;
497     acb->canceled   = 0;
498 
499     list[0].lba = sector_qemu2lun(sector_num, iscsilun);
500     list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
501 
502     acb->task = iscsi_unmap_task(iscsi, iscsilun->lun,
503                                  0, 0, &list[0], 1,
504                                  iscsi_unmap_cb,
505                                  acb);
506     if (acb->task == NULL) {
507         error_report("iSCSI: Failed to send unmap command. %s",
508                      iscsi_get_error(iscsi));
509         qemu_aio_release(acb);
510         return NULL;
511     }
512 
513     iscsi_set_events(iscsilun);
514 
515     return &acb->common;
516 }
517 
518 static int64_t
519 iscsi_getlength(BlockDriverState *bs)
520 {
521     IscsiLun *iscsilun = bs->opaque;
522     int64_t len;
523 
524     len  = iscsilun->num_blocks;
525     len *= iscsilun->block_size;
526 
527     return len;
528 }
529 
530 static void
531 iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status,
532                         void *command_data, void *opaque)
533 {
534     struct IscsiTask *itask = opaque;
535     struct scsi_readcapacity16 *rc16;
536     struct scsi_task *task = command_data;
537 
538     if (status != 0) {
539         error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
540                      iscsi_get_error(iscsi));
541         itask->status   = 1;
542         itask->complete = 1;
543         scsi_free_scsi_task(task);
544         return;
545     }
546 
547     rc16 = scsi_datain_unmarshall(task);
548     if (rc16 == NULL) {
549         error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
550         itask->status   = 1;
551         itask->complete = 1;
552         scsi_free_scsi_task(task);
553         return;
554     }
555 
556     itask->iscsilun->block_size = rc16->block_length;
557     itask->iscsilun->num_blocks = rc16->returned_lba + 1;
558     itask->bs->total_sectors    = itask->iscsilun->num_blocks *
559                                itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
560 
561     itask->status   = 0;
562     itask->complete = 1;
563     scsi_free_scsi_task(task);
564 }
565 
566 static void
567 iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
568                         void *command_data, void *opaque)
569 {
570     struct IscsiTask *itask = opaque;
571     struct scsi_readcapacity10 *rc10;
572     struct scsi_task *task = command_data;
573 
574     if (status != 0) {
575         error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
576                      iscsi_get_error(iscsi));
577         itask->status   = 1;
578         itask->complete = 1;
579         scsi_free_scsi_task(task);
580         return;
581     }
582 
583     rc10 = scsi_datain_unmarshall(task);
584     if (rc10 == NULL) {
585         error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
586         itask->status   = 1;
587         itask->complete = 1;
588         scsi_free_scsi_task(task);
589         return;
590     }
591 
592     itask->iscsilun->block_size = rc10->block_size;
593     itask->iscsilun->num_blocks = rc10->lba + 1;
594     itask->bs->total_sectors    = itask->iscsilun->num_blocks *
595                                itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
596 
597     itask->status   = 0;
598     itask->complete = 1;
599     scsi_free_scsi_task(task);
600 }
601 
602 static void
603 iscsi_inquiry_cb(struct iscsi_context *iscsi, int status, void *command_data,
604                  void *opaque)
605 {
606     struct IscsiTask *itask = opaque;
607     struct scsi_task *task = command_data;
608     struct scsi_inquiry_standard *inq;
609 
610     if (status != 0) {
611         itask->status   = 1;
612         itask->complete = 1;
613         scsi_free_scsi_task(task);
614         return;
615     }
616 
617     inq = scsi_datain_unmarshall(task);
618     if (inq == NULL) {
619         error_report("iSCSI: Failed to unmarshall inquiry data.");
620         itask->status   = 1;
621         itask->complete = 1;
622         scsi_free_scsi_task(task);
623         return;
624     }
625 
626     itask->iscsilun->type = inq->periperal_device_type;
627 
628     scsi_free_scsi_task(task);
629 
630     switch (itask->iscsilun->type) {
631     case TYPE_DISK:
632         task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun,
633                                    iscsi_readcapacity16_cb, opaque);
634         if (task == NULL) {
635             error_report("iSCSI: failed to send readcapacity16 command.");
636             itask->status   = 1;
637             itask->complete = 1;
638             return;
639         }
640         break;
641     case TYPE_ROM:
642         task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun,
643                                    0, 0,
644                                    iscsi_readcapacity10_cb, opaque);
645         if (task == NULL) {
646             error_report("iSCSI: failed to send readcapacity16 command.");
647             itask->status   = 1;
648             itask->complete = 1;
649             return;
650         }
651         break;
652     default:
653         itask->status   = 0;
654         itask->complete = 1;
655     }
656 }
657 
658 static void
659 iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
660                  void *opaque)
661 {
662     struct IscsiTask *itask = opaque;
663     struct scsi_task *task;
664 
665     if (status != 0) {
666         itask->status   = 1;
667         itask->complete = 1;
668         return;
669     }
670 
671     task = iscsi_inquiry_task(iscsi, itask->iscsilun->lun,
672                               0, 0, 36,
673                               iscsi_inquiry_cb, opaque);
674     if (task == NULL) {
675         error_report("iSCSI: failed to send inquiry command.");
676         itask->status   = 1;
677         itask->complete = 1;
678         return;
679     }
680 }
681 
682 static int parse_chap(struct iscsi_context *iscsi, const char *target)
683 {
684     QemuOptsList *list;
685     QemuOpts *opts;
686     const char *user = NULL;
687     const char *password = NULL;
688 
689     list = qemu_find_opts("iscsi");
690     if (!list) {
691         return 0;
692     }
693 
694     opts = qemu_opts_find(list, target);
695     if (opts == NULL) {
696         opts = QTAILQ_FIRST(&list->head);
697         if (!opts) {
698             return 0;
699         }
700     }
701 
702     user = qemu_opt_get(opts, "user");
703     if (!user) {
704         return 0;
705     }
706 
707     password = qemu_opt_get(opts, "password");
708     if (!password) {
709         error_report("CHAP username specified but no password was given");
710         return -1;
711     }
712 
713     if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
714         error_report("Failed to set initiator username and password");
715         return -1;
716     }
717 
718     return 0;
719 }
720 
721 static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
722 {
723     QemuOptsList *list;
724     QemuOpts *opts;
725     const char *digest = NULL;
726 
727     list = qemu_find_opts("iscsi");
728     if (!list) {
729         return;
730     }
731 
732     opts = qemu_opts_find(list, target);
733     if (opts == NULL) {
734         opts = QTAILQ_FIRST(&list->head);
735         if (!opts) {
736             return;
737         }
738     }
739 
740     digest = qemu_opt_get(opts, "header-digest");
741     if (!digest) {
742         return;
743     }
744 
745     if (!strcmp(digest, "CRC32C")) {
746         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
747     } else if (!strcmp(digest, "NONE")) {
748         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
749     } else if (!strcmp(digest, "CRC32C-NONE")) {
750         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
751     } else if (!strcmp(digest, "NONE-CRC32C")) {
752         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
753     } else {
754         error_report("Invalid header-digest setting : %s", digest);
755     }
756 }
757 
758 static char *parse_initiator_name(const char *target)
759 {
760     QemuOptsList *list;
761     QemuOpts *opts;
762     const char *name = NULL;
763 
764     list = qemu_find_opts("iscsi");
765     if (!list) {
766         return g_strdup("iqn.2008-11.org.linux-kvm");
767     }
768 
769     opts = qemu_opts_find(list, target);
770     if (opts == NULL) {
771         opts = QTAILQ_FIRST(&list->head);
772         if (!opts) {
773             return g_strdup("iqn.2008-11.org.linux-kvm");
774         }
775     }
776 
777     name = qemu_opt_get(opts, "initiator-name");
778     if (!name) {
779         return g_strdup("iqn.2008-11.org.linux-kvm");
780     }
781 
782     return g_strdup(name);
783 }
784 
785 /*
786  * We support iscsi url's on the form
787  * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
788  */
789 static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
790 {
791     IscsiLun *iscsilun = bs->opaque;
792     struct iscsi_context *iscsi = NULL;
793     struct iscsi_url *iscsi_url = NULL;
794     struct IscsiTask task;
795     char *initiator_name = NULL;
796     int ret;
797 
798     if ((BDRV_SECTOR_SIZE % 512) != 0) {
799         error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
800                      "BDRV_SECTOR_SIZE(%lld) is not a multiple "
801                      "of 512", BDRV_SECTOR_SIZE);
802         return -EINVAL;
803     }
804 
805     iscsi_url = iscsi_parse_full_url(iscsi, filename);
806     if (iscsi_url == NULL) {
807         error_report("Failed to parse URL : %s %s", filename,
808                      iscsi_get_error(iscsi));
809         ret = -EINVAL;
810         goto failed;
811     }
812 
813     memset(iscsilun, 0, sizeof(IscsiLun));
814 
815     initiator_name = parse_initiator_name(iscsi_url->target);
816 
817     iscsi = iscsi_create_context(initiator_name);
818     if (iscsi == NULL) {
819         error_report("iSCSI: Failed to create iSCSI context.");
820         ret = -ENOMEM;
821         goto failed;
822     }
823 
824     if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
825         error_report("iSCSI: Failed to set target name.");
826         ret = -EINVAL;
827         goto failed;
828     }
829 
830     if (iscsi_url->user != NULL) {
831         ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
832                                               iscsi_url->passwd);
833         if (ret != 0) {
834             error_report("Failed to set initiator username and password");
835             ret = -EINVAL;
836             goto failed;
837         }
838     }
839 
840     /* check if we got CHAP username/password via the options */
841     if (parse_chap(iscsi, iscsi_url->target) != 0) {
842         error_report("iSCSI: Failed to set CHAP user/password");
843         ret = -EINVAL;
844         goto failed;
845     }
846 
847     if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
848         error_report("iSCSI: Failed to set session type to normal.");
849         ret = -EINVAL;
850         goto failed;
851     }
852 
853     iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
854 
855     /* check if we got HEADER_DIGEST via the options */
856     parse_header_digest(iscsi, iscsi_url->target);
857 
858     task.iscsilun = iscsilun;
859     task.status = 0;
860     task.complete = 0;
861     task.bs = bs;
862 
863     iscsilun->iscsi = iscsi;
864     iscsilun->lun   = iscsi_url->lun;
865 
866     if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,
867                                  iscsi_connect_cb, &task)
868         != 0) {
869         error_report("iSCSI: Failed to start async connect.");
870         ret = -EINVAL;
871         goto failed;
872     }
873 
874     while (!task.complete) {
875         iscsi_set_events(iscsilun);
876         qemu_aio_wait();
877     }
878     if (task.status != 0) {
879         error_report("iSCSI: Failed to connect to LUN : %s",
880                      iscsi_get_error(iscsi));
881         ret = -EINVAL;
882         goto failed;
883     }
884 
885     if (iscsi_url != NULL) {
886         iscsi_destroy_url(iscsi_url);
887     }
888     return 0;
889 
890 failed:
891     if (initiator_name != NULL) {
892         g_free(initiator_name);
893     }
894     if (iscsi_url != NULL) {
895         iscsi_destroy_url(iscsi_url);
896     }
897     if (iscsi != NULL) {
898         iscsi_destroy_context(iscsi);
899     }
900     memset(iscsilun, 0, sizeof(IscsiLun));
901     return ret;
902 }
903 
904 static void iscsi_close(BlockDriverState *bs)
905 {
906     IscsiLun *iscsilun = bs->opaque;
907     struct iscsi_context *iscsi = iscsilun->iscsi;
908 
909     qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
910     iscsi_destroy_context(iscsi);
911     memset(iscsilun, 0, sizeof(IscsiLun));
912 }
913 
914 static BlockDriver bdrv_iscsi = {
915     .format_name     = "iscsi",
916     .protocol_name   = "iscsi",
917 
918     .instance_size   = sizeof(IscsiLun),
919     .bdrv_file_open  = iscsi_open,
920     .bdrv_close      = iscsi_close,
921 
922     .bdrv_getlength  = iscsi_getlength,
923 
924     .bdrv_aio_readv  = iscsi_aio_readv,
925     .bdrv_aio_writev = iscsi_aio_writev,
926     .bdrv_aio_flush  = iscsi_aio_flush,
927 
928     .bdrv_aio_discard = iscsi_aio_discard,
929 };
930 
931 static void iscsi_block_init(void)
932 {
933     bdrv_register(&bdrv_iscsi);
934 }
935 
936 block_init(iscsi_block_init);
937