From: Paolo Bonzini Date: Thu, 21 Mar 2013 11:53:49 +0000 (+0100) Subject: qemu: add support for libiscsi X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=1a308ee015048267cd74ccb12d7ea3b14b6587d0;p=libvirt.git qemu: add support for libiscsi 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 --- diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e4ed3f7f35..f17b808e9b 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1446,10 +1446,13 @@ are "nbd", "iscsi", "rbd", "sheepdog" or "gluster". If the protocol attribute is "rbd", "sheepdog" or "gluster", an additional attribute name is mandatory to specify which - volume/image will be used; for "nbd" it is optional. When the disk - type is "network", the source may have zero - or more host sub-elements used to specify the hosts - to connect. + volume/image will be used; for "nbd" it is optional. For "iscsi", + the name attribute may include a logical unit number, + separated from the target's name by a slash (for example, + iqn.1992-01.com.example/1); the default LUN is zero. + When the disk type is "network", the source + may have zero or more host sub-elements used to + specify the hosts to connect. Since 0.0.3; type='dir' since 0.7.5; type='network' since 0.8.7; protocol='iscsi' since 1.0.4
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8626b629b9..4774650d82 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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; } } diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index d421985421..6fd1de6fe6 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -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"); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-gluster.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-gluster.args index 6dbb009b1e..9d70586b48 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-gluster.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-gluster.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=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 index 0000000000..b8bc9c6145 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml index dd8503261e..7db342639e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.xml @@ -21,6 +21,13 @@ + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args index a942935d18..1541073552 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6-export.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args index 7cdbdd1e1b..a28d015e61 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-nbd-ipv6.args @@ -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 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 44bfe678c8..07a423e6b4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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",