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