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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list