Statistics
| Branch: | Revision:

root / block / iscsi.c @ 077805fa

History | View | Annotate | Download (26.1 kB)

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-config.h"
31
#include "qemu-error.h"
32
#include "block_int.h"
33
#include "trace.h"
34
#include "hw/scsi-defs.h"
35

    
36
#include <iscsi/iscsi.h>
37
#include <iscsi/scsi-lowlevel.h>
38

    
39
#ifdef __linux__
40
#include <scsi/sg.h>
41
#include <hw/scsi-defs.h>
42
#endif
43

    
44
typedef struct IscsiLun {
45
    struct iscsi_context *iscsi;
46
    int lun;
47
    enum scsi_inquiry_peripheral_device_type type;
48
    int block_size;
49
    uint64_t num_blocks;
50
    int events;
51
} IscsiLun;
52

    
53
typedef struct IscsiAIOCB {
54
    BlockDriverAIOCB common;
55
    QEMUIOVector *qiov;
56
    QEMUBH *bh;
57
    IscsiLun *iscsilun;
58
    struct scsi_task *task;
59
    uint8_t *buf;
60
    int status;
61
    int canceled;
62
    size_t read_size;
63
    size_t read_offset;
64
#ifdef __linux__
65
    sg_io_hdr_t *ioh;
66
#endif
67
} IscsiAIOCB;
68

    
69
static void
70
iscsi_bh_cb(void *p)
71
{
72
    IscsiAIOCB *acb = p;
73

    
74
    qemu_bh_delete(acb->bh);
75

    
76
    if (acb->canceled == 0) {
77
        acb->common.cb(acb->common.opaque, acb->status);
78
    }
79

    
80
    if (acb->task != NULL) {
81
        scsi_free_scsi_task(acb->task);
82
        acb->task = NULL;
83
    }
84

    
85
    qemu_aio_release(acb);
86
}
87

    
88
static void
89
iscsi_schedule_bh(IscsiAIOCB *acb)
90
{
91
    if (acb->bh) {
92
        return;
93
    }
94
    acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
95
    qemu_bh_schedule(acb->bh);
96
}
97

    
98

    
99
static void
100
iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
101
                    void *private_data)
102
{
103
    IscsiAIOCB *acb = private_data;
104

    
105
    acb->status = -ECANCELED;
106
    iscsi_schedule_bh(acb);
107
}
108

    
109
static void
110
iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
111
{
112
    IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
113
    IscsiLun *iscsilun = acb->iscsilun;
114

    
115
    if (acb->status != -EINPROGRESS) {
116
        return;
117
    }
118

    
119
    acb->canceled = 1;
120

    
121
    /* send a task mgmt call to the target to cancel the task on the target */
122
    iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
123
                                     iscsi_abort_task_cb, acb);
124

    
125
    while (acb->status == -EINPROGRESS) {
126
        qemu_aio_wait();
127
    }
128
}
129

    
130
static const AIOCBInfo iscsi_aiocb_info = {
131
    .aiocb_size         = sizeof(IscsiAIOCB),
132
    .cancel             = iscsi_aio_cancel,
133
};
134

    
135

    
136
static void iscsi_process_read(void *arg);
137
static void iscsi_process_write(void *arg);
138

    
139
static int iscsi_process_flush(void *arg)
140
{
141
    IscsiLun *iscsilun = arg;
142

    
143
    return iscsi_queue_length(iscsilun->iscsi) > 0;
144
}
145

    
146
static void
147
iscsi_set_events(IscsiLun *iscsilun)
148
{
149
    struct iscsi_context *iscsi = iscsilun->iscsi;
150
    int ev;
151

    
152
    /* We always register a read handler.  */
153
    ev = POLLIN;
154
    ev |= iscsi_which_events(iscsi);
155
    if (ev != iscsilun->events) {
156
        qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
157
                      iscsi_process_read,
158
                      (ev & POLLOUT) ? iscsi_process_write : NULL,
159
                      iscsi_process_flush,
160
                      iscsilun);
161

    
162
    }
163

    
164
    iscsilun->events = ev;
