#include "qemu/error-report.h"
#include "block/block_int.h"
#include "trace.h"
-#include "hw/scsi-defs.h"
+#include "block/scsi.h"
#include <iscsi/iscsi.h>
#include <iscsi/scsi-lowlevel.h>
#ifdef __linux__
#include <scsi/sg.h>
-#include <hw/scsi-defs.h>
+#include <block/scsi.h>
#endif
typedef struct IscsiLun {
if (status == SCSI_STATUS_CHECK_CONDITION
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& acb->retries-- > 0) {
- if (acb->task != NULL) {
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
- }
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
if (iscsi_aio_writev_acb(acb) == 0) {
iscsi_set_events(acb->iscsilun);
return;
acb);
#endif
if (ret != 0) {
+ scsi_free_scsi_task(acb->task);
g_free(acb->buf);
return -1;
}
acb->retries = ISCSI_CMD_RETRIES;
if (iscsi_aio_writev_acb(acb) != 0) {
- if (acb->task) {
- scsi_free_scsi_task(acb->task);
- }
qemu_aio_release(acb);
return NULL;
}
if (status == SCSI_STATUS_CHECK_CONDITION
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& acb->retries-- > 0) {
- if (acb->task != NULL) {
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
- }
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
if (iscsi_aio_readv_acb(acb) == 0) {
iscsi_set_events(acb->iscsilun);
return;
NULL,
acb);
if (ret != 0) {
+ scsi_free_scsi_task(acb->task);
return -1;
}
acb->retries = ISCSI_CMD_RETRIES;
if (iscsi_aio_readv_acb(acb) != 0) {
- if (acb->task) {
- scsi_free_scsi_task(acb->task);
- }
qemu_aio_release(acb);
return NULL;
}
if (status == SCSI_STATUS_CHECK_CONDITION
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& acb->retries-- > 0) {
- if (acb->task != NULL) {
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
- }
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
if (iscsi_aio_flush_acb(acb) == 0) {
iscsi_set_events(acb->iscsilun);
return;
if (status == SCSI_STATUS_CHECK_CONDITION
&& acb->task->sense.key == SCSI_SENSE_UNIT_ATTENTION
&& acb->retries-- > 0) {
- if (acb->task != NULL) {
- scsi_free_scsi_task(acb->task);
- acb->task = NULL;
- }
+ scsi_free_scsi_task(acb->task);
+ acb->task = NULL;
if (iscsi_aio_discard_acb(acb) == 0) {
iscsi_set_events(acb->iscsilun);
return;
acb->retries = ISCSI_CMD_RETRIES;
if (iscsi_aio_discard_acb(acb) != 0) {
- if (acb->task) {
- scsi_free_scsi_task(acb->task);
- }
qemu_aio_release(acb);
return NULL;
}
return ret;
}
+/* TODO Convert to fine grained options */
+static QemuOptsList runtime_opts = {
+ .name = "iscsi",
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
+ .desc = {
+ {
+ .name = "filename",
+ .type = QEMU_OPT_STRING,
+ .help = "URL to the iscsi image",
+ },
+ { /* end of list */ }
+ },
+};
+
/*
* We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
*/
-static int iscsi_open(BlockDriverState *bs, const char *filename,
- QDict *options, int flags)
+static int iscsi_open(BlockDriverState *bs, QDict *options, int flags)
{
IscsiLun *iscsilun = bs->opaque;
struct iscsi_context *iscsi = NULL;
struct scsi_task *task = NULL;
struct scsi_inquiry_standard *inq = NULL;
char *initiator_name = NULL;
+ QemuOpts *opts;
+ Error *local_err = NULL;
+ const char *filename;
int ret;
if ((BDRV_SECTOR_SIZE % 512) != 0) {
return -EINVAL;
}
+ opts = qemu_opts_create_nofail(&runtime_opts);
+ qemu_opts_absorb_qdict(opts, options, &local_err);
+ if (error_is_set(&local_err)) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ filename = qemu_opt_get(opts, "filename");
+
+
iscsi_url = iscsi_parse_full_url(iscsi, filename);
if (iscsi_url == NULL) {
error_report("Failed to parse URL : %s", filename);
#endif
out:
+ qemu_opts_del(opts);
if (initiator_name != NULL) {
g_free(initiator_name);
}
int64_t total_size = 0;
BlockDriverState bs;
IscsiLun *iscsilun = NULL;
+ QDict *bs_options;
memset(&bs, 0, sizeof(BlockDriverState));
bs.opaque = g_malloc0(sizeof(struct IscsiLun));
iscsilun = bs.opaque;
- ret = iscsi_open(&bs, filename, NULL, 0);
+ bs_options = qdict_new();
+ qdict_put(bs_options, "filename", qstring_from_str(filename));
+ ret = iscsi_open(&bs, bs_options, 0);
+ QDECREF(bs_options);
+
if (ret != 0) {
goto out;
}