Each iSCSI target can provide multiple logical units. Support this
with an additional attribute in the <source> element.
libiscsi places the LUN in the path component of the URI. iSCSI
names cannot contain slashes, so this is unambiguous
Signed-off-by: Paolo Bonzini <pbonzini(a)redhat.com>
---
docs/formatdomain.html.in | 9 ++++---
docs/schemas/domaincommon.rng | 29 +++++++++++++++-------
src/conf/domain_conf.c | 12 +++++++++
src/conf/domain_conf.h | 2 ++
src/qemu/qemu_command.c | 23 +++++++++++++----
.../qemuxml2argv-disk-drive-network-iscsi.args | 2 +-
.../qemuxml2argv-disk-drive-network-iscsi.xml | 7 ++++++
7 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index fd6d5ae..5b4eabe 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1441,10 +1441,11 @@
are "nbd", "iscsi", "rbd", "sheepdog" or
"gluster". If the
<code>protocol</code> attribute is "rbd",
"sheepdog" or "gluster", an
additional attribute <code>name</code> is mandatory to specify which
- volume/image will be used; for "nbd" it is optional. When the disk
- <code>type</code> is "network", the
<code>source</code> may have zero
- or more <code>host</code> sub-elements used to specify the hosts
- to connect.
+ volume/image will be used; for "nbd" it is optional. "iscsi"
supports
+ an additional numeric attribute <code>unit</code> for the logical
unit
+ number (default 0). When the disk <code>type</code> is
"network",
+ the <code>source</code> may have zero or more
<code>host</code>
+ sub-elements used to specify the hosts to connect.
<span class="since">Since 0.0.3;
<code>type='dir'</code> since
0.7.5; <code>type='network'</code> since
0.8.7</span><br/>
For a "file" disk type which represents a cdrom or floppy
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 980410f..82062a3 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1078,15 +1078,26 @@
<interleave>
<optional>
<element name="source">
- <attribute name="protocol">
- <choice>
- <value>nbd</value>
- <value>rbd</value>
- <value>sheepdog</value>
- <value>gluster</value>
- <value>iscsi</value>
- </choice>
- </attribute>
+ <choice>
+ <attribute name="protocol">
+ <choice>
+ <value>nbd</value>
+ <value>rbd</value>
+ <value>sheepdog</value>
+ <value>gluster</value>
+ </choice>
+ </attribute>
+ <group>
+ <attribute name="protocol">
+ <value>iscsi</value>
+ </attribute>
+ <optional>
+ <attribute name="unit">
+ <data type="integer"/>
+ </attribute>
+ </optional>
+ </group>
+ </choice>
<optional>
<attribute name="name"/>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b42c79c..b801239 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3950,6 +3950,15 @@ virDomainDiskDefParseXML(virCapsPtr caps,
protocol);
goto error;
}
+ if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI) {
+ if (virXMLPropString(cur, "unit") &&
+ virXPathUInt("string(./source/@unit)",
+ ctxt, &def->unit) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid logical unit number"));
+ goto error;
+ }
+ }
if (!(source = virXMLPropString(cur, "name")) &&
def->protocol != VIR_DOMAIN_DISK_PROTOCOL_NBD) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -12555,6 +12564,9 @@ virDomainDiskDefFormat(virBufferPtr buf,
if (def->src) {
virBufferEscapeString(buf, " name='%s'", def->src);
}
+ if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI &&
def->unit) {
+ virBufferAsprintf(buf, " unit='%u'", def->unit);
+ }
if (def->nhosts == 0) {
virBufferAddLit(buf, "/>\n");
} else {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7cd0264..ac8a446 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -606,6 +606,8 @@ struct _virDomainDiskDef {
int device;
int bus;
char *src;
+ unsigned unit;
+
char *dst;
int tray_status;
int protocol;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 07700cc..59773ec 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2148,14 +2148,19 @@ static int
qemuParseISCSIString(virDomainDiskDefPtr def)
{
virURIPtr uri = NULL;
+ char *p;
if (!(uri = virURIParse(def->src)))
return -1;
- if (uri->path && strchr(uri->path + 1, '/')) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid address for iSCSI target"), disk->src);
- return -1;
+ p = uri->path ? strchr(uri->path + 1, '/') : NULL;
+ if (p) {
+ *p++ = '\0';
+ if (virStrToLong_ui(p, NULL, 10, &def->unit) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse iSCSI LUN '%s'"), p);
+ return -1;
+ }
}
return qemuParseDriveURIString(def, uri, "iscsi");
@@ -2308,7 +2313,15 @@ qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt)
static int
qemuBuildISCSIString(virDomainDiskDefPtr disk, virBufferPtr opt)
{
- return qemuBuildDriveURIString(disk, opt, "iscsi");
+ int ret;
+ ret = qemuBuildDriveURIString(disk, opt, "iscsi");
+ if (ret < 0)
+ return ret;
+
+ if (disk->unit) {
+ virBufferAsprintf(opt, "/%u", disk->unit);
+ }
+ return 0;
}
static int
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
index ed4f337..b8bc9c6 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214
-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb
-drive file=iscsi://example.org:6000/iqn.1992-01.com.example,if=virtio,format=raw -net
none -serial none -parallel none
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214
-smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb
-drive file=iscsi://example.org:6000/iqn.1992-01.com.example,if=virtio,format=raw -drive
file=iscsi://example.org:6000/iqn.1992-01.com.example/1,if=virtio,format=raw -net none
-serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
index dd85032..dfa60f3 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
@@ -21,6 +21,13 @@
</source>
<target dev='vda' bus='virtio'/>
</disk>
+ <disk type='network' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='iscsi' name='iqn.1992-01.com.example'
unit='1'>
+ <host name='example.org' port='6000'/>
+ </source>
+ <target dev='vdb' bus='virtio'/>
+ </disk>
<controller type='usb' index='0'/>
<memballoon model='virtio'/>
</devices>
--
1.8.1.2