165
}
166

    
167
static void
168
iscsi_process_read(void *arg)
169
{
170
    IscsiLun *iscsilun = arg;
171
    struct iscsi_context *iscsi = iscsilun->iscsi;
172

    
173
    iscsi_service(iscsi, POLLIN);
174
    iscsi_set_events(iscsilun);
175
}
176

    
177
static void
178
iscsi_process_write(void *arg)
179
{
180
    IscsiLun *iscsilun = arg;
181
    struct iscsi_context *iscsi = iscsilun->iscsi;
182

    
183
    iscsi_service(iscsi, POLLOUT);
184
    iscsi_set_events(iscsilun);
185
}
186

    
187

    
188
static void
189
iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
190
                     void *command_data, void *opaque)
191
{
192
    IscsiAIOCB *acb = opaque;
193

    
194
    trace_iscsi_aio_write16_cb(iscsi, status, acb, acb->canceled);
195

    
196
    g_free(acb->buf);
197

    
198
    if (acb->canceled != 0) {
199
        return;
200
    }
201

    
202
    acb->status = 0;
203
    if (status < 0) {
204
        error_report("Failed to write16 data to iSCSI lun. %s",
205
                     iscsi_get_error(iscsi));
206
        acb->status = -EIO;
207
    }
208

    
209
    iscsi_schedule_bh(acb);
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_aiocb_info, 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
    acb->bh         = NULL;
239
    acb->status     = -EINPROGRESS;
240

    
241
    /* XXX we should pass the iovec to write16 to avoid the extra copy */
242
    /* this will allow us to get rid of 'buf' completely */
243
    size = nb_sectors * BDRV_SECTOR_SIZE;
244
    acb->buf = g_malloc(size);
245
    qemu_iovec_to_buf(acb->qiov, 0, acb->buf, size);
246

    
247
    acb->task = malloc(sizeof(struct scsi_task));
248
    if (acb->task == NULL) {
249
        error_report("iSCSI: Failed to allocate task for scsi WRITE16 "
250
                     "command. %s", iscsi_get_error(iscsi));
251
        qemu_aio_release(acb);
252
        return NULL;
253
    }
254
    memset(acb->task, 0, sizeof(struct scsi_task));
255

    
256
    acb->task->xfer_dir = SCSI_XFER_WRITE;
257
    acb->task->cdb_size = 16;
258
    acb->task->cdb[0] = 0x8a;
259
    lba = sector_qemu2lun(sector_num, iscsilun);
260
    *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
261
    *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
262
    num_sectors = size / iscsilun->block_size;
263
    *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
264
    acb->task->expxferlen = size;
265

    
266
    data.data = acb->buf;
267
    data.size = size;
268

    
269
    if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
270
                                 iscsi_aio_write16_cb,
271
                                 &data,
272
                                 acb) != 0) {
273
        scsi_free_scsi_task(acb->task);
274
        g_free(acb->buf);
275
        qemu_aio_release(acb);
276
        return NULL;
277
    }
278

    
279
    iscsi_set_events(iscsilun);
280

    
281
    return &acb->common;
282
}
283

    
284
static void
285
iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
286
                    void *command_data, void *opaque)
287
{
288
    IscsiAIOCB *acb = opaque;
289

    
290
    trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
291

    
292
    if (acb->canceled != 0) {
293
        return;
294
    }
295

    
296
    acb->status = 0;
297
    if (status != 0) {
298
        error_report("Failed to read16 data from iSCSI lun. %s",
299
                     iscsi_get_error(iscsi));
300
        acb->status = -EIO;
301
    }
302

    
303
    iscsi_schedule_bh(acb);
304
}
305

    
306
static BlockDriverAIOCB *
307
iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
308
                QEMUIOVector *qiov, int nb_sectors,
309
                BlockDriverCompletionFunc *cb,
310
                void *opaque)
311
{
312
    IscsiLun *iscsilun = bs->opaque;
313
    struct iscsi_context *iscsi = iscsilun->iscsi;
314
    IscsiAIOCB *acb;
315
    size_t qemu_read_size;
316
    int i;
317
    uint64_t lba;
318
    uint32_t num_sectors;
319

    
320
    qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;
321

    
322
    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
323
    trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);
324

    
325
    acb->iscsilun = iscsilun;
326
    acb->qiov     = qiov;
327

    
328
    acb->canceled    = 0;
329
    acb->bh          = NULL;
330
    acb->status      = -EINPROGRESS;
331
    acb->read_size   = qemu_read_size;
332
    acb->buf         = NULL;
333

    
334
    /* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU
335
     * may be misaligned to the LUN, so we may need to read some extra
336
     * data.
337
     */
338
    acb->read_offset = 0;
