@@ -1199,7 +1199,7 @@ retry:
}
/* Look up the -iscsi command-line option */
-static QemuOpts *find_iscsi_opts(const char *id)
+static QemuOpts *find_iscsi_opts(const char *id, bool default_to_first)
{
QemuOptsList *list;
QemuOpts *opts;
@@ -1210,13 +1210,9 @@ static QemuOpts *find_iscsi_opts(const char *id)
}
opts = qemu_opts_find(list, id);
- if (opts == NULL) {
+ if (opts == NULL && default_to_first) {
opts = QTAILQ_FIRST(&list->head);
- if (!opts) {
- return NULL;
- }
}
-
return opts;
}
@@ -1411,6 +1407,11 @@ static QemuOptsList runtime_opts = {
.type = QEMU_OPT_STRING,
.help = "URL to the iscsi image",
},
+ {
+ .name = "iscsi",
+ .type = QEMU_OPT_STRING,
+ .help = "id of iscsi object",
+ },
{ /* end of list */ }
},
};
@@ -1550,6 +1551,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
QemuOpts *iscsi_opts;
Error *local_err = NULL;
const char *filename;
+ const char *iscsi_opts_id;
int i, ret = 0, timeout = 0;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
@@ -1571,7 +1573,12 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
memset(iscsilun, 0, sizeof(IscsiLun));
- iscsi_opts = find_iscsi_opts(iscsi_url->target);
+ iscsi_opts_id = qemu_opt_get(opts, "iscsi");
+ if (iscsi_opts_id) {
+ iscsi_opts = find_iscsi_opts(iscsi_opts_id, false);
+ } else {
+ iscsi_opts = find_iscsi_opts(iscsi_url->target, true);
+ }
initiator_name = parse_initiator_name(iscsi_opts);
@@ -2515,14 +2515,18 @@ LIBISCSI_CHAP_PASSWORD="password" \
qemu-system-i386 -drive file=iscsi://192.0.2.1/iqn.2001-04.com.example/1
@end example
+An iSCSI drive is associated with an -iscsi option as follows. If -drive
+...,iscsi=<iscsi-id> is present then the -iscsi option with that id is used.
+Otherwise an -iscsi option whose id matches the drive's target IQN is searched
+and if the search fails the first -iscsi option is used.
+
iSCSI support is an optional feature of QEMU and only available when
compiled and linked against libiscsi.
ETEXI
DEF("iscsi", HAS_ARG, QEMU_OPTION_iscsi,
"-iscsi [user=user][,password=password]\n"
" [,header-digest=CRC32C|CR32C-NONE|NONE-CRC32C|NONE\n"
- " [,initiator-name=initiator-iqn][,id=target-iqn]\n"
- " [,timeout=timeout]\n"
+ " [,initiator-name=initiator-iqn][,id=id][,timeout=timeout]\n"
" iSCSI session parameters\n", QEMU_ARCH_ALL)
STEXI
An iSCSI block driver instance is implicitly matched with an -iscsi object that has id=<target-iqn>. If no -iscsi object with that id exists then the first -iscsi object is used. This patch adds a -drive ...,iscsi=<iscsi-id> option so the relationship between the block driver instance and an -iscsi object can be specified explicitly. When the iscsi=<iscsi-id> parameter is used there is no fallback to the first -iscsi option (which is weird legacy behavior). This makes it possible to connect to multiple LUNs on the same target with different credentials whereas previously the same -iscsi object would be associated with all block driver instances for that iSCSI target. Example: $ qemu-system-x86_64 -iscsi id=test,user=foo,password=x,\ initiator-name=iqn.2001-04.com.example:my-initiator \ -drive driver=iscsi,filename=iscsi://127.0.0.1/iqn.2003-01.org.linux-iscsi.test.x8664:sn.d964cc832811/0,iscsi=test Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- block/iscsi.c | 21 ++++++++++++++------- qemu-options.hx | 8 ++++++-- 2 files changed, 20 insertions(+), 9 deletions(-)