Statistics
| Branch: | Revision:

root / block / iscsi.c @ 0834c9ea

History | View | Annotate | Download (28.8 kB)

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