339
    if (iscsilun->block_size > BDRV_SECTOR_SIZE) {
340
        uint64_t bdrv_offset = BDRV_SECTOR_SIZE * sector_num;
341

    
342
        acb->read_offset  = bdrv_offset % iscsilun->block_size;
343
    }
344

    
345
    num_sectors  = (qemu_read_size + iscsilun->block_size
346
                    + acb->read_offset - 1)
347
                    / iscsilun->block_size;
348

    
349
    acb->task = malloc(sizeof(struct scsi_task));
350
    if (acb->task == NULL) {
351
        error_report("iSCSI: Failed to allocate task for scsi READ16 "
352
                     "command. %s", iscsi_get_error(iscsi));
353
        qemu_aio_release(acb);
354
        return NULL;
355
    }
356
    memset(acb->task, 0, sizeof(struct scsi_task));
357

    
358
    acb->task->xfer_dir = SCSI_XFER_READ;
359
    lba = sector_qemu2lun(sector_num, iscsilun);
360
    acb->task->expxferlen = qemu_read_size;
361

    
362
    switch (iscsilun->type) {
363
    case TYPE_DISK:
364
        acb->task->cdb_size = 16;
365
        acb->task->cdb[0]  = 0x88;
366
        *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
367
        *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
368
        *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);
369
        break;
370
    default:
371
        acb->task->cdb_size = 10;
372
        acb->task->cdb[0]  = 0x28;
373
        *(uint32_t *)&acb->task->cdb[2] = htonl(lba);
374
        *(uint16_t *)&acb->task->cdb[7] = htons(num_sectors);
375
        break;
376
    }
377

    
378
    if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
379
                                 iscsi_aio_read16_cb,
380
                                 NULL,
381
                                 acb) != 0) {
382
        scsi_free_scsi_task(acb->task);
383
        qemu_aio_release(acb);
384
        return NULL;
385
    }
386

    
387
    for (i = 0; i < acb->qiov->niov; i++) {
388
        scsi_task_add_data_in_buffer(acb->task,
389
                acb->qiov->iov[i].iov_len,
390
                acb->qiov->iov[i].iov_base);
391
    }
392

    
393
    iscsi_set_events(iscsilun);
394

    
395
    return &acb->common;
396
}
397

    
398

    
399
static void
400
iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
401
                     void *command_data, void *opaque)
402
{
403
    IscsiAIOCB *acb = opaque;
404

    
405
    if (acb->canceled != 0) {
406
        return;
407
    }
408

    
409
    acb->status = 0;
410
    if (status < 0) {
411
        error_report("Failed to sync10 data on iSCSI lun. %s",
412
                     iscsi_get_error(iscsi));
413
        acb->status = -EIO;
414
    }
415

    
416
    iscsi_schedule_bh(acb);
417
}
418

    
419
static BlockDriverAIOCB *
420
iscsi_aio_flush(BlockDriverState *bs,
421
                BlockDriverCompletionFunc *cb, void *opaque)
422
{
423
    IscsiLun *iscsilun = bs->opaque;
424
    struct iscsi_context *iscsi = iscsilun->iscsi;
425
    IscsiAIOCB *acb;
426

    
427
    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
428

    
429
    acb->iscsilun = iscsilun;
430
    acb->canceled   = 0;
431
    acb->bh         = NULL;
432
    acb->status     = -EINPROGRESS;
433

    
434
    acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
435
                                         0, 0, 0, 0,
436
                                         iscsi_synccache10_cb,
437
                                         acb);
438
    if (acb->task == NULL) {
439
        error_report("iSCSI: Failed to send synchronizecache10 command. %s",
440
                     iscsi_get_error(iscsi));
441
        qemu_aio_release(acb);
442
        return NULL;
443
    }
444

    
445
    iscsi_set_events(iscsilun);
446

    
447
    return &acb->common;
448
}
449

    
450
static void
451
iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
452
                     void *command_data, void *opaque)
453
{
454
    IscsiAIOCB *acb = opaque;
455

    
456
    if (acb->canceled != 0) {
457
        return;
458
    }
459

    
460
    acb->status = 0;
461
    if (status < 0) {
462
        error_report("Failed to unmap data on iSCSI lun. %s",
463
                     iscsi_get_error(iscsi));
464
        acb->status = -EIO;
465
    }
466

    
467
    iscsi_schedule_bh(acb);
468
}
469

    
470
static BlockDriverAIOCB *
471
iscsi_aio_discard(BlockDriverState *bs,
472
                  int64_t sector_num, int nb_sectors,
473
                  BlockDriverCompletionFunc *cb, void *opaque)
