[PATCH v1 2/5] qemu: Support iser transport in iscsi

Han Han hhan at redhat.com
Mon Apr 27 02:01:07 UTC 2020


The iscsi iser transport is introdcued since QEMU 2.9. For iscsi blockdev
json, it will be shown at 'transport' field:
'json:{...,{"driver": "iscsi","transport":"iser",...}}'

For legacy drive filename as iscsi uri, it will start with 'iser'
scheme:
iser://[[username][%<password>]@]<host>[:<port>]/<target-iqn-name>/<lun>

By default, the iscsi transport is still tcp.

Signed-off-by: Han Han <hhan at redhat.com>
---
 src/qemu/qemu_backup.c             |  1 +
 src/qemu/qemu_block.c              | 16 +++++++++++++---
 src/qemu/qemu_command.c            | 17 +++++++++++++++++
 src/qemu/qemu_monitor_json.c       |  1 +
 src/storage/storage_file_gluster.c |  7 +++++++
 src/util/virstoragefile.c          | 26 ++++++++++++++++++--------
 src/util/virstoragefile.h          |  1 +
 7 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index 80fc5d77..caf0b4ce 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -88,6 +88,7 @@ qemuBackupPrepare(virDomainBackupDefPtr def)
             /* TODO: Do we need to mess with selinux? */
             break;
 
+        case VIR_STORAGE_NET_HOST_TRANS_ISER:
         case VIR_STORAGE_NET_HOST_TRANS_RDMA:
         case VIR_STORAGE_NET_HOST_TRANS_LAST:
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index d32277d7..003c18f1 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -418,10 +418,16 @@ qemuBlockStorageSourceGetURI(virStorageSourcePtr src)
     if (VIR_ALLOC(uri) < 0)
         return NULL;
 
-    if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
+    if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP ||
+        src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_RDMA ||
+        src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_ISER)
         uri->port = src->hosts->port;
 
