[libvirt] [PATCH 09/13] qemu: support LUN numbers for iSCSI disks

Paolo Bonzini pbonzini at redhat.com
Mon Feb 25 17:44:28 UTC 2013


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 at 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





More information about the libvir-list mailing list