474
{
475
    IscsiLun *iscsilun = bs->opaque;
476
    struct iscsi_context *iscsi = iscsilun->iscsi;
477
    IscsiAIOCB *acb;
478
    struct unmap_list list[1];
479

    
480
    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
481

    
482
    acb->iscsilun = iscsilun;
483
    acb->canceled   = 0;
484
    acb->bh         = NULL;
485
    acb->status     = -EINPROGRESS;
486

    
487
    list[0].lba = sector_qemu2lun(sector_num, iscsilun);
488
    list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
489

    
490
    acb->task = iscsi_unmap_task(iscsi, iscsilun->lun,
491
                                 0, 0, &list[0], 1,
492
                                 iscsi_unmap_cb,
493
                                 acb);
494
    if (acb->task == NULL) {
495
        error_report("iSCSI: Failed to send unmap command. %s",
496
                     iscsi_get_error(iscsi));
497
        qemu_aio_release(acb);
498
        return NULL;
499
    }
500

    
501
    iscsi_set_events(iscsilun);
502

    
503
    return &acb->common;
504
}
505

    
506
#ifdef __linux__
507
static void
508
iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
509
                     void *command_data, void *opaque)
510
{
511
    IscsiAIOCB *acb = opaque;
512

    
513
    if (acb->canceled != 0) {
514
        return;
515
    }
516

    
517
    acb->status = 0;
518
    if (status < 0) {
519
        error_report("Failed to ioctl(SG_IO) to iSCSI lun. %s",
520
                     iscsi_get_error(iscsi));
521
        acb->status = -EIO;
522
    }
523

    
524
    acb->ioh->driver_status = 0;
525
    acb->ioh->host_status   = 0;
526
    acb->ioh->resid         = 0;
527

    
528
#define SG_ERR_DRIVER_SENSE    0x08
529

    
530
    if (status == SCSI_STATUS_CHECK_CONDITION && acb->task->datain.size >= 2) {
531
        int ss;
532

    
533
        acb->ioh->driver_status |= SG_ERR_DRIVER_SENSE;
534

    
535
        acb->ioh->sb_len_wr = acb->task->datain.size - 2;
536
        ss = (acb->ioh->mx_sb_len >= acb->ioh->sb_len_wr) ?
537
             acb->ioh->mx_sb_len : acb->ioh->sb_len_wr;
538
        memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
539
    }
540

    
541
    iscsi_schedule_bh(acb);
542
}
543

    
544
static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
545
        unsigned long int req, void *buf,
546
        BlockDriverCompletionFunc *cb, void *opaque)
547
{
548
    IscsiLun *iscsilun = bs->opaque;
549
    struct iscsi_context *iscsi = iscsilun->iscsi;
550
    struct iscsi_data data;
551
    IscsiAIOCB *acb;
552

    
553
    assert(req == SG_IO);
554

    
555
    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
556

    
557
    acb->iscsilun = iscsilun;
558
    acb->canceled    = 0;
559
    acb->bh          = NULL;
560
    acb->status      = -EINPROGRESS;
561
    acb->buf         = NULL;
562
    acb->ioh         = buf;
563

    
564
    acb->task = malloc(sizeof(struct scsi_task));
565
    if (acb->task == NULL) {
566
        error_report("iSCSI: Failed to allocate task for scsi command. %s",
567
                     iscsi_get_error(iscsi));
568
        qemu_aio_release(acb);
569
        return NULL;
570
    }
571
    memset(acb->task, 0, sizeof(struct scsi_task));
572

    
573
    switch (acb->ioh->dxfer_direction) {
574
    case SG_DXFER_TO_DEV:
575
        acb->task->xfer_dir = SCSI_XFER_WRITE;
576
        break;
577
    case SG_DXFER_FROM_DEV:
578
        acb->task->xfer_dir = SCSI_XFER_READ;
579
        break;
580
    default:
581
        acb->task->xfer_dir = SCSI_XFER_NONE;
582
        break;
583
    }
584

    
585
    acb->task->cdb_size = acb->ioh->cmd_len;
586
    memcpy(&acb->task->cdb[0], acb->ioh->cmdp, acb->ioh->cmd_len);
587
    acb->task->expxferlen = acb->ioh->dxfer_len;
588

    
589
    if (acb->task->xfer_dir == SCSI_XFER_WRITE) {
590
        data.data = acb->ioh->dxferp;
591
        data.size = acb->ioh->dxfer_len;
592
    }
593
    if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,
594
                                 iscsi_aio_ioctl_cb,
595
                                 (acb->task->xfer_dir == SCSI_XFER_WRITE) ?
596
                                     &data : NULL,
597
                                 acb) != 0) {
598
        scsi_free_scsi_task(acb->task);
599
        qemu_aio_release(acb);
600
        return NULL;
601
    }
