]> Git Repo - qemu.git/blob - block/iscsi.c
block: Support GlusterFS as a QEMU block backend.
[qemu.git] / block / iscsi.c
1 /*
2  * QEMU Block driver for iSCSI images
3  *
4  * Copyright (c) 2010-2011 Ronnie Sahlberg <[email protected]>
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 #ifdef __linux__
39 #include <scsi/sg.h>
40 #include <hw/scsi-defs.h>
41 #endif
42
43 typedef struct IscsiLun {
44     struct iscsi_context *iscsi;
45     int lun;
46     enum scsi_inquiry_peripheral_device_type type;
47     int block_size;
48     uint64_t num_blocks;
49     int events;
50 } IscsiLun;
51
52 typedef struct IscsiAIOCB {
53     BlockDriverAIOCB common;
54     QEMUIOVector *qiov;
55     QEMUBH *bh;
56     IscsiLun *iscsilun;
57     struct scsi_task *task;
58     uint8_t *buf;
59     int status;
60     int canceled;
61     size_t read_size;
62     size_t read_offset;
63 #ifdef __linux__
64     sg_io_hdr_t *ioh;
65 #endif
66 } IscsiAIOCB;
67
68 struct IscsiTask {
69     IscsiLun *iscsilun;
70     BlockDriverState *bs;
71     int status;
72     int complete;
73 };
74
75 static void
76 iscsi_bh_cb(void *p)
77 {
78     IscsiAIOCB *acb = p;
79
80     qemu_bh_delete(acb->bh);
81
82     if (acb->canceled == 0) {
83         acb->common.cb(acb->common.opaque, acb->status);
84     }
85
86     if (acb->task != NULL) {
87         scsi_free_scsi_task(acb->task);
88         acb->task = NULL;
89     }
90
91     qemu_aio_release(acb);
92 }
93
94 static void
95 iscsi_schedule_bh(IscsiAIOCB *acb)
96 {
97     if (acb->bh) {
98         return;
99     }
100     acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
101     qemu_bh_schedule(acb->bh);
102 }
103
104
105 static void
106 iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
107                     void *private_data)
108 {
109     IscsiAIOCB *acb = private_data;
110
111     acb->status = -ECANCELED;
112     iscsi_schedule_bh(acb);
113 }
114
115 static void
116 iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
117 {
118     IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
119     IscsiLun *iscsilun = acb->iscsilun;
120
121     if (acb->status != -EINPROGRESS) {
122         return;
123     }
124
125     acb->canceled = 1;
126
127     /* send a task mgmt call to the target to cancel the task on the target */
128     iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
129                                      iscsi_abort_task_cb, acb);
130
131     while (acb->status == -EINPROGRESS) {
132         qemu_aio_wait();
133     }
134 }
135
136 static AIOPool iscsi_aio_pool = {
137     .aiocb_size         = sizeof(IscsiAIOCB),
138     .cancel             = iscsi_aio_cancel,
139 };
140
141
142 static void iscsi_process_read(void *arg);
143 static void iscsi_process_write(void *arg);
144
145 static int iscsi_process_flush(void *arg)
146 {
147     IscsiLun *iscsilun = arg;
148
149     return iscsi_queue_length(iscsilun->iscsi) > 0;
150 }
151
152 static void
153 iscsi_set_events(IscsiLun *iscsilun)
154 {
155     struct iscsi_context *iscsi = iscsilun->iscsi;
156     int ev;
157
158     /* We always register a read handler.  */
159     ev = POLLIN;
160     ev |= iscsi_which_events(iscsi);
161     if (ev != iscsilun->events) {
162         qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
163                       iscsi_process_read,
164                       (ev & POLLOUT) ? iscsi_process_write : NULL,
165                       iscsi_process_flush,
166                       iscsilun);
167
168     }
169
170     iscsilun->events = ev;
171 }
172
173 static void
174 iscsi_process_read(void *arg)
175 {
176     IscsiLun *iscsilun = arg;
177     struct iscsi_context *iscsi = iscsilun->iscsi;
178
179     iscsi_service(iscsi, POLLIN);
180     iscsi_set_events(iscsilun);
181 }
182
183 static void
184 iscsi_process_write(void *arg)
185 {
186     IscsiLun *iscsilun = arg;
187     struct iscsi_context *iscsi = iscsilun->iscsi;
188
189     iscsi_service(iscsi, POLLOUT);
190     iscsi_set_events(iscsilun);
191 }
192
193
194 static void
195 iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
196                      void *command_data, void *opaque)
197 {
198     IscsiAIOCB *acb = opaque;
199
200     trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled);
201
202     g_free(acb->buf);
203
204     if (acb->canceled != 0) {
205         return;
206     }
207
208     acb->status = 0;
209     if (status < 0) {
210         error_report("Failed to write16 data to iSCSI lun. %s",
211                      iscsi_get_error(iscsi));
212         acb->status = -EIO;
213     }
214
215     iscsi_schedule_bh(acb);
216 }
217
218 static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
219 {
220     return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
221 }
222
223 static BlockDriverAIOCB *
224 iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
225                  QEMUIOVector *qiov, int nb_sectors,
226                  BlockDriverCompletionFunc *cb,
227                  void *opaque)
228 {
229     IscsiLun *iscsilun = bs->opaque;
230     struct iscsi_context *iscsi = iscsilun->iscsi;
231     IscsiAIOCB *acb;
232     size_t size;
233     uint32_t num_sectors;
234     uint64_t lba;
235     struct iscsi_data data;
236
237     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
238     trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);
239
240     acb->iscsilun = iscsilun;
241     acb->qiov     = qiov;
242
243     acb->canceled   = 0;
244     acb->bh         = NULL;
245     acb->status     = -EINPROGRESS;
246
247     /* XXX we should pass the iovec to write16 to avoid the extra copy */
248     /* this will allow us to get rid of 'buf' completely */
249     size = nb_sectors * BDRV_SECTOR_SIZE;
250     acb->buf = g_malloc(size);
251     qemu_iovec_to_buf(acb->qiov, 0, acb->buf, size);
252
253     acb->task = malloc(sizeof(struct scsi_task));
254     if (acb->task == NULL) {
255         error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
256                      "command. %s", iscsi_get_error(iscsi));
257         qemu_aio_release(acb);
258         return NULL;
259     }
260     memset(acb->task, 0, sizeof(struct scsi_task));
261
262     acb->task->xfer_dir = SCSI_XFER_WRITE;
263     acb->task->cdb_size = 16;
264     acb->task->cdb[0] = 0x8a;
265     lba = sector_qemu2lun(sector_num, iscsilun);
266     *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
267     *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
268     num_sectors = size / iscsilun->block_size;
269     *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
270     acb->task->expxferlen = size;
271
272     data.data = acb->buf;
273     data.size = size;
274
275     if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
276                                  iscsi_aio_write16_cb,
277                                  &data,
278                                  acb) != 0) {
279         scsi_free_scsi_task(acb->task);
280         g_free(acb->buf);
281         qemu_aio_release(acb);
282         return NULL;
283     }
284
285     iscsi_set_events(iscsilun);
286
287     return &acb->common;
288 }
289
290 static void
291 iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
292                     void *command_data, void *opaque)
293 {
294     IscsiAIOCB *acb = opaque;
295
296     trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
297
298     if (acb->canceled != 0) {
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(acb);
310 }
311
312 static BlockDriverAIOCB *
313 iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
314                 QEMUIOVector *qiov, int nb_sectors,
315                 BlockDriverCompletionFunc *cb,
316                 void *opaque)
317 {
318     IscsiLun *iscsilun = bs->opaque;
319     struct iscsi_context *iscsi = iscsilun->iscsi;
320     IscsiAIOCB *acb;
321     size_t qemu_read_size;
322     int i;
323     uint64_t lba;
324     uint32_t num_sectors;
325
326     qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
327
328     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
329     trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
330
331     acb->iscsilun = iscsilun;
332     acb->qiov     = qiov;
333
334     acb->canceled    = 0;
335     acb->bh          = NULL;
336     acb->status      = -EINPROGRESS;
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         return;
413     }
414
415     acb->status = 0;
416     if (status < 0) {
417         error_report("Failed to sync10 data on iSCSI lun. %s",
418                      iscsi_get_error(iscsi));
419         acb->status = -EIO;
420     }
421
422     iscsi_schedule_bh(acb);
423 }
424
425 static BlockDriverAIOCB *
426 iscsi_aio_flush(BlockDriverState *bs,
427                 BlockDriverCompletionFunc *cb, void *opaque)
428 {
429     IscsiLun *iscsilun = bs->opaque;
430     struct iscsi_context *iscsi = iscsilun->iscsi;
431     IscsiAIOCB *acb;
432
433     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
434
435     acb->iscsilun = iscsilun;
436     acb->canceled   = 0;
437     acb->bh         = NULL;
438     acb->status     = -EINPROGRESS;
439
440     acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
441                                          0, 0, 0, 0,
442                                          iscsi_synccache10_cb,
443                                          acb);
444     if (acb->task == NULL) {
445         error_report("iSCSI: Failed to send synchronizecache10 command. %s",
446                      iscsi_get_error(iscsi));
447         qemu_aio_release(acb);
448         return NULL;
449     }
450
451     iscsi_set_events(iscsilun);
452
453     return &acb->common;
454 }
455
456 static void
457 iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
458                      void *command_data, void *opaque)
459 {
460     IscsiAIOCB *acb = opaque;
461
462     if (acb->canceled != 0) {
463         return;
464     }
465
466     acb->status = 0;
467     if (status < 0) {
468         error_report("Failed to unmap data on iSCSI lun. %s",
469                      iscsi_get_error(iscsi));
470         acb->status = -EIO;
471     }
472
473     iscsi_schedule_bh(acb);
474 }
475
476 static BlockDriverAIOCB *
477 iscsi_aio_discard(BlockDriverState *bs,
478                   int64_t sector_num, int nb_sectors,
479                   BlockDriverCompletionFunc *cb, void *opaque)
480 {
481     IscsiLun *iscsilun = bs->opaque;
482     struct iscsi_context *iscsi = iscsilun->iscsi;
483     IscsiAIOCB *acb;
484     struct unmap_list list[1];
485
486     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
487
488     acb->iscsilun = iscsilun;
489     acb->canceled   = 0;
490     acb->bh         = NULL;
491     acb->status     = -EINPROGRESS;
492
493     list[0].lba = sector_qemu2lun(sector_num, iscsilun);
494     list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
495
496     acb->task = iscsi_unmap_task(iscsi, iscsilun->lun,
497                                  0, 0, &list[0], 1,
498                                  iscsi_unmap_cb,
499                                  acb);
500     if (acb->task == NULL) {
501         error_report("iSCSI: Failed to send unmap command. %s",
502                      iscsi_get_error(iscsi));
503         qemu_aio_release(acb);
504         return NULL;
505     }
506
507     iscsi_set_events(iscsilun);
508
509     return &acb->common;
510 }
511
512 #ifdef __linux__
513 static void
514 iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
515                      void *command_data, void *opaque)
516 {
517     IscsiAIOCB *acb = opaque;
518
519     if (acb->canceled != 0) {
520         return;
521     }
522
523     acb->status = 0;
524     if (status < 0) {
525         error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
526                      iscsi_get_error(iscsi));
527         acb->status = -EIO;
528     }
529
530     acb->ioh->driver_status = 0;
531     acb->ioh->host_status   = 0;
532     acb->ioh->resid         = 0;
533
534 #define SG_ERR_DRIVER_SENSE    0x08
535
536     if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
537         int ss;
538
539         acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
540
541         acb->ioh->sb_len_wr = acb->task->datain.size - 2;
542         ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
543              acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
544         memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
545     }
546
547     iscsi_schedule_bh(acb);
548 }
549
550 static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
551         unsigned long int req, void *buf,
552         BlockDriverCompletionFunc *cb, void *opaque)
553 {
554     IscsiLun *iscsilun = bs->opaque;
555     struct iscsi_context *iscsi = iscsilun->iscsi;
556     struct iscsi_data data;
557     IscsiAIOCB *acb;
558
559     assert(req == SG_IO);
560
561     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
562
563     acb->iscsilun = iscsilun;
564     acb->canceled    = 0;
565     acb->bh          = NULL;
566     acb->status      = -EINPROGRESS;
567     acb->buf         = NULL;
568     acb->ioh         = buf;
569
570     acb->task = malloc(sizeof(struct scsi_task));
571     if (acb->task == NULL) {
572         error_report("iSCSI: Failed to allocate task for scsi command. %s",
573                      iscsi_get_error(iscsi));
574         qemu_aio_release(acb);
575         return NULL;
576     }
577     memset(acb->task, 0, sizeof(struct scsi_task));
578
579     switch (acb->ioh->dxfer_direction) {
580     case SG_DXFER_TO_DEV:
581         acb->task->xfer_dir = SCSI_XFER_WRITE;
582         break;
583     case SG_DXFER_FROM_DEV:
584         acb->task->xfer_dir = SCSI_XFER_READ;
585         break;
586     default:
587         acb->task->xfer_dir = SCSI_XFER_NONE;
588         break;
589     }
590
591     acb->task->cdb_size = acb->ioh->cmd_len;
592     memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
593     acb->task->expxferlen = acb->ioh->dxfer_len;
594
595     if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
596         data.data = acb->ioh->dxferp;
597         data.size = acb->ioh->dxfer_len;
598     }
599     if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
600                                  iscsi_aio_ioctl_cb,
601                                  (acb->task->xfer_dir == SCSI_XFER_WRITE) ?
602                                      &data : NULL,
603                                  acb) != 0) {
604         scsi_free_scsi_task(acb->task);
605         qemu_aio_release(acb);
606         return NULL;
607     }
608
609     /* tell libiscsi to read straight into the buffer we got from ioctl */
610     if (acb->task->xfer_dir == SCSI_XFER_READ) {
611         scsi_task_add_data_in_buffer(acb->task,
612                                      acb->ioh->dxfer_len,
613                                      acb->ioh->dxferp);
614     }
615
616     iscsi_set_events(iscsilun);
617
618     return &acb->common;
619 }
620
621
622 static void ioctl_cb(void *opaque, int status)
623 {
624     int *p_status = opaque;
625     *p_status = status;
626 }
627
628 static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
629 {
630     IscsiLun *iscsilun = bs->opaque;
631     int status;
632
633     switch (req) {
634     case SG_GET_VERSION_NUM:
635         *(int *)buf = 30000;
636         break;
637     case SG_GET_SCSI_ID:
638         ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
639         break;
640     case SG_IO:
641         status = -EINPROGRESS;
642         iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
643
644         while (status == -EINPROGRESS) {
645             qemu_aio_wait();
646         }
647
648         return 0;
649     default:
650         return -1;
651     }
652     return 0;
653 }
654 #endif
655
656 static int64_t
657 iscsi_getlength(BlockDriverState *bs)
658 {
659     IscsiLun *iscsilun = bs->opaque;
660     int64_t len;
661
662     len  = iscsilun->num_blocks;
663     len *= iscsilun->block_size;
664
665     return len;
666 }
667
668 static void
669 iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status,
670                         void *command_data, void *opaque)
671 {
672     struct IscsiTask *itask = opaque;
673     struct scsi_readcapacity16 *rc16;
674     struct scsi_task *task = command_data;
675
676     if (status != 0) {
677         error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
678                      iscsi_get_error(iscsi));
679         itask->status   = 1;
680         itask->complete = 1;
681         scsi_free_scsi_task(task);
682         return;
683     }
684
685     rc16 = scsi_datain_unmarshall(task);
686     if (rc16 == NULL) {
687         error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
688         itask->status   = 1;
689         itask->complete = 1;
690         scsi_free_scsi_task(task);
691         return;
692     }
693
694     itask->iscsilun->block_size = rc16->block_length;
695     itask->iscsilun->num_blocks = rc16->returned_lba + 1;
696     itask->bs->total_sectors    = itask->iscsilun->num_blocks *
697                                itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
698
699     itask->status   = 0;
700     itask->complete = 1;
701     scsi_free_scsi_task(task);
702 }
703
704 static void
705 iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
706                         void *command_data, void *opaque)
707 {
708     struct IscsiTask *itask = opaque;
709     struct scsi_readcapacity10 *rc10;
710     struct scsi_task *task = command_data;
711
712     if (status != 0) {
713         error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
714                      iscsi_get_error(iscsi));
715         itask->status   = 1;
716         itask->complete = 1;
717         scsi_free_scsi_task(task);
718         return;
719     }
720
721     rc10 = scsi_datain_unmarshall(task);
722     if (rc10 == NULL) {
723         error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
724         itask->status   = 1;
725         itask->complete = 1;
726         scsi_free_scsi_task(task);
727         return;
728     }
729
730     itask->iscsilun->block_size = rc10->block_size;
731     if (rc10->lba == 0) {
732         /* blank disk loaded */
733         itask->iscsilun->num_blocks = 0;
734     } else {
735         itask->iscsilun->num_blocks = rc10->lba + 1;
736     }
737     itask->bs->total_sectors    = itask->iscsilun->num_blocks *
738                                itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
739
740     itask->status   = 0;
741     itask->complete = 1;
742     scsi_free_scsi_task(task);
743 }
744
745 static void
746 iscsi_inquiry_cb(struct iscsi_context *iscsi, int status, void *command_data,
747                  void *opaque)
748 {
749     struct IscsiTask *itask = opaque;
750     struct scsi_task *task = command_data;
751     struct scsi_inquiry_standard *inq;
752
753     if (status != 0) {
754         itask->status   = 1;
755         itask->complete = 1;
756         scsi_free_scsi_task(task);
757         return;
758     }
759
760     inq = scsi_datain_unmarshall(task);
761     if (inq == NULL) {
762         error_report("iSCSI: Failed to unmarshall inquiry data.");
763         itask->status   = 1;
764         itask->complete = 1;
765         scsi_free_scsi_task(task);
766         return;
767     }
768
769     itask->iscsilun->type = inq->periperal_device_type;
770
771     scsi_free_scsi_task(task);
772
773     switch (itask->iscsilun->type) {
774     case TYPE_DISK:
775         task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun,
776                                    iscsi_readcapacity16_cb, opaque);
777         if (task == NULL) {
778             error_report("iSCSI: failed to send readcapacity16 command.");
779             itask->status   = 1;
780             itask->complete = 1;
781             return;
782         }
783         break;
784     case TYPE_ROM:
785         task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun,
786                                    0, 0,
787                                    iscsi_readcapacity10_cb, opaque);
788         if (task == NULL) {
789             error_report("iSCSI: failed to send readcapacity16 command.");
790             itask->status   = 1;
791             itask->complete = 1;
792             return;
793         }
794         break;
795     default:
796         itask->status   = 0;
797         itask->complete = 1;
798     }
799 }
800
801 static void
802 iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
803                  void *opaque)
804 {
805     struct IscsiTask *itask = opaque;
806     struct scsi_task *task;
807
808     if (status != 0) {
809         itask->status   = 1;
810         itask->complete = 1;
811         return;
812     }
813
814     task = iscsi_inquiry_task(iscsi, itask->iscsilun->lun,
815                               0, 0, 36,
816                               iscsi_inquiry_cb, opaque);
817     if (task == NULL) {
818         error_report("iSCSI: failed to send inquiry command.");
819         itask->status   = 1;
820         itask->complete = 1;
821         return;
822     }
823 }
824
825 static int parse_chap(struct iscsi_context *iscsi, const char *target)
826 {
827     QemuOptsList *list;
828     QemuOpts *opts;
829     const char *user = NULL;
830     const char *password = NULL;
831
832     list = qemu_find_opts("iscsi");
833     if (!list) {
834         return 0;
835     }
836
837     opts = qemu_opts_find(list, target);
838     if (opts == NULL) {
839         opts = QTAILQ_FIRST(&list->head);
840         if (!opts) {
841             return 0;
842         }
843     }
844
845     user = qemu_opt_get(opts, "user");
846     if (!user) {
847         return 0;
848     }
849
850     password = qemu_opt_get(opts, "password");
851     if (!password) {
852         error_report("CHAP username specified but no password was given");
853         return -1;
854     }
855
856     if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
857         error_report("Failed to set initiator username and password");
858         return -1;
859     }
860
861     return 0;
862 }
863
864 static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
865 {
866     QemuOptsList *list;
867     QemuOpts *opts;
868     const char *digest = NULL;
869
870     list = qemu_find_opts("iscsi");
871     if (!list) {
872         return;
873     }
874
875     opts = qemu_opts_find(list, target);
876     if (opts == NULL) {
877         opts = QTAILQ_FIRST(&list->head);
878         if (!opts) {
879             return;
880         }
881     }
882
883     digest = qemu_opt_get(opts, "header-digest");
884     if (!digest) {
885         return;
886     }
887
888     if (!strcmp(digest, "CRC32C")) {
889         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
890     } else if (!strcmp(digest, "NONE")) {
891         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
892     } else if (!strcmp(digest, "CRC32C-NONE")) {
893         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
894     } else if (!strcmp(digest, "NONE-CRC32C")) {
895         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
896     } else {
897         error_report("Invalid header-digest setting : %s", digest);
898     }
899 }
900
901 static char *parse_initiator_name(const char *target)
902 {
903     QemuOptsList *list;
904     QemuOpts *opts;
905     const char *name = NULL;
906     const char *iscsi_name = qemu_get_vm_name();
907
908     list = qemu_find_opts("iscsi");
909     if (list) {
910         opts = qemu_opts_find(list, target);
911         if (!opts) {
912             opts = QTAILQ_FIRST(&list->head);
913         }
914         if (opts) {
915             name = qemu_opt_get(opts, "initiator-name");
916         }
917     }
918
919     if (name) {
920         return g_strdup(name);
921     } else {
922         return g_strdup_printf("iqn.2008-11.org.linux-kvm%s%s",
923                                iscsi_name ? ":" : "",
924                                iscsi_name ? iscsi_name : "");
925     }
926 }
927
928 /*
929  * We support iscsi url's on the form
930  * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
931  */
932 static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
933 {
934     IscsiLun *iscsilun = bs->opaque;
935     struct iscsi_context *iscsi = NULL;
936     struct iscsi_url *iscsi_url = NULL;
937     struct IscsiTask task;
938     char *initiator_name = NULL;
939     int ret;
940
941     if ((BDRV_SECTOR_SIZE % 512) != 0) {
942         error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
943                      "BDRV_SECTOR_SIZE(%lld) is not a multiple "
944                      "of 512", BDRV_SECTOR_SIZE);
945         return -EINVAL;
946     }
947
948     iscsi_url = iscsi_parse_full_url(iscsi, filename);
949     if (iscsi_url == NULL) {
950         error_report("Failed to parse URL : %s %s", filename,
951                      iscsi_get_error(iscsi));
952         ret = -EINVAL;
953         goto out;
954     }
955
956     memset(iscsilun, 0, sizeof(IscsiLun));
957
958     initiator_name = parse_initiator_name(iscsi_url->target);
959
960     iscsi = iscsi_create_context(initiator_name);
961     if (iscsi == NULL) {
962         error_report("iSCSI: Failed to create iSCSI context.");
963         ret = -ENOMEM;
964         goto out;
965     }
966
967     if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
968         error_report("iSCSI: Failed to set target name.");
969         ret = -EINVAL;
970         goto out;
971     }
972
973     if (iscsi_url->user != NULL) {
974         ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
975                                               iscsi_url->passwd);
976         if (ret != 0) {
977             error_report("Failed to set initiator username and password");
978             ret = -EINVAL;
979             goto out;
980         }
981     }
982
983     /* check if we got CHAP username/password via the options */
984     if (parse_chap(iscsi, iscsi_url->target) != 0) {
985         error_report("iSCSI: Failed to set CHAP user/password");
986         ret = -EINVAL;
987         goto out;
988     }
989
990     if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
991         error_report("iSCSI: Failed to set session type to normal.");
992         ret = -EINVAL;
993         goto out;
994     }
995
996     iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
997
998     /* check if we got HEADER_DIGEST via the options */
999     parse_header_digest(iscsi, iscsi_url->target);
1000
1001     task.iscsilun = iscsilun;
1002     task.status = 0;
1003     task.complete = 0;
1004     task.bs = bs;
1005
1006     iscsilun->iscsi = iscsi;
1007     iscsilun->lun   = iscsi_url->lun;
1008
1009     if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,
1010                                  iscsi_connect_cb, &task)
1011         != 0) {
1012         error_report("iSCSI: Failed to start async connect.");
1013         ret = -EINVAL;
1014         goto out;
1015     }
1016
1017     while (!task.complete) {
1018         iscsi_set_events(iscsilun);
1019         qemu_aio_wait();
1020     }
1021     if (task.status != 0) {
1022         error_report("iSCSI: Failed to connect to LUN : %s",
1023                      iscsi_get_error(iscsi));
1024         ret = -EINVAL;
1025         goto out;
1026     }
1027
1028     /* Medium changer or tape. We dont have any emulation for this so this must
1029      * be sg ioctl compatible. We force it to be sg, otherwise qemu will try
1030      * to read from the device to guess the image format.
1031      */
1032     if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
1033         iscsilun->type == TYPE_TAPE) {
1034         bs->sg = 1;
1035     }
1036
1037     ret = 0;
1038
1039 out:
1040     if (initiator_name != NULL) {
1041         g_free(initiator_name);
1042     }
1043     if (iscsi_url != NULL) {
1044         iscsi_destroy_url(iscsi_url);
1045     }
1046
1047     if (ret) {
1048         if (iscsi != NULL) {
1049             iscsi_destroy_context(iscsi);
1050         }
1051         memset(iscsilun, 0, sizeof(IscsiLun));
1052     }
1053     return ret;
1054 }
1055
1056 static void iscsi_close(BlockDriverState *bs)
1057 {
1058     IscsiLun *iscsilun = bs->opaque;
1059     struct iscsi_context *iscsi = iscsilun->iscsi;
1060
1061     qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
1062     iscsi_destroy_context(iscsi);
1063     memset(iscsilun, 0, sizeof(IscsiLun));
1064 }
1065
1066 static BlockDriver bdrv_iscsi = {
1067     .format_name     = "iscsi",
1068     .protocol_name   = "iscsi",
1069
1070     .instance_size   = sizeof(IscsiLun),
1071     .bdrv_file_open  = iscsi_open,
1072     .bdrv_close      = iscsi_close,
1073
1074     .bdrv_getlength  = iscsi_getlength,
1075
1076     .bdrv_aio_readv  = iscsi_aio_readv,
1077     .bdrv_aio_writev = iscsi_aio_writev,
1078     .bdrv_aio_flush  = iscsi_aio_flush,
1079
1080     .bdrv_aio_discard = iscsi_aio_discard,
1081
1082 #ifdef __linux__
1083     .bdrv_ioctl       = iscsi_ioctl,
1084     .bdrv_aio_ioctl   = iscsi_aio_ioctl,
1085 #endif
1086 };
1087
1088 static void iscsi_block_init(void)
1089 {
1090     bdrv_register(&bdrv_iscsi);
1091 }
1092
1093 block_init(iscsi_block_init);
This page took 0.086596 seconds and 4 git commands to generate.