]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: add support for libiscsi
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 21 Mar 2013 11:53:49 +0000 (12:53 +0100)
committerOsier Yang <jyang@redhat.com>
Fri, 22 Mar 2013 04:10:22 +0000 (12:10 +0800)
libiscsi provides a userspace iSCSI initiator.

The main advantage over the kernel initiator is that it is very
easy to provide different initiator names for VMs on the same host.
Thus libiscsi supports usage of persistent reservations in the VM,
which otherwise would only be possible with NPIV.

libiscsi uses "iscsi" as the scheme, not "iscsi+tcp".  We can change
this in the tests (while remaining backwards-compatible manner, because
QEMU uses TCP as the default transport for both Gluster and NBD).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
docs/formatdomain.html.in
src/qemu/qemu_command.c
tests/qemuargv2xmltest.c
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-gluster.args
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args
tests/qemuxml2argvtest.c

index e4ed3f7f35d865360c43fafaebb1b1cf84b17db4..f17b808e9bff6c40917fd8770e370f345894a62a 100644 (file)
         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.  For "iscsi",
+        the <code>name</code> attribute may include a logical unit number,
+        separated from the target's name by a slash (for example,
+        <code>iqn.1992-01.com.example/1</code>); the default LUN is zero.
+        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; <code>protocol='iscsi'</code> since 1.0.4</span><br/>
index 8626b629b91d6a591ce86d06dc958e427d3a92c9..4774650d825471ade79fa808219df774fe47514e 100644 (file)
@@ -2390,6 +2390,31 @@ qemuParseGlusterString(virDomainDiskDefPtr def)
     return qemuParseDriveURIString(def, uri, "gluster");
 }
 
+static int
+qemuParseISCSIString(virDomainDiskDefPtr def)
+{
+    virURIPtr uri = NULL;
+    char *slash;
+    unsigned lun;
+
+    if (!(uri = virURIParse(def->src)))
+        return -1;
+
+    if (uri->path &&
+        (slash = strchr(uri->path + 1, '/')) != NULL) {
+
+        if (slash[1] == '\0')
+            *slash = '\0';
+        else if (virStrToLong_ui(slash + 1, NULL, 10, &lun) == -1) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("invalid name '%s' for iSCSI disk"), def->src);
+            return -1;
+        }
+    }
+
+    return qemuParseDriveURIString(def, uri, "iscsi");
+}
+
 static int
 qemuParseNBDString(virDomainDiskDefPtr disk)
 {
@@ -2484,8 +2509,14 @@ qemuBuildDriveURIString(virDomainDiskDefPtr disk, virBufferPtr opt,
     virBufferAddLit(opt, "file=");
     transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
 
-    if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0)
-        goto no_memory;
+    if (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
+        tmpscheme = strdup(scheme);
+        if (tmpscheme == NULL)
+            goto no_memory;
+    } else {
+        if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0)
+            goto no_memory;
+    }
 
     if (disk->src && virAsprintf(&volimg, "/%s", disk->src) < 0)
         goto no_memory;
@@ -2530,6 +2561,12 @@ qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt)
 
 #define QEMU_DEFAULT_NBD_PORT "10809"
 
+static int
+qemuBuildISCSIString(virDomainDiskDefPtr disk, virBufferPtr opt)
+{
+    return qemuBuildDriveURIString(disk, opt, "iscsi");
+}
+
 static int
 qemuBuildNBDString(virDomainDiskDefPtr disk, virBufferPtr opt)
 {
@@ -2713,6 +2750,11 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
+            case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
+                if (qemuBuildISCSIString(disk, &opt) < 0)
+                    goto error;
+                virBufferAddChar(&opt, ',');
+                break;
 
             case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
                 if (disk->nhosts == 0) {
@@ -7909,6 +7951,12 @@ qemuParseCommandLineDisk(virCapsPtr qemuCaps,
 
                     if (qemuParseGlusterString(def) < 0)
                         goto error;
+                } else if (STRPREFIX(def->src, "iscsi:")) {
+                    def->type = VIR_DOMAIN_DISK_TYPE_NETWORK;
+                    def->protocol = VIR_DOMAIN_DISK_PROTOCOL_ISCSI;
+
+                    if (qemuParseISCSIString(def) < 0)
+                        goto error;
                 } else if (STRPREFIX(def->src, "sheepdog:")) {
                     char *p = def->src;
                     char *port, *vdi;
@@ -9199,6 +9247,11 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
                     if (qemuParseGlusterString(disk) < 0)
                         goto error;
 
+                    break;
+                case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
+                    if (qemuParseISCSIString(disk) < 0)
+                        goto error;
+
                     break;
                 }
             }
index d4219854214df3848c0504d9d13d5a60430c17c0..6fd1de6fe69af5af5c4d554a4b676a1ec98280a7 100644 (file)
@@ -189,6 +189,7 @@ mymain(void)
     DO_TEST("disk-drive-network-nbd-ipv6");
     DO_TEST("disk-drive-network-nbd-ipv6-export");
     DO_TEST("disk-drive-network-nbd-unix");
+    DO_TEST("disk-drive-network-iscsi");
     DO_TEST("disk-drive-network-gluster");
     DO_TEST("disk-drive-network-rbd");
     DO_TEST("disk-drive-network-rbd-ipv6");
index 6dbb009b1e1f996af4344801baa4ff47d00971fb..9d70586b483dc28de0a1c25fec234f0423f8e4ee 100644 (file)
@@ -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=gluster+tcp://example.org:6000/Volume1/Image,if=virtio,format=raw -drive 'file=gluster+unix:///Volume2/Image?socket=/path/to/sock,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=gluster://example.org:6000/Volume1/Image,if=virtio,format=raw -drive 'file=gluster+unix:///Volume2/Image?socket=/path/to/sock,if=virtio,format=raw' -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
new file mode 100644 (file)
index 0000000..b8bc9c6
--- /dev/null
@@ -0,0 +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 -drive file=iscsi://example.org:6000/iqn.1992-01.com.example/1,if=virtio,format=raw -net none -serial none -parallel none
index dd8503261ea58e71876180ad0bcca257d0798afb..7db342639e53dd66c400bcbf7ddabcd956b6cdc2 100644 (file)
       </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/1'>
+        <host name='example.org' port='6000'/>
+      </source>
+      <target dev='vdb' bus='virtio'/>
+    </disk>
     <controller type='usb' index='0'/>
     <memballoon model='virtio'/>
   </devices>
index a942935d18706eadc9ccdbd0a08720a6e0f3b8e7..15410735528f92d331887f0db0c1bff082160783 100644 (file)
@@ -1,5 +1,5 @@
 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=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 \
--drive 'file=nbd+tcp://[::1]:6000/bar,if=virtio,format=raw' -net none \
+-drive 'file=nbd://[::1]:6000/bar,if=virtio,format=raw' -net none \
 -serial none -parallel none
index 7cdbdd1e1b3077182c6388baad5a085d9193bc0c..a28d015e61c2743da3a5292fc19487eb621467df 100644 (file)
@@ -1,5 +1,5 @@
 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=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 \
--drive 'file=nbd+tcp://[::1]:6000,if=virtio,format=raw' -net none \
+-drive 'file=nbd://[::1]:6000,if=virtio,format=raw' -net none \
 -serial none -parallel none
index 44bfe678c8c81ed81fe1d65afcf2e1d8d93b6d6e..07a423e6b478f4d6f096ea0283034fc9aefe336f 100644 (file)
@@ -501,6 +501,8 @@ mymain(void)
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-nbd-unix",
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
+    DO_TEST("disk-drive-network-iscsi",
+            QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-gluster",
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-rbd",