602

    
603
    /* tell libiscsi to read straight into the buffer we got from ioctl */
604
    if (acb->task->xfer_dir == SCSI_XFER_READ) {
605
        scsi_task_add_data_in_buffer(acb->task,
606
                                     acb->ioh->dxfer_len,
607
                                     acb->ioh->dxferp);
608
    }
609

    
610
    iscsi_set_events(iscsilun);
611

    
612
    return &acb->common;
613
}
614

    
615

    
616
static void ioctl_cb(void *opaque, int status)
617
{
618
    int *p_status = opaque;
619
    *p_status = status;
620
}
621

    
622
static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
623
{
624
    IscsiLun *iscsilun = bs->opaque;
625
    int status;
626

    
627
    switch (req) {
628
    case SG_GET_VERSION_NUM:
629
        *(int *)buf = 30000;
630
        break;
631
    case SG_GET_SCSI_ID:
632
        ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
633
        break;
634
    case SG_IO:
635
        status = -EINPROGRESS;
636
        iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
637

    
638
        while (status == -EINPROGRESS) {
639
            qemu_aio_wait();
640
        }
641

    
642
        return 0;
643
    default:
644
        return -1;
645
    }
646
    return 0;
647
}
648
#endif
649

    
650
static int64_t
651
iscsi_getlength(BlockDriverState *bs)
652
{
653
    IscsiLun *iscsilun = bs->opaque;
654
    int64_t len;
655

    
656
    len  = iscsilun->num_blocks;
657
    len *= iscsilun->block_size;
658

    
659
    return len;
660
}
661

    
662
static int parse_chap(struct iscsi_context *iscsi, const char *target)
663
{
664
    QemuOptsList *list;
665
    QemuOpts *opts;
666
    const char *user = NULL;
667
    const char *password = NULL;
668

    
669
    list = qemu_find_opts("iscsi");
670
    if (!list) {
671
        return 0;
672
    }
673

    
674
    opts = qemu_opts_find(list, target);
675
    if (opts == NULL) {
676
        opts = QTAILQ_FIRST(&list->head);
677
        if (!opts) {
678
            return 0;
679
        }
680
    }
681

    
682
    user = qemu_opt_get(opts, "user");
683
    if (!user) {
684
        return 0;
685
    }
686

    
687
    password = qemu_opt_get(opts, "password");
688
    if (!password) {
689
        error_report("CHAP username specified but no password was given");
690
        return -1;
691
    }
692

    
693
    if (iscsi_set_initiator_username_pwd(iscsi, user, password)) {
694
        error_report("Failed to set initiator username and password");
695
        return -1;
696
    }
697

    
698
    return 0;
699
}
700

    
701
static void parse_header_digest(struct iscsi_context *iscsi, const char *target)
702
{
703
    QemuOptsList *list;
704
    QemuOpts *opts;
705
    const char *digest = NULL;
706

    
707
    list = qemu_find_opts("iscsi");
708
    if (!list) {
709
        return;
710
    }
711

    
712
    opts = qemu_opts_find(list, target);
713
    if (opts == NULL) {
714
        opts = QTAILQ_FIRST(&list->head);
715
        if (!opts) {
716
            return;
717
        }
718
    }
719

    
720
    digest = qemu_opt_get(opts, "header-digest");
721
    if (!digest) {
722
        return;
723
    }
724

    
725
    if (!strcmp(digest, "CRC32C")) {
726
        iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C);
727
    } else if (!strcmp(digest, "NONE")) {
728
        iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE);
729
    } else if (!strcmp(digest, "CRC32C-NONE")) {
730
        iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_CRC32C_NONE);
731
    } else if (!strcmp(digest, "NONE-CRC32C")) {
732
        iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
733
    } else {
734
        error_report("Invalid header-digest setting : %s", digest);
735
    }
