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(a)redhat.com>
---
src/qemu/qemu_command.c | 49 +++++++++++++++++++++-
tests/qemuargv2xmltest.c | 1 +
.../qemuxml2argv-disk-drive-network-gluster.args | 2 +-
.../qemuxml2argv-disk-drive-network-iscsi.args | 1 +
...ml2argv-disk-drive-network-nbd-ipv6-export.args | 2 +-
.../qemuxml2argv-disk-drive-network-nbd-ipv6.args | 2 +-
tests/qemuxml2argvtest.c | 2 +
7 files changed, 54 insertions(+), 5 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi.args
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 733d3bf..07700cc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2145,6 +2145,23 @@ qemuParseGlusterString(virDomainDiskDefPtr def)
}
static int
+qemuParseISCSIString(virDomainDiskDefPtr def)
+{
+ virURIPtr uri = NULL;
+
+ 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;
+ }
+
+ return qemuParseDriveURIString(def, uri, "iscsi");
+}
+
+static int
qemuParseNBDString(virDomainDiskDefPtr disk)
{
virDomainDiskHostDefPtr h = NULL;
@@ -2238,8 +2255,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;
@@ -2283,6 +2306,12 @@ qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt)
}
static int
+qemuBuildISCSIString(virDomainDiskDefPtr disk, virBufferPtr opt)
+{
+ return qemuBuildDriveURIString(disk, opt, "iscsi");
+}
+
+static int
qemuBuildNBDString(virDomainDiskDefPtr disk, virBufferPtr opt)
{
const char *transp;
@@ -2471,6 +2500,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) {
@@ -7503,6 +7537,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;
@@ -8793,6 +8833,11 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
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 9fbba94..314c7b3 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -186,6 +186,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 6dbb009..9d70586 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 0000000..ed4f337
--- /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 -net
none -serial none -parallel none
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 e12d4d6..183119b 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 -serial none \
+'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 e814805..a0cb07b 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 -serial none \
+'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 35cba01..babdd8c 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -493,6 +493,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",
--
1.8.1.2