3e5111
From 825c7ad1ab9be3abcd1935491d11d0590e3b3462 Mon Sep 17 00:00:00 2001
3e5111
Message-Id: <825c7ad1ab9be3abcd1935491d11d0590e3b3462@dist-git>
3e5111
From: Peter Krempa <pkrempa@redhat.com>
3e5111
Date: Tue, 20 Jun 2017 10:22:43 +0200
3e5111
Subject: [PATCH] util: storage: adapt to changes in JSON format for ceph/rbd
3e5111
3e5111
Since qemu 2.9 the options changed from a monolithic string into fine
3e5111
grained options for the json pseudo-protocol object.
3e5111
3e5111
(cherry picked from commit 4fac5a1935041254964313ed722fa8d59f8fa2de)
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 | 50 +++++++++++++++++++++++++++++++++++++++++++----
3e5111
 tests/virstoragetest.c    | 19 ++++++++++++++++++
3e5111
 2 files changed, 65 insertions(+), 4 deletions(-)
3e5111
3e5111
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
3e5111
index ef3050711b..68bfdcd0ca 100644
3e5111
--- a/src/util/virstoragefile.c
3e5111
+++ b/src/util/virstoragefile.c
3e5111
@@ -3127,6 +3127,15 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
3e5111
                                     int opaque ATTRIBUTE_UNUSED)
3e5111
 {
3e5111
     const char *filename;
3e5111
+    const char *pool = virJSONValueObjectGetString(json, "pool");
3e5111
+    const char *image = virJSONValueObjectGetString(json, "image");
3e5111
+    const char *conf = virJSONValueObjectGetString(json, "conf");
3e5111
+    const char *snapshot = virJSONValueObjectGetString(json, "snapshot");
3e5111
+    virJSONValuePtr servers = virJSONValueObjectGetArray(json, "server");
3e5111
+    char *fullname = NULL;
3e5111
+    size_t nservers;
3e5111
+    size_t i;
3e5111
+    int ret = -1;
3e5111
 
3e5111
     src->type = VIR_STORAGE_TYPE_NETWORK;
3e5111
     src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
3e5111
@@ -3135,11 +3144,44 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
3e5111
     if ((filename = virJSONValueObjectGetString(json, "filename")))
3e5111
         return virStorageSourceParseRBDColonString(filename, src);
3e5111
 
3e5111
-    /* RBD currently supports only URI syntax passed in as filename */
3e5111
-    virReportError(VIR_ERR_INVALID_ARG, "%s",
3e5111
-                   _("missing RBD filename in JSON backing volume definition"));
3e5111
+    if (!pool || !image) {
3e5111
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
3e5111
+                       _("missing pool or image name in ceph backing volume "
3e5111
+                         "JSON specification"));
3e5111
+        return -1;
3e5111
+    }
3e5111
 
3e5111
-    return -1;
3e5111
+    /* currently we need to store the pool name and image name together, since
3e5111
+     * the rest of the code is not prepared for it */
3e5111
+    if (virAsprintf(&fullname, "%s/%s", pool, image) < 0)
3e5111
+        return -1;
3e5111
+
3e5111
+    if (VIR_STRDUP(src->snapshot, snapshot) < 0 ||
3e5111
+        VIR_STRDUP(src->configFile, conf) < 0)
3e5111
+        goto cleanup;
3e5111
+
3e5111
+    VIR_STEAL_PTR(src->path, fullname);
3e5111
+
3e5111
+    if (servers) {
3e5111
+        nservers = virJSONValueArraySize(servers);
3e5111
+
3e5111
+        if (VIR_ALLOC_N(src->hosts, nservers) < 0)
3e5111
+            goto cleanup;
3e5111
+
3e5111
+        src->nhosts = nservers;
3e5111
+
3e5111
+        for (i = 0; i < nservers; i++) {
3e5111
+            if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts + i,
3e5111
+                                                                  virJSONValueArrayGet(servers, i)) < 0)
3e5111
+                goto cleanup;
3e5111
+        }
3e5111
+    }
3e5111
+
3e5111
+    ret = 0;
3e5111
+ cleanup:
3e5111
+    VIR_FREE(fullname);
3e5111
+
3e5111
+    return ret;
3e5111
 }
3e5111
 
3e5111
 static int
3e5111
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
3e5111
index 54f7c849c5..97eaeab094 100644
3e5111
--- a/tests/virstoragetest.c
3e5111
+++ b/tests/virstoragetest.c
3e5111
@@ -1507,6 +1507,25 @@ mymain(void)
3e5111
                        "<source protocol='rbd' name='testshare'>\n"
3e5111
                        "  <host name='example.com'/>\n"
3e5111
                        "</source>\n");
3e5111
+    TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"rbd\","
3e5111
+                                       "\"image\":\"test\","
3e5111
+                                       "\"pool\":\"libvirt\","
3e5111
+                                       "\"conf\":\"/path/to/conf\","
3e5111
+                                       "\"snapshot\":\"snapshotname\","
3e5111
+                                       "\"server\":[ {\"host\":\"example.com\","
3e5111
+                                                      "\"port\":\"1234\""
3e5111
+                                                    "},"
3e5111
+                                                    "{\"host\":\"example2.com\""
3e5111
+                                                    "}"
3e5111
+                                                  "]"
3e5111
+                                      "}"
3e5111
+                             "}",
3e5111
+                        "<source protocol='rbd' name='libvirt/test'>\n"
3e5111
+                        "  <host name='example.com' port='1234'/>\n"
3e5111
+                        "  <host name='example2.com'/>\n"
3e5111
+                        "  <snapshot name='snapshotname'/>\n"
3e5111
+                        "  <config file='/path/to/conf'/>\n"
3e5111
+                        "</source>\n");
3e5111
     TEST_BACKING_PARSE("json:{ \"file\": { "
3e5111
                                 "\"driver\": \"raw\","
3e5111
                                 "\"file\": {"
3e5111
-- 
3e5111
2.13.1
3e5111