736
}
737

    
738
static char *parse_initiator_name(const char *target)
739
{
740
    QemuOptsList *list;
741
    QemuOpts *opts;
742
    const char *name = NULL;
743
    const char *iscsi_name = qemu_get_vm_name();
744

    
745
    list = qemu_find_opts("iscsi");
746
    if (list) {
747
        opts = qemu_opts_find(list, target);
748
        if (!opts) {
749
            opts = QTAILQ_FIRST(&list->head);
750
        }
751
        if (opts) {
752
            name = qemu_opt_get(opts, "initiator-name");
753
        }
754
    }
755

    
756
    if (name) {
757
        return g_strdup(name);
758
    } else {
759
        return g_strdup_printf("iqn.2008-11.org.linux-kvm%s%s",
760
                               iscsi_name ? ":" : "",
761
                               iscsi_name ? iscsi_name : "");
762
    }
763
}
764

    
765
/*
766
 * We support iscsi url's on the form
767
 * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
768
 */
769
static int iscsi_open(BlockDriverState *bs, const char *filename, int flags)
770
{
771
    IscsiLun *iscsilun = bs->opaque;
772
    struct iscsi_context *iscsi = NULL;
773
    struct iscsi_url *iscsi_url = NULL;
774
    struct scsi_task *task = NULL;
775
    struct scsi_inquiry_standard *inq = NULL;
776
    struct scsi_readcapacity10 *rc10 = NULL;
777
    struct scsi_readcapacity16 *rc16 = NULL;
778
    char *initiator_name = NULL;
779
    int ret;
780

    
781
    if ((BDRV_SECTOR_SIZE % 512) != 0) {
782
        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "
783
                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "
784
                     "of 512", BDRV_SECTOR_SIZE);
785
        return -EINVAL;
786
    }
787

    
788
    iscsi_url = iscsi_parse_full_url(iscsi, filename);
789
    if (iscsi_url == NULL) {
790
        error_report("Failed to parse URL : %s", filename);
791
        ret = -EINVAL;
792
        goto out;
793
    }
794

    
795
    memset(iscsilun, 0, sizeof(IscsiLun));
796

    
797
    initiator_name = parse_initiator_name(iscsi_url->target);
798

    
799
    iscsi = iscsi_create_context(initiator_name);
800
    if (iscsi == NULL) {
801
        error_report("iSCSI: Failed to create iSCSI context.");
802
        ret = -ENOMEM;
803
        goto out;
804
    }
805

    
806
    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {
807
        error_report("iSCSI: Failed to set target name.");
808
        ret = -EINVAL;
809
        goto out;
810
    }
811

    
812
    if (iscsi_url->user != NULL) {
813
        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,
814
                                              iscsi_url->passwd);
815
        if (ret != 0) {
816
            error_report("Failed to set initiator username and password");
817
            ret = -EINVAL;
818
            goto out;
819
        }
820
    }
821

    
822
    /* check if we got CHAP username/password via the options */
823
    if (parse_chap(iscsi, iscsi_url->target) != 0) {
824
        error_report("iSCSI: Failed to set CHAP user/password");
825
        ret = -EINVAL;
826
        goto out;
827
    }
828

    
829
    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {
830
        error_report("iSCSI: Failed to set session type to normal.");
831
        ret = -EINVAL;
832
        goto out;
833
    }
834

    
835
    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
836

    
837
    /* check if we got HEADER_DIGEST via the options */
838
    parse_header_digest(iscsi, iscsi_url->target);
839

    
840
    if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
841
        error_report("iSCSI: Failed to connect to LUN : %s",
842
            iscsi_get_error(iscsi));
843
        ret = -EINVAL;
844
        goto out;
845
    }
846

    
847
    iscsilun->iscsi = iscsi;
848
    iscsilun->lun   = iscsi_url->lun;
849

    
850
    task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
851

    
852
    if (task == NULL || task->status != SCSI_STATUS_GOOD) {
853
        error_report("iSCSI: failed to send inquiry command.");
854
        ret = -EINVAL;
855
        goto out;
856
    }
857

    
858
    inq = scsi_datain_unmarshall(task);
859
    if (inq == NULL) {
860
        error_report("iSCSI: Failed to unmarshall inquiry data.");
861
        ret = -EINVAL;
862
        goto out;
863
    }
864

    
865
    iscsilun->type = inq->periperal_device_type;
