diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 66e21c4bd..c83ce5718 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4554,6 +4554,11 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev,
             disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI &&
             virDomainPostParseCheckISCSIPath(&disk->src->path) < 0)
             return -1;
+
+ if (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
+            disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISER &&
+            virDomainPostParseCheckISCSIPath(&disk->src->path) < 0)
+            return -1;
 
         if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO &&
             virDomainCheckVirtioOptions(disk->virtio) < 0)
@@ -5160,7 +5165,8 @@ virDomainDiskDefValidate(const virDomainDiskDef *disk)
         if (!(disk->src->type == VIR_STORAGE_TYPE_BLOCK ||
               disk->src->type == VIR_STORAGE_TYPE_VOLUME ||
               (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
-               disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI))) {
+               (disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI ||
+         disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISER)))) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("disk '%s' improperly configured for a "
                              "device='lun'"), disk->dst);
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 585f0255e..a9543293d 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -831,7 +831,7 @@ qemuBlockStorageSourceGetISCSIProps(virStorageSourcePtr src)
                                           "s:portal", portal,
                                           "s:target", target,
                                           "u:lun", lun,
-                                          "s:transport", "tcp",
+                                          "s:transport", src->protocol == VIR_STORAGE_NET_PROTOCOL_ISER? "iser":"tcp",
                                           "S:user", username,
                                           "S:password-secret", objalias,
                                           NULL));
@@ -1030,6 +1030,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src)
             break;
 
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_ISER:
             if (!(fileprops = qemuBlockStorageSourceGetISCSIProps(src)))
                 return NULL;
             break;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 645802795..a21ba0ae4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -932,6 +932,7 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
         case VIR_STORAGE_NET_PROTOCOL_FTPS:
         case VIR_STORAGE_NET_PROTOCOL_TFTP:
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+      case VIR_STORAGE_NET_PROTOCOL_ISER:
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
             ret = qemuBuildNetworkDriveURI(src, secinfo);
             break;
