This patch adds support for gluster specific JSON parser functionality
This will help in parsing the backing store which uses JSON syntax and update
the meta-data in the domain specific objects while taking snapshots which inturn
helps in successful creation/updation of backing store information in domain xml
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever(a)redhat.com>
---
src/util/virstoragefile.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 2aa1d90..c122d3a 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -41,6 +41,7 @@
#include "virstring.h"
#include "virutil.h"
#include "viruri.h"
+#include "virjson.h"
#include "dirname.h"
#include "virbuffer.h"
@@ -2124,6 +2125,132 @@ virStorageSourceNewFromBackingRelative(virStorageSourcePtr
parent,
goto cleanup;
}
+static int
+virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+ const char *path)
+{
+#if WITH_STORAGE_GLUSTER
+
+ virJSONValuePtr json = NULL;
+ virJSONValuePtr file = NULL;
+ virJSONValuePtr volfile_server = NULL;
+ char *transport = NULL;
+ int port = 0;
+ size_t i = 0;
+
+ /* The string may look like:
+ * json:{ file: { driver:"gluster", volname:"testvol",
image-path:"/a.img",
+ * volfile-servers :[ {server:"1.2.3.4", port:24007,
transport:"tcp"} ,
+ * {server:"5.6.7.8", port:24008,
transport:"rdma"},
+ * {}, ... ] }, driver:"qcow2" }
+ */
+
+ json = virJSONValueFromString(path+strlen("json:"));
+
+ if (virJSONValueObjectHasKey(json, "driver")) {
+ if (!(src->format = virStorageFileFormatTypeFromString(
+ virJSONValueObjectGetString(json, "driver")))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get Format type of key 'driver' from
JSON"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(json, "file")) {
+ if (!(file = virJSONValueObjectGet(json, "file"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unbale to get Object from key 'file'"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(file, "driver")) {
+ if (!(src->protocol = virStorageNetProtocolTypeFromString(
+ virJSONValueObjectGetString(file, "driver")))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get Protocol type of key 'driver' from
JSON"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(file, "volname")) {
+ if (!(src->volume = (char *) virJSONValueObjectGetString(file,
+ "volname"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unbale to get String from key 'volname'"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(file, "image-path")) {
+ if (!(src->path = (char *) virJSONValueObjectGetString(file,
+ "image-path"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get String from key 'image-path'"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(file, "volfile-servers")) {
+ if (!(src->nhosts = virJSONValueArraySize(virJSONValueObjectGet(file,
+ "volfile-servers")))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get Size of Array of key
'volfile-servers'"));
+ goto error;
+ }
+ }
+
+ /* null-terminated list */
+ if (VIR_ALLOC_N(src->hosts, src->nhosts + 1) < 0)
+ goto error;
+
+ for (i = 0; i < src->nhosts; i++) {
+ volfile_server = virJSONValueArrayGet(virJSONValueObjectGetArray(file,
+ "volfile-servers"), i);
+
+ if (virJSONValueObjectHasKey(volfile_server, "server")) {
+ if (VIR_STRDUP(src->hosts[i].name,
+ virJSONValueObjectGetString(volfile_server, "server"))
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get String from key 'server'"));
+ goto error;
+ }
+ }
+
+ if (virJSONValueObjectHasKey(volfile_server, "port")) {
+ if (virJSONValueObjectGetNumberInt(volfile_server, "port",
&port) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get NumberInt from key 'port'"));
+ goto error;
+ }
+ if (virAsprintf(&src->hosts[i].port, "%d", port) < 0)
+ goto error;
+ }
+
+ if (virJSONValueObjectHasKey(volfile_server, "transport")) {
+ if (VIR_STRDUP(transport, virJSONValueObjectGetString(volfile_server,
+ "transport")) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to get String from key
'transport'"));
+ goto error;
+ }
+ src->hosts[i].transport =
virStorageNetHostTransportTypeFromString(transport);
+ VIR_FREE(transport);
+ }
+ }
+
+ return 0;
+
+ error:
+ VIR_FREE(transport);
+ virJSONValueFree(volfile_server);
+ virJSONValueFree(file);
+ virJSONValueFree(json);
+
+#endif /* WITH_STORAGE_GLUSTER */
+
+ return -1;
+}
static int
virStorageSourceParseBackingURI(virStorageSourcePtr src,
@@ -2535,6 +2662,9 @@ virStorageSourceNewFromBackingAbsolute(const char *path)
if (strstr(path, "://")) {
if (virStorageSourceParseBackingURI(ret, path) < 0)
goto error;
+ } else if (strstr(path, "json:")) {
+ if (virStorageSourceParseBackingJSON(ret, path) < 0)
+ goto error;
} else {
if (virStorageSourceParseBackingColon(ret, path) < 0)
goto error;
--
2.1.0