866

    
867
    scsi_free_scsi_task(task);
868

    
869
    switch (iscsilun->type) {
870
    case TYPE_DISK:
871
        task = iscsi_readcapacity16_sync(iscsi, iscsilun->lun);
872
        if (task == NULL || task->status != SCSI_STATUS_GOOD) {
873
            error_report("iSCSI: failed to send readcapacity16 command.");
874
            ret = -EINVAL;
875
            goto out;
876
        }
877
        rc16 = scsi_datain_unmarshall(task);
878
        if (rc16 == NULL) {
879
            error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
880
            ret = -EINVAL;
881
            goto out;
882
        }
883
        iscsilun->block_size = rc16->block_length;
884
        iscsilun->num_blocks = rc16->returned_lba + 1;
885
        break;
886
    case TYPE_ROM:
887
        task = iscsi_readcapacity10_sync(iscsi, iscsilun->lun, 0, 0);
888
        if (task == NULL || task->status != SCSI_STATUS_GOOD) {
889
            error_report("iSCSI: failed to send readcapacity10 command.");
890
            ret = -EINVAL;
891
            goto out;
892
        }
893
        rc10 = scsi_datain_unmarshall(task);
894
        if (rc10 == NULL) {
895
            error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
896
            ret = -EINVAL;
897
            goto out;
898
        }
899
        iscsilun->block_size = rc10->block_size;
900
        if (rc10->lba == 0) {
901
            /* blank disk loaded */
902
            iscsilun->num_blocks = 0;
903
        } else {
904
            iscsilun->num_blocks = rc10->lba + 1;
905
        }
906
        break;
907
    default:
908
        break;
909
    }
910

    
911
    bs->total_sectors    = iscsilun->num_blocks *
912
                           iscsilun->block_size / BDRV_SECTOR_SIZE ;
913

    
914
    /* Medium changer or tape. We dont have any emulation for this so this must
915
     * be sg ioctl compatible. We force it to be sg, otherwise qemu will try
916
     * to read from the device to guess the image format.
917
     */
918
    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||
919
        iscsilun->type == TYPE_TAPE) {
920
        bs->sg = 1;
921
    }
922

    
923
    ret = 0;
924

    
925
out:
926
    if (initiator_name != NULL) {
927
        g_free(initiator_name);
928
    }
929
    if (iscsi_url != NULL) {
930
        iscsi_destroy_url(iscsi_url);
931
    }
932
    if (task != NULL) {
933
        scsi_free_scsi_task(task);
934
    }
935

    
936
    if (ret) {
937
        if (iscsi != NULL) {
938
            iscsi_destroy_context(iscsi);
939
        }
940
        memset(iscsilun, 0, sizeof(IscsiLun));
941
    }
942
    return ret;
943
}
944

    
945
static void iscsi_close(BlockDriverState *bs)
946
{
947
    IscsiLun *iscsilun = bs->opaque;
948
    struct iscsi_context *iscsi = iscsilun->iscsi;
949

    
950
    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
951
    iscsi_destroy_context(iscsi);
952
    memset(iscsilun, 0, sizeof(IscsiLun));
953
}
954

    
955
static int iscsi_has_zero_init(BlockDriverState *bs)
956
{
957
    return 0;
958
}
959

    
960
static BlockDriver bdrv_iscsi = {
961
    .format_name     = "iscsi",
962
    .protocol_name   = "iscsi",
963

    
964
    .instance_size   = sizeof(IscsiLun),
965
    .bdrv_file_open  = iscsi_open,
966
    .bdrv_close      = iscsi_close,
967

    
968
    .bdrv_getlength  = iscsi_getlength,
969

    
970
    .bdrv_aio_readv  = iscsi_aio_readv,
971
    .bdrv_aio_writev = iscsi_aio_writev,
972
    .bdrv_aio_flush  = iscsi_aio_flush,
973

    
974
    .bdrv_aio_discard = iscsi_aio_discard,
975
    .bdrv_has_zero_init = iscsi_has_zero_init,
976

    
977
#ifdef __linux__
978
    .bdrv_ioctl       = iscsi_ioctl,
979
    .bdrv_aio_ioctl   = iscsi_aio_ioctl,
980
#endif
981
};
982

    
983
static void iscsi_block_init(void)
984
{
985
    bdrv_register(&bdrv_iscsi);
986
}
987

    
988
block_init(iscsi_block_init);