@@ -1482,7 +1483,7 @@ qemuDiskSourceNeedsProps(virStorageSourcePtr src,
         return true;
 
     if (actualType == VIR_STORAGE_TYPE_NETWORK &&
-        src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI &&
+        (src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI || src->protocol == VIR_STORAGE_NET_PROTOCOL_ISER) &&
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_ISCSI_PASSWORD_SECRET))
         return true;
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d7150cae1..76b2a6cc9 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8133,7 +8133,7 @@ int
 qemuDomainDefValidateDiskLunSource(const virStorageSource *src)
 {
     if (virStorageSourceGetActualType(src) == VIR_STORAGE_TYPE_NETWORK) {
-        if (src->protocol != VIR_STORAGE_NET_PROTOCOL_ISCSI) {
+        if (src->protocol != VIR_STORAGE_NET_PROTOCOL_ISCSI && src->protocol != VIR_STORAGE_NET_PROTOCOL_ISER) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("disk device='lun' is not supported "
                              "for protocol='%s'"),
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index aa30b119a..104b73ebe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -13983,6 +13983,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi
         case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_ISER:
         case VIR_STORAGE_NET_PROTOCOL_HTTP:
         case VIR_STORAGE_NET_PROTOCOL_HTTPS:
         case VIR_STORAGE_NET_PROTOCOL_FTP:
@@ -14060,6 +14061,7 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
         case VIR_STORAGE_NET_PROTOCOL_RBD:
         case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_ISER:
         case VIR_STORAGE_NET_PROTOCOL_HTTP:
         case VIR_STORAGE_NET_PROTOCOL_HTTPS:
         case VIR_STORAGE_NET_PROTOCOL_FTP:
@@ -14178,6 +14180,7 @@ qemuDomainSnapshotPrepareDiskInternal(virConnectPtr conn,
         case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_ISER:
         case VIR_STORAGE_NET_PROTOCOL_HTTP:
         case VIR_STORAGE_NET_PROTOCOL_HTTPS:
         case VIR_STORAGE_NET_PROTOCOL_FTP:
diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c
index 5fe3f97d0..72e137ce4 100644
--- a/src/qemu/qemu_parse_command.c
+++ b/src/qemu/qemu_parse_command.c
@@ -709,6 +709,12 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
 
                     if (qemuParseISCSIString(def) < 0)
                         goto error;
+ } else if (STRPREFIX(def->src->path, "iser:")) {
+                    def->src->type = VIR_STORAGE_TYPE_NETWORK;
+                    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISER;
+
+                    if (qemuParseISCSIString(def) < 0)
+                        goto error;
                 } else if (STRPREFIX(def->src->path, "sheepdog:")) {
                     char *p = def->src->path;
                     char *port, *vdi;
@@ -2157,6 +2163,7 @@ qemuParseCommandLine(virCapsPtr caps,
                         goto error;
 
                     break;
+                case VIR_STORAGE_NET_PROTOCOL_ISER:
                 case VIR_STORAGE_NET_PROTOCOL_ISCSI:
                     if (qemuParseISCSIString(disk) < 0)
                         goto error;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 6594715e5..cf5c2904e 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -81,6 +81,7 @@ VIR_ENUM_IMPL(virStorageNetProtocol, VIR_STORAGE_NET_PROTOCOL_LAST,
               "sheepdog",
               "gluster",
               "iscsi",
+              "iser",
               "http",
               "https",
               "ftp",
@@ -2750,6 +2751,7 @@ virStorageSourceParseBackingColon(virStorageSourcePtr src,
     case VIR_STORAGE_NET_PROTOCOL_FTPS:
     case VIR_STORAGE_NET_PROTOCOL_TFTP:
     case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+    case VIR_STORAGE_NET_PROTOCOL_ISER:
     case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
     case VIR_STORAGE_NET_PROTOCOL_SSH:
     case VIR_STORAGE_NET_PROTOCOL_VXHS:
@@ -3040,6 +3042,77 @@ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
     return ret;
 }
 
+static int 
+virStorageSourceParseBackingJSONiSER(virStorageSourcePtr src,
+                                      virJSONValuePtr json,
+                                      int opaque ATTRIBUTE_UNUSED)
+{
+    const char *transport = virJSONValueObjectGetString(json, "transport");
+    const char *portal = virJSONValueObjectGetString(json, "portal");
+    const char *target = virJSONValueObjectGetString(json, "target");
+    const char *uri;
+    char *port;
+    unsigned int lun = 0;
+    char *fulltarget = NULL;
+    int ret = -1;
+
+    /* legacy URI based syntax passed via 'filename' option */
+    if ((uri = virJSONValueObjectGetString(json, "filename")))
+        return virStorageSourceParseBackingJSONUriStr(src, uri,
+                                                      VIR_STORAGE_NET_PROTOCOL_ISER);
+
+    src->type = VIR_STORAGE_TYPE_NETWORK;
+    src->protocol = VIR_STORAGE_NET_PROTOCOL_ISER;
+
+    if (VIR_ALLOC(src->hosts) < 0)
+        goto cleanup;
+
+    src->nhosts = 1;
+
+    if (STRNEQ_NULLABLE(transport, "iser")) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("only ISER transport is supported for iSER volumes"));
+        goto cleanup;
+    }
+
+    src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+
+    if (!portal) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing 'portal' address in iSER backing definition"));
+        goto cleanup;
+    }
+
+    if (!target) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing 'target' in iSER backing definition"));
+        goto cleanup;
+    }
+
+    if (VIR_STRDUP(src->hosts->name, portal) < 0)
+        goto cleanup;
+
+    if ((port = strrchr(src->hosts->name, ':')) &&
+        !strchr(port, ']')) {
+        if (virStringParsePort(port + 1, &src->hosts->port) < 0)
+            goto cleanup;
+
+        *port = '\0';
+    }
+
+    ignore_value(virJSONValueObjectGetNumberUint(json, "lun", &lun));
+
+    if (virAsprintf(&fulltarget, "%s/%u", target, lun) < 0)
+        goto cleanup;
+
+    VIR_STEAL_PTR(src->path, fulltarget);
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(fulltarget);
+    return ret;
+}
 
 static int
 virStorageSourceParseBackingJSONNbd(virStorageSourcePtr src,
@@ -3295,6 +3368,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
     {"tftp", virStorageSourceParseBackingJSONUri, VIR_STORAGE_NET_PROTOCOL_TFTP},
     {"gluster", virStorageSourceParseBackingJSONGluster, 0},
     {"iscsi", virStorageSourceParseBackingJSONiSCSI, 0},
+    {"iser", virStorageSourceParseBackingJSONiSER, 0},
     {"nbd", virStorageSourceParseBackingJSONNbd, 0},
     {"sheepdog", virStorageSourceParseBackingJSONSheepdog, 0},
     {"ssh", virStorageSourceParseBackingJSONSSH, 0},
@@ -4054,6 +4128,7 @@ virStorageSourceNetworkDefaultPort(virStorageNetProtocol protocol)
             return 22;
 
         case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_ISER:
             return 3260;
 
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 24382a0a6..33771ddaf 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -129,6 +129,7 @@ typedef enum {
     VIR_STORAGE_NET_PROTOCOL_SHEEPDOG,
     VIR_STORAGE_NET_PROTOCOL_GLUSTER,
     VIR_STORAGE_NET_PROTOCOL_ISCSI,
+    VIR_STORAGE_NET_PROTOCOL_ISER,
     VIR_STORAGE_NET_PROTOCOL_HTTP,
     VIR_STORAGE_NET_PROTOCOL_HTTPS,
     VIR_STORAGE_NET_PROTOCOL_FTP,

Best Regards,
Charles.

zhangshengyu@fusionstack.cn