Blame SOURCES/libvirt-util-storage-Add-JSON-parser-for-new-options-in-iSCSI-protocol.patch

6d3351
From 0d64aa3d8573b36ae85b77138dc463ca05e7bae1 Mon Sep 17 00:00:00 2001
6d3351
Message-Id: <0d64aa3d8573b36ae85b77138dc463ca05e7bae1@dist-git>
6d3351
From: Peter Krempa <pkrempa@redhat.com>
6d3351
Date: Tue, 20 Jun 2017 10:22:41 +0200
6d3351
Subject: [PATCH] util: storage: Add JSON parser for new options in iSCSI
6d3351
 protocol
6d3351
6d3351
Starting from qemu 2.9, more granular options are supported. Add parser
6d3351
for the relevant bits.
6d3351
6d3351
With this patch libvirt is able to parse the host and target IQN of from
6d3351
the JSON pseudo-protocol specification.
6d3351
6d3351
This corresponds to BlockdevOptionsIscsi in qemu qapi.
6d3351
6d3351
(cherry picked from commit b24bc54080b4bc444e60560c0db00c5867e74000)
6d3351
6d3351
https://bugzilla.redhat.com/show_bug.cgi?id=1461638
6d3351
6d3351
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
6d3351
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
6d3351
---
6d3351
 src/util/virstoragefile.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---
6d3351
 tests/virstoragetest.c    | 19 ++++++++++++++
6d3351
 2 files changed, 78 insertions(+), 4 deletions(-)
6d3351
6d3351
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
6d3351
index 3f8bc43928..945c3e4198 100644
6d3351
--- a/src/util/virstoragefile.c
6d3351
+++ b/src/util/virstoragefile.c
6d3351
@@ -2940,18 +2940,73 @@ virStorageSourceParseBackingJSONiSCSI(virStorageSourcePtr src,
6d3351
                                       virJSONValuePtr json,
6d3351
                                       int opaque ATTRIBUTE_UNUSED)
6d3351
 {
6d3351
+    const char *transport = virJSONValueObjectGetString(json, "transport");
6d3351
+    const char *portal = virJSONValueObjectGetString(json, "portal");
6d3351
+    const char *target = virJSONValueObjectGetString(json, "target");
6d3351
     const char *uri;
6d3351
+    char *port;
6d3351
+    unsigned int lun = 0;
6d3351
+    char *fulltarget = NULL;
6d3351
+    int ret = -1;
6d3351
 
6d3351
     /* legacy URI based syntax passed via 'filename' option */
6d3351
     if ((uri = virJSONValueObjectGetString(json, "filename")))
6d3351
         return virStorageSourceParseBackingJSONUriStr(src, uri,
6d3351
                                                       VIR_STORAGE_NET_PROTOCOL_ISCSI);
6d3351
 
6d3351
-    /* iSCSI currently supports only URI syntax passed in as filename */
6d3351
-    virReportError(VIR_ERR_INVALID_ARG, "%s",
6d3351
-                   _("missing iSCSI URI in JSON backing volume definition"));
6d3351
+    src->type = VIR_STORAGE_TYPE_NETWORK;
6d3351
+    src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
6d3351
 
6d3351
-    return -1;
6d3351
+    if (VIR_ALLOC(src->hosts) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    src->nhosts = 1;
6d3351
+
6d3351
+    if (STRNEQ_NULLABLE(transport, "tcp")) {
6d3351
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
6d3351
+                       _("only TCP transport is supported for iSCSI volumes"));
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+
6d3351
+    src->hosts->transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
6d3351
+
6d3351
+    if (!portal) {
6d3351
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
6d3351
+                       _("missing 'portal' address in iSCSI backing definition"));
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+
6d3351
+    if (!target) {
6d3351
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
6d3351
+                       _("missing 'target' in iSCSI backing definition"));
6d3351
+        goto cleanup;
6d3351
+    }
6d3351
+
6d3351
+    if (VIR_STRDUP(src->hosts->name, portal) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    if ((port = strchr(src->hosts->name, ':'))) {
6d3351
+        if (VIR_STRDUP(src->hosts->port, port + 1) < 0)
6d3351
+            goto cleanup;
6d3351
+
6d3351
+        if (strlen(src->hosts->port) == 0)
6d3351
+            VIR_FREE(src->hosts->port);
6d3351
+
6d3351
+        *port = '\0';
6d3351
+    }
6d3351
+
6d3351
+    ignore_value(virJSONValueObjectGetNumberUint(json, "lun", &lun));
6d3351
+
6d3351
+    if (virAsprintf(&fulltarget, "%s/%u", target, lun) < 0)
6d3351
+        goto cleanup;
6d3351
+
6d3351
+    VIR_STEAL_PTR(src->path, fulltarget);
6d3351
+
6d3351
+    ret = 0;
6d3351
+
6d3351
+ cleanup:
6d3351
+    VIR_FREE(fulltarget);
6d3351
+    return ret;
6d3351
 }
6d3351
 
6d3351
 
6d3351
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
6d3351
index 4a1d4d0923..294e1f6ffb 100644
6d3351
--- a/tests/virstoragetest.c
6d3351
+++ b/tests/virstoragetest.c
6d3351
@@ -1502,6 +1502,25 @@ mymain(void)
6d3351
                                     "\"driver\": \"file\","
6d3351
                                     "\"filename\": \"/path/to/file\" } } }",
6d3351
                        "<source file='/path/to/file'/>\n");
6d3351
+    TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"iscsi\","
6d3351
+                                       "\"transport\":\"tcp\","
6d3351
+                                       "\"portal\":\"test.org\","
6d3351
+                                       "\"target\":\"iqn.2016-12.com.virttest:emulated-iscsi-noauth.target\""
6d3351
+                                      "}"
6d3351
+                            "}",
6d3351
+                       "<source protocol='iscsi' name='iqn.2016-12.com.virttest:emulated-iscsi-noauth.target/0'>\n"
6d3351
+                       "  <host name='test.org'/>\n"
6d3351
+                       "</source>\n");
6d3351
+    TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"iscsi\","
6d3351
+                                       "\"transport\":\"tcp\","
6d3351
+                                       "\"portal\":\"test.org:1234\","
6d3351
+                                       "\"target\":\"iqn.2016-12.com.virttest:emulated-iscsi-noauth.target\","
6d3351
+                                       "\"lun\":6"
6d3351
+                                      "}"
6d3351
+                            "}",
6d3351
+                       "<source protocol='iscsi' name='iqn.2016-12.com.virttest:emulated-iscsi-noauth.target/6'>\n"
6d3351
+                       "  <host name='test.org' port='1234'/>\n"
6d3351
+                       "</source>\n");
6d3351
 
6d3351
  cleanup:
6d3351
     /* Final cleanup */
6d3351
-- 
6d3351
2.13.1
6d3351