+    if (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
         uri->scheme = g_strdup(virStorageNetProtocolTypeToString(src->protocol));
+    } else if (src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI &&
+               src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_ISER) {
+        uri->scheme = g_strdup("iser");
     } else {
         uri->scheme = g_strdup_printf("%s+%s",
                                       virStorageNetProtocolTypeToString(src->protocol),
@@ -497,6 +503,7 @@ qemuBlockStorageSourceBuildJSONSocketAddress(virStorageNetHostDefPtr host,
             return NULL;
         break;
 
+    case VIR_STORAGE_NET_HOST_TRANS_ISER:
     case VIR_STORAGE_NET_HOST_TRANS_RDMA:
     case VIR_STORAGE_NET_HOST_TRANS_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -743,6 +750,7 @@ qemuBlockStorageSourceGetISCSIProps(virStorageSourcePtr src,
 {
     qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
     g_autofree char *target = NULL;
+    const char *transport = NULL;
     char *lunStr = NULL;
     char *username = NULL;
     char *objalias = NULL;
@@ -762,6 +770,7 @@ qemuBlockStorageSourceGetISCSIProps(virStorageSourcePtr src,
      */
 
     target = g_strdup(src->path);
+    transport = virStorageNetHostTransportTypeToString(src->hosts->transport);
 
     /* Separate the target and lun */
     if ((lunStr = strchr(target, '/'))) {
@@ -791,7 +800,7 @@ qemuBlockStorageSourceGetISCSIProps(virStorageSourcePtr src,
                                           "s:portal", portal,
                                           "s:target", target,
                                           "u:lun", lun,
-                                          "s:transport", "tcp",
+                                          "s:transport", transport,
                                           "S:user", username,
                                           "S:password-secret", objalias,
                                           "S:initiator-name", src->initiator.iqn,
@@ -2063,7 +2072,8 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src,
         /* generate simplified URIs for the easy cases */
         if (actualType == VIR_STORAGE_TYPE_NETWORK &&
             src->nhosts == 1 &&
-            src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
+            (src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP ||
+             src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_ISER) &&
             src->timeout == 0 &&
             src->ncookies == 0 &&
             src->sslverify == VIR_TRISTATE_BOOL_ABSENT &&
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 45dd8307..c5cf9401 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1443,6 +1443,16 @@ qemuCheckDiskConfig(virDomainDiskDefPtr disk,
                 return -1;
             }
         }
+
+        if (disk->src &&
+            disk->src->hosts &&
+            disk->src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_ISER &&
+            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_ISCSI_TRANSPORT_ISER)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                    _("iSCSI iser transport is not supported by this "
+                      "QEMU binary"));
+            return -1;
+        }
     }
 
     if (disk->serial &&
@@ -4888,6 +4898,13 @@ qemuBuildSCSIiSCSIHostdevDrvStr(virDomainHostdevDefPtr dev,
     qemuDomainStorageSourcePrivatePtr srcPriv =
         QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(iscsisrc->src);
 
+    if (iscsisrc->src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_ISER &&
+        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_ISCSI_TRANSPORT_ISER)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("This QEMU doesn't support iSCSI iser transport"));
+        return NULL;
+    }
+
     if (qemuDiskSourceNeedsProps(iscsisrc->src, qemuCaps)) {
         if (!(srcprops = qemuDiskSourceGetProps(iscsisrc->src)))
             return NULL;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 619717ea..338f66ef 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -7199,6 +7199,7 @@ qemuMonitorJSONNBDServerStart(qemuMonitorPtr mon,
     case VIR_STORAGE_NET_HOST_TRANS_UNIX:
         addr = qemuMonitorJSONBuildUnixSocketAddress(server->socket);
         break;
+    case VIR_STORAGE_NET_HOST_TRANS_ISER:
     case VIR_STORAGE_NET_HOST_TRANS_RDMA:
     case VIR_STORAGE_NET_HOST_TRANS_LAST:
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/storage/storage_file_gluster.c b/src/storage/storage_file_gluster.c
index f389a944..73dfef0c 100644
--- a/src/storage/storage_file_gluster.c
+++ b/src/storage/storage_file_gluster.c
@@ -78,6 +78,13 @@ virStorageFileBackendGlusterInitServer(virStorageFileBackendGlusterPrivPtr priv,
         hoststr = host->socket;
         break;
 
+    case VIR_STORAGE_NET_HOST_TRANS_ISER:
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid transport '%s' for gluster host"),
+                       transport);
+        return -1;
+        break;
+
     case VIR_STORAGE_NET_HOST_TRANS_LAST:
         break;
     }
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index ffc8bdb3..4f162f10 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -97,6 +97,7 @@ VIR_ENUM_IMPL(virStorageNetHostTransport,
               "tcp",
               "unix",
               "rdma",
+              "iser",
 );
 
 VIR_ENUM_IMPL(virStorageSourcePoolMode,
@@ -2839,10 +2840,15 @@ virStorageSourceParseBackingURI(virStorageSourcePtr src,
 
     if (!scheme[0] ||
         (src->protocol = virStorageNetProtocolTypeFromString(scheme[0])) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("invalid backing protocol '%s'"),
-                       NULLSTR(scheme[0]));
-        return -1;
+        if (STRNEQ(scheme[0], "iser")) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("invalid backing protocol '%s'"),
+                           NULLSTR(scheme[0]));
+            return -1;
+        }
+
+        src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+        src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_ISER;
     }
 
     if (scheme[1] &&
@@ -3523,14 +3529,17 @@ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
         return -1;
 
     src->nhosts = 1;
+    src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
 
-    if (STRNEQ_NULLABLE(transport, "tcp")) {
+    if (STRNEQ(transport, "tcp") && STRNEQ(transport, "iser") && transport) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
-                       _("only TCP transport is supported for iSCSI volumes"));
+                       _("only TCP or iSER transport is supported for iSCSI "
+                         "volumes"));
         return -1;
     }
 
-    src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+    if (transport)
+        src->hosts->transport = virStorageNetHostTransportTypeFromString(transport);
 
     if (!portal) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -4710,7 +4719,8 @@ virStorageSourceNetworkAssignDefaultPorts(virStorageSourcePtr src)
     size_t i;
 
     for (i = 0; i < src->nhosts; i++) {
-        if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP &&
+        if ((src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP ||
+             src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_ISER) &&
             src->hosts[i].port == 0)
             src->hosts[i].port = virStorageSourceNetworkDefaultPort(src->protocol);
     }
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 7939c09c..120d6190 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -146,6 +146,7 @@ typedef enum {
     VIR_STORAGE_NET_HOST_TRANS_TCP,
     VIR_STORAGE_NET_HOST_TRANS_UNIX,
     VIR_STORAGE_NET_HOST_TRANS_RDMA,
+    VIR_STORAGE_NET_HOST_TRANS_ISER,
 
     VIR_STORAGE_NET_HOST_TRANS_LAST
 } virStorageNetHostTransport;
-- 
2.25.0




More information about the libvir-list mailing list