Since qemu 2.9 the options changed from a monolithic string into fine
grained options for the json pseudo-protocol object.
---
src/util/virstoragefile.c | 50 +++++++++++++++++++++++++++++++++++++++++++----
tests/virstoragetest.c | 19 ++++++++++++++++++
2 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 36e7ca759..2526bac0b 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -3118,6 +3118,15 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
int opaque ATTRIBUTE_UNUSED)
{
const char *filename;
+ const char *pool = virJSONValueObjectGetString(json, "pool");
+ const char *image = virJSONValueObjectGetString(json, "image");
+ const char *conf = virJSONValueObjectGetString(json, "conf");
+ const char *snapshot = virJSONValueObjectGetString(json, "snapshot");
+ virJSONValuePtr servers = virJSONValueObjectGetArray(json, "server");
+ char *fullname = NULL;
+ size_t nservers;
+ size_t i;
+ int ret = -1;
src->type = VIR_STORAGE_TYPE_NETWORK;
src->protocol = VIR_STORAGE_NET_PROTOCOL_RBD;
@@ -3126,11 +3135,44 @@ virStorageSourceParseBackingJSONRBD(virStorageSourcePtr src,
if ((filename = virJSONValueObjectGetString(json, "filename")))
return virStorageSourceParseRBDColonString(filename, src);
- /* RBD currently supports only URI syntax passed in as filename */
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("missing RBD filename in JSON backing volume
definition"));
+ if (!pool || !image) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("missing pool or image name in ceph backing volume "
+ "JSON specification"));
+ return -1;
+ }
- return -1;
+ /* currently we need to store the pool name and image name together, since
+ * the rest of the code is not prepared for it */
+ if (virAsprintf(&fullname, "%s/%s", pool, image) < 0)
+ return -1;
+
+ if (VIR_STRDUP(src->snapshot, snapshot) < 0 ||
+ VIR_STRDUP(src->configFile, conf) < 0)
+ goto cleanup;
+
+ VIR_STEAL_PTR(src->path, fullname);
+
+ if (servers) {
+ nservers = virJSONValueArraySize(servers);
+
+ if (VIR_ALLOC_N(src->hosts, nservers) < 0)
+ goto cleanup;
+
+ src->nhosts = nservers;
+
+ for (i = 0; i < nservers; i++) {
+ if (virStorageSourceParseBackingJSONInetSocketAddress(src->hosts + i,
+
virJSONValueArrayGet(servers, i)) < 0)
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(fullname);
+
+ return ret;
}
static int
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index 443d9c6ec..890b5c37c 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1507,6 +1507,25 @@ mymain(void)
"<source protocol='rbd'
name='testshare'>\n"
" <host name='example.com'/>\n"
"</source>\n");
+
TEST_BACKING_PARSE("json:{\"file\":{\"driver\":\"rbd\","
+
"\"image\":\"test\","
+
"\"pool\":\"libvirt\","
+
"\"conf\":\"/path/to/conf\","
+
"\"snapshot\":\"snapshotname\","
+ "\"server\":[
{\"host\":\"example.com\","
+
"\"port\":\"1234\""
+ "},"
+
"{\"host\":\"example2.com\""
+ "}"
+ "]"
+ "}"
+ "}",
+ "<source protocol='rbd'
name='libvirt/test'>\n"
+ " <host name='example.com'
port='1234'/>\n"
+ " <host name='example2.com'/>\n"
+ " <snapshot name='snapshotname'/>\n"
+ " <config file='/path/to/conf'/>\n"
+ "</source>\n");
TEST_BACKING_PARSE("json:{ \"file\": { "
"\"driver\": \"raw\","
"\"file\": {"
--
2.12.2