render / rpms / libvirt

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