xref: /qemu/block/iscsi.c (revision b2cd7dee)
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 "qemu-common.h"
29 #include "qemu-error.h"
30 #include "block_int.h"
31 #include "trace.h"
32 
33 #include <iscsi/iscsi.h>
34 #include <iscsi/scsi-lowlevel.h>
35 
36 
37 typedef struct IscsiLun {
38     struct iscsi_context *iscsi;
39     int lun;
40     int block_size;
41     unsigned long num_blocks;
42 } IscsiLun;
43 
44 typedef struct IscsiAIOCB {
45     BlockDriverAIOCB common;
46     QEMUIOVector *qiov;
47     QEMUBH *bh;
48     IscsiLun *iscsilun;
49     struct scsi_task *task;
50     uint8_t *buf;
51     int status;
52     int canceled;
53     size_t read_size;
54     size_t read_offset;
55 } IscsiAIOCB;
56 
57 struct IscsiTask {
58     IscsiLun *iscsilun;
59     BlockDriverState *bs;
60     int status;
61     int complete;
62 };
63 
64 static void
65 iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
66                     void *private_data)
67 {
68 }
69 
70 static void
71 iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
72 {
73     IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
74     IscsiLun *iscsilun = acb->iscsilun;
75 
76     acb->common.cb(acb->common.opaque, -ECANCELED);
77     acb->canceled = 1;
78 
79     /* send a task mgmt call to the target to cancel the task on the target */
80     iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
81                                      iscsi_abort_task_cb, NULL);
82 
83     /* then also cancel the task locally in libiscsi */
84     iscsi_scsi_task_cancel(iscsilun->iscsi, acb->task);
85 }
86 
87 static AIOPool iscsi_aio_pool = {
88     .aiocb_size         = sizeof(IscsiAIOCB),
89     .cancel             = iscsi_aio_cancel,
90 };
91 
92 
93 static void iscsi_process_read(void *arg);
94 static void iscsi_process_write(void *arg);
95 
96 static int iscsi_process_flush(void *arg)
97 {
98     IscsiLun *iscsilun = arg;
99 
100     return iscsi_queue_length(iscsilun->iscsi) > 0;
101 }
102 
103 static void
104 iscsi_set_events(IscsiLun *iscsilun)
105 {
106     struct iscsi_context *iscsi = iscsilun->iscsi;
107 
108     qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), iscsi_process_read,
109                            (iscsi_which_events(iscsi) & POLLOUT)
110                            ? iscsi_process_write : NULL,
111                            iscsi_process_flush, NULL, iscsilun);
112 }
113 
114 static void
115 iscsi_process_read(void *arg)
116 {
117     IscsiLun *iscsilun = arg;
118     struct iscsi_context *iscsi = iscsilun->iscsi;
119 
120     iscsi_service(iscsi, POLLIN);
121     iscsi_set_events(iscsilun);
122 }
123 
124 static void
125 iscsi_process_write(void *arg)
126 {
127     IscsiLun *iscsilun = arg;
128     struct iscsi_context *iscsi = iscsilun->iscsi;
129 
130     iscsi_service(iscsi, POLLOUT);
131     iscsi_set_events(iscsilun);
132 }
133 
134 
135 static int
136 iscsi_schedule_bh(QEMUBHFunc *cb, IscsiAIOCB *acb)
137 {
138     acb->bh = qemu_bh_new(cb, acb);
139     if (!acb->bh) {
140         error_report("oom: could not create iscsi bh");
141         return -EIO;
142     }
143 
144     qemu_bh_schedule(acb->bh);
145     return 0;
146 }
147 
148 static void
149 iscsi_readv_writev_bh_cb(void *p)
150 {
151     IscsiAIOCB *acb = p;
152 
153     qemu_bh_delete(acb->bh);
154 
155     if (acb->canceled == 0) {
156         acb->common.cb(acb->common.opaque, acb->status);
157     }
158 
159     qemu_aio_release(acb);
160 }
161 
162 
163 static void
164 iscsi_aio_write10_cb(struct iscsi_context *iscsi, int status,
165                      void *command_data, void *opaque)
166 {
167     IscsiAIOCB *acb = opaque;
168 
169     trace_iscsi_aio_write10_cb(iscsi, status, acb, acb->canceled);
170 
171     g_free(acb->buf);
172 
173     if (acb->canceled != 0) {
174         qemu_aio_release(acb);
175         scsi_free_scsi_task(acb->task);
176         acb->task = NULL;
177         return;
178     }
179 
180     acb->status = 0;
181     if (status < 0) {
182         error_report("Failed to write10 data to iSCSI lun. %s",
183                      iscsi_get_error(iscsi));
184         acb->status = -EIO;
185     }
186 
187     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
188     scsi_free_scsi_task(acb->task);
189     acb->task = NULL;
190 }
191 
192 static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
193 {
194     return sector * BDRV_SECTOR_SIZE / iscsilun->block_size;
195 }
196 
197 static BlockDriverAIOCB *
198 iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
199                  QEMUIOVector *qiov, int nb_sectors,
200                  BlockDriverCompletionFunc *cb,
201                  void *opaque)
202 {
203     IscsiLun *iscsilun = bs->opaque;
204     struct iscsi_context *iscsi = iscsilun->iscsi;
205     IscsiAIOCB *acb;
206     size_t size;
207     int fua = 0;
208 
209     /* set FUA on writes when cache mode is write through */
210     if (!(bs->open_flags & BDRV_O_CACHE_WB)) {
211         fua = 1;
212     }
213 
214     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
215     trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);
216 
217     acb->iscsilun = iscsilun;
218     acb->qiov     = qiov;
219 
220     acb->canceled   = 0;
221 
222     /* XXX we should pass the iovec to write10 to avoid the extra copy */
223     /* this will allow us to get rid of 'buf' completely */
224     size = nb_sectors * BDRV_SECTOR_SIZE;
225     acb->buf = g_malloc(size);
226     qemu_iovec_to_buffer(acb->qiov, acb->buf);
227     acb->task = iscsi_write10_task(iscsi, iscsilun->lun, acb->buf, size,
228                               sector_qemu2lun(sector_num, iscsilun),
229                               fua, 0, iscsilun->block_size,
230                               iscsi_aio_write10_cb, acb);
231     if (acb->task == NULL) {
232         error_report("iSCSI: Failed to send write10 command. %s",
233                      iscsi_get_error(iscsi));
234         g_free(acb->buf);
235         qemu_aio_release(acb);
236         return NULL;
237     }
238 
239     iscsi_set_events(iscsilun);
240 
241     return &acb->common;
242 }
243 
244 static void
245 iscsi_aio_read10_cb(struct iscsi_context *iscsi, int status,
246                     void *command_data, void *opaque)
247 {
248     IscsiAIOCB *acb = opaque;
249 
250     trace_iscsi_aio_read10_cb(iscsi, status, acb, acb->canceled);
251 
252     if (acb->canceled != 0) {
253         qemu_aio_release(acb);
254         scsi_free_scsi_task(acb->task);
255         acb->task = NULL;
256         return;
257     }
258 
259     acb->status = 0;
260     if (status != 0) {
261         error_report("Failed to read10 data from iSCSI lun. %s",
262                      iscsi_get_error(iscsi));
263         acb->status = -EIO;
264     }
265 
266     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
267     scsi_free_scsi_task(acb->task);
268     acb->task = NULL;
269 }
270 
271 static BlockDriverAIOCB *
272 iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
273                 QEMUIOVector *qiov, int nb_sectors,
274                 BlockDriverCompletionFunc *cb,
275                 void *opaque)
276 {
277     IscsiLun *iscsilun = bs->opaque;
278     struct iscsi_context *iscsi = iscsilun->iscsi;
279     IscsiAIOCB *acb;
280     size_t qemu_read_size, lun_read_size;
281     int i;
282 
283     qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
284 
285     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
286     trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
287 
288     acb->iscsilun = iscsilun;
289     acb->qiov     = qiov;
290 
291     acb->canceled    = 0;
292     acb->read_size   = qemu_read_size;
293     acb->buf         = NULL;
294 
295     /* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU
296      * may be misaligned to the LUN, so we may need to read some extra
297      * data.
298      */
299     acb->read_offset = 0;
300     if (iscsilun->block_size > BDRV_SECTOR_SIZE) {
301         uint64_t bdrv_offset = BDRV_SECTOR_SIZE * sector_num;
302 
303         acb->read_offset  = bdrv_offset % iscsilun->block_size;
304     }
305 
306     lun_read_size  = (qemu_read_size + iscsilun->block_size
307                      + acb->read_offset - 1)
308                      / iscsilun->block_size * iscsilun->block_size;
309     acb->task = iscsi_read10_task(iscsi, iscsilun->lun,
310                              sector_qemu2lun(sector_num, iscsilun),
311                              lun_read_size, iscsilun->block_size,
312                              iscsi_aio_read10_cb, acb);
313     if (acb->task == NULL) {
314         error_report("iSCSI: Failed to send read10 command. %s",
315                      iscsi_get_error(iscsi));
316         qemu_aio_release(acb);
317         return NULL;
318     }
319 
320     for (i = 0; i < acb->qiov->niov; i++) {
321         scsi_task_add_data_in_buffer(acb->task,
322                 acb->qiov->iov[i].iov_len,
323                 acb->qiov->iov[i].iov_base);
324     }
325 
326     iscsi_set_events(iscsilun);
327 
328     return &acb->common;
329 }
330 
331 
332 static void
333 iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
334                      void *command_data, void *opaque)
335 {
336     IscsiAIOCB *acb = opaque;
337 
338     if (acb->canceled != 0) {
339         qemu_aio_release(acb);
340         scsi_free_scsi_task(acb->task);
341         acb->task = NULL;
342         return;
343     }
344 
345     acb->status = 0;
346     if (status < 0) {
347         error_report("Failed to sync10 data on iSCSI lun. %s",
348                      iscsi_get_error(iscsi));
349         acb->status = -EIO;
350     }
351 
352     iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
353     scsi_free_scsi_task(acb->task);
354     acb->task = NULL;
355 }
356 
357 static BlockDriverAIOCB *
358 iscsi_aio_flush(BlockDriverState *bs,
359                 BlockDriverCompletionFunc *cb, void *opaque)
360 {
361     IscsiLun *iscsilun = bs->opaque;
362     struct iscsi_context *iscsi = iscsilun->iscsi;
363     IscsiAIOCB *acb;
364 
365     acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
366 
367     acb->iscsilun = iscsilun;
368     acb->canceled   = 0;
369 
370     acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
371                                          0, 0, 0, 0,
372                                          iscsi_synccache10_cb,
373                                          acb);
374     if (acb->task == NULL) {
375         error_report("iSCSI: Failed to send synchronizecache10 command. %s",
376                      iscsi_get_error(iscsi));
377         qemu_aio_release(acb);
378         return NULL;
379     }
380 
381     iscsi_set_events(iscsilun);
382 
383     return &acb->common;
384 }
385 
386 static int64_t
387 iscsi_getlength(BlockDriverState *bs)
388 {
389     IscsiLun *iscsilun = bs->opaque;
390     int64_t len;
391 
392     len  = iscsilun->num_blocks;
393     len *= iscsilun->block_size;
394 
395     return len;
396 }
397 
398 static void
399 iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
400                         void *command_data, void *opaque)
401 {
402     struct IscsiTask *itask = opaque;
403     struct scsi_readcapacity10 *rc10;
404     struct scsi_task *task = command_data;
405 
406     if (status != 0) {
407         error_report("iSCSI: Failed to read capacity of iSCSI lun. %s",
408                      iscsi_get_error(iscsi));
409         itask->status   = 1;
410         itask->complete = 1;
411         scsi_free_scsi_task(task);
412         return;
413     }
414 
415     rc10 = scsi_datain_unmarshall(task);
416     if (rc10 == NULL) {
417         error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
418         itask->status   = 1;
419         itask->complete = 1;
420         scsi_free_scsi_task(task);
421         return;
422     }
423 
424     itask->iscsilun->block_size = rc10->block_size;
425     itask->iscsilun->num_blocks = rc10->lba;
426     itask->bs->total_sectors = (uint64_t)rc10->lba *
427                                rc10->block_size / BDRV_SECTOR_SIZE ;
428 
429     itask->status   = 0;
430     itask->complete = 1;
431     scsi_free_scsi_task(task);
432 }
433 
434 
435 static void
436 iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
437                  void *opaque)
438 {
439     struct IscsiTask *itask = opaque;
440     struct scsi_task *task;
441 
442     if (status != 0) {
443         itask->status   = 1;
444         itask->complete = 1;
445         return;
446     }
447 
448     task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun, 0, 0,
449                                    iscsi_readcapacity10_cb, opaque);
450     if (task == NULL) {
451         error_report("iSCSI: failed to send readcapacity command.");
452         itask->status   = 1;
453         itask->complete = 1;
454         return;
455     }
456 }
457 
458 static int parse_chap(struct iscsi_context *iscsi, const char *target)
459 {
460     QemuOptsList *list;
461     QemuOpts *opts;
462     const char *user = NULL;
463     const char *password = NULL;
464 
465     list = qemu_find_opts("iscsi");
466     if (!list) {
467         return 0;
468     }
469 
470     opts = qemu_opts_find(list, target);
471     if (opts == NULL) {
472         opts = QTAILQ_FIRST(&list->head);
473         if (!opts) {
474             return 0;
475         }
476     }
477 
478     user = qemu_opt_get(opts, "user");
479     if (!user) {
480         return 0;
481     }
482 
483     password = qemu_opt_get(opts, "password");
484     if (!password) {
485         error_report("CHAP username specified but no password was given");
486         return -1;
487     }
488 
489     if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
490         error_report("Failed to set initiator username and password");
491         return -1;
492     }
493 
494     return 0;
495 }
496 
497 static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
498 {
499     QemuOptsList *list;
500     QemuOpts *opts;
501     const char *digest = NULL;
502 
503     list = qemu_find_opts("iscsi");
504     if (!list) {
505         return;
506     }
507 
508     opts = qemu_opts_find(list, target);
509     if (opts == NULL) {
510         opts = QTAILQ_FIRST(&list->head);
511         if (!opts) {
512             return;
513         }
514     }
515 
516     digest = qemu_opt_get(opts, "header-digest");
517     if (!digest) {
518         return;
519     }
520 
521     if (!strcmp(digest, "CRC32C")) {
522         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
523     } else if (!strcmp(digest, "NONE")) {
524         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
525     } else if (!strcmp(digest, "CRC32C-NONE")) {
526         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
527     } else if (!strcmp(digest, "NONE-CRC32C")) {
528         iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
529     } else {
530         error_report("Invalid header-digest setting : %s", digest);
531     }
532 }
533 
534 static char *parse_initiator_name(const char *target)
535 {
536     QemuOptsList *list;
537     QemuOpts *opts;
538     const char *name = NULL;
539 
540     list = qemu_find_opts("iscsi");
541     if (!list) {
542         return g_strdup("iqn.2008-11.org.linux-kvm");
543     }
544 
545     opts = qemu_opts_find(list, target);
546     if (opts == NULL) {
547         opts = QTAILQ_FIRST(&list->head);
548         if (!opts) {
549             return g_strdup("iqn.2008-11.org.linux-kvm");
550         }
551     }
552 
553     name = qemu_opt_get(opts, "initiator-name");
554     if (!name) {
555         return g_strdup("iqn.2008-11.org.linux-kvm");
556     }
557 
558     return g_strdup(name);
559 }
560 
561 /*
562  * We support iscsi url's on the form
563  * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
564  */
565 static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
566 {
567     IscsiLun *iscsilun = bs->opaque;
568     struct iscsi_context *iscsi = NULL;
569     struct iscsi_url *iscsi_url = NULL;
570     struct IscsiTask task;
571     char *initiator_name = NULL;
572     int ret;
573 
574     if ((BDRV_SECTOR_SIZE % 512) != 0) {
575         error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
576                      "BDRV_SECTOR_SIZE(%lld) is not a multiple "
577                      "of 512", BDRV_SECTOR_SIZE);
578         return -EINVAL;
579     }
580 
581     iscsi_url = iscsi_parse_full_url(iscsi, filename);
582     if (iscsi_url == NULL) {
583         error_report("Failed to parse URL : %s %s", filename,
584                      iscsi_get_error(iscsi));
585         ret = -EINVAL;
586         goto failed;
587     }
588 
589     memset(iscsilun, 0, sizeof(IscsiLun));
590 
591     initiator_name = parse_initiator_name(iscsi_url->target);
592 
593     iscsi = iscsi_create_context(initiator_name);
594     if (iscsi == NULL) {
595         error_report("iSCSI: Failed to create iSCSI context.");
596         ret = -ENOMEM;
597         goto failed;
598     }
599 
600     if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
601         error_report("iSCSI: Failed to set target name.");
602         ret = -EINVAL;
603         goto failed;
604     }
605 
606     if (iscsi_url->user != NULL) {
607         ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
608                                               iscsi_url->passwd);
609         if (ret != 0) {
610             error_report("Failed to set initiator username and password");
611             ret = -EINVAL;
612             goto failed;
613         }
614     }
615 
616     /* check if we got CHAP username/password via the options */
617     if (parse_chap(iscsi, iscsi_url->target) != 0) {
618         error_report("iSCSI: Failed to set CHAP user/password");
619         ret = -EINVAL;
620         goto failed;
621     }
622 
623     if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
624         error_report("iSCSI: Failed to set session type to normal.");
625         ret = -EINVAL;
626         goto failed;
627     }
628 
629     iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
630 
631     /* check if we got HEADER_DIGEST via the options */
632     parse_header_digest(iscsi, iscsi_url->target);
633 
634     task.iscsilun = iscsilun;
635     task.status = 0;
636     task.complete = 0;
637     task.bs = bs;
638 
639     iscsilun->iscsi = iscsi;
640     iscsilun->lun   = iscsi_url->lun;
641 
642     if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,
643                                  iscsi_connect_cb, &task)
644         != 0) {
645         error_report("iSCSI: Failed to start async connect.");
646         ret = -EINVAL;
647         goto failed;
648     }
649 
650     while (!task.complete) {
651         iscsi_set_events(iscsilun);
652         qemu_aio_wait();
653     }
654     if (task.status != 0) {
655         error_report("iSCSI: Failed to connect to LUN : %s",
656                      iscsi_get_error(iscsi));
657         ret = -EINVAL;
658         goto failed;
659     }
660 
661     if (iscsi_url != NULL) {
662         iscsi_destroy_url(iscsi_url);
663     }
664     return 0;
665 
666 failed:
667     if (initiator_name != NULL) {
668         g_free(initiator_name);
669     }
670     if (iscsi_url != NULL) {
671         iscsi_destroy_url(iscsi_url);
672     }
673     if (iscsi != NULL) {
674         iscsi_destroy_context(iscsi);
675     }
676     memset(iscsilun, 0, sizeof(IscsiLun));
677     return ret;
678 }
679 
680 static void iscsi_close(BlockDriverState *bs)
681 {
682     IscsiLun *iscsilun = bs->opaque;
683     struct iscsi_context *iscsi = iscsilun->iscsi;
684 
685     qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL, NULL);
686     iscsi_destroy_context(iscsi);
687     memset(iscsilun, 0, sizeof(IscsiLun));
688 }
689 
690 static BlockDriver bdrv_iscsi = {
691     .format_name     = "iscsi",
692     .protocol_name   = "iscsi",
693 
694     .instance_size   = sizeof(IscsiLun),
695     .bdrv_file_open  = iscsi_open,
696     .bdrv_close      = iscsi_close,
697 
698     .bdrv_getlength  = iscsi_getlength,
699 
700     .bdrv_aio_readv  = iscsi_aio_readv,
701     .bdrv_aio_writev = iscsi_aio_writev,
702     .bdrv_aio_flush  = iscsi_aio_flush,
703 };
704 
705 static void iscsi_block_init(void)
706 {
707     bdrv_register(&bdrv_iscsi);
708 }
709 
710 block_init(iscsi_block_init);
711