[libvirt] [PATCH v3 3/3] util: add backing store parser support for gluster protocol

Prasanna Kumar Kalever prasanna.kalever at redhat.com
Fri Jul 22 08:20:31 UTC 2016


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 at redhat.com>
---
 src/util/virstoragefile.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 208 insertions(+)

diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 16de603..033d6a2 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -41,10 +41,12 @@
 #include "virstring.h"
 #include "virutil.h"
 #include "viruri.h"
+#include "virjson.h"
 #include "dirname.h"
 #include "virbuffer.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
+#define DEFAULT_GLUSTER_PORT 24007
 
 VIR_LOG_INIT("util.storagefile");
 
@@ -2126,6 +2128,209 @@ virStorageSourceNewFromBackingRelative(virStorageSourcePtr parent,
     goto cleanup;
 }
 
+#if WITH_STORAGE_GLUSTER
+static int
+virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+                                 const char *path)
+{
+    virJSONValuePtr json = NULL;
+    virJSONValuePtr file = NULL;
+    virJSONValuePtr server = NULL;
+    virJSONValuePtr object = NULL;
+    const char *str = NULL;
+    int port = 0;
+    size_t i = 0;
+    int ret = -1;
+
+    /* An example of gluster json formatted string containing two servers:
+     *
+     * json:{ file: { driver:"gluster", volume:"testvol", path:"/a.img",
+     * server :[ {type:"tcp", host:"1.2.3.4", port:24007},
+     *           {type:"unix", socket:"/tmp/glusterd.socket"},
+     *         ] }, driver:"qcow2" }
+     */
+
+    /* Get 'json:' object */
+    json = virJSONValueFromString(path+strlen("json:"));
+
+    /* Get Image file format */
+    if (virJSONValueObjectHasKey(json, "driver")) {
+        if (!(str = virJSONValueObjectGetString(json, "driver"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get String from key 'driver'"));
+            goto error;
+        }
+        if ((src->format = virStorageFileFormatTypeFromString(str)) <= 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get Format type of key 'driver'"));
+            goto error;
+        }
+    } else {
+        src->format = 1;  /* default to raw */
+    }
+
+    /* Get 'file:' object */
+    if (virJSONValueObjectHasKey(json, "file")) {
+        if (!(file = virJSONValueObjectGet(json, "file"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get Object from key 'file'"));
+            goto error;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'file'"));
+        goto error;
+    }
+
+    /* Get 'protocol' Info */
+    if (virJSONValueObjectHasKey(file, "driver")) {
+        if (!(str = virJSONValueObjectGetString(file, "driver"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get String from key 'driver'"));
+            goto error;
+        }
+        if ((src->protocol = virStorageNetProtocolTypeFromString(str)) <= 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get Protocol type of key 'driver'"));
+            goto error;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("No protocol Key 'driver'"));
+        goto error;
+    }
+
+    /* Get 'volume' name Info */
+    if (virJSONValueObjectHasKey(file, "volume")) {
+        if (!(str = virJSONValueObjectGetString(file, "volume"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get String from key 'volume'"));
+            goto error;
+        }
+        if (VIR_STRDUP(src->volume, str) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Falied to duplicate value of key 'volume'"));
+            goto error;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'volume'"));
+        goto error;
+    }
+
+    /* Get 'path' info of Image*/
+    if (virJSONValueObjectHasKey(file, "path")) {
+        if (!(str = virJSONValueObjectGetString(file, "path"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get String from key 'path'"));
+            goto error;
+        }
+        if (VIR_STRDUP(src->path, str) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Falied to duplicate value of key 'path'"));
+            goto error;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'path'"));
+        goto error;
+    }
+
+    /* Get 'server:' object */
+    if (virJSONValueObjectHasKey(file, "server")) {
+        if (!(server = virJSONValueObjectGetArray(file, "server"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get Array Object from key 'file'"));
+            goto error;
+        }
+        if (!(src->nhosts = virJSONValueArraySize(server))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("Unable to get Size of Array from key 'server'"));
+            goto error;
+        }
+    } else {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'server'"));
+        goto error;
+    }
+
+    /* null-terminated list */
+    if (VIR_ALLOC_N(src->hosts, src->nhosts + 1) < 0)
+        goto error;
+
+    /* Parse 'server' object for { type, host, port, socket} */
+    for (i = 0; i < src->nhosts; i++) {
+        object = virJSONValueArrayGet(server, i);
+        if (virJSONValueObjectHasKey(object, "type")) {
+            if (!(str = virJSONValueObjectGetString(object, "type"))) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Unable to get String from key 'type'"));
+                goto error;
+            }
+            if ((src->hosts[i].transport = virStorageNetHostTransportTypeFromString(str)) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("Unable to get Transport from key 'type'"));
+            }
+        } else {
+            src->hosts[i].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+        }
+
+        if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_UNIX) {
+            if (virJSONValueObjectHasKey(object, "socket")) {
+                if (!(str = virJSONValueObjectGetString(object, "socket"))) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("Unable to get String from key 'socket'"));
+                    goto error;
+                }
+                if (VIR_STRDUP(src->hosts[i].socket, str) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("Falied to duplicate value of key 'socket'"));
+                    goto error;
+                }
+            } else {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'socket'"));
+                goto error;
+            }
+        } else { /* tcp */
+            if (virJSONValueObjectHasKey(object, "host")) {
+                if (!(str = virJSONValueObjectGetString(object, "host"))) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("Unable to get String from key 'host'"));
+                    goto error;
+                }
+                if (VIR_STRDUP(src->hosts[i].name, str) < 0) {
+                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                   _("Falied to duplicate value of key 'host'"));
+                    goto error;
+                }
+            } else {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No Key 'host'"));
+                goto error;
+            }
+
+            if (virJSONValueObjectHasKey(object, "port")) {
+                if (virJSONValueObjectGetNumberInt(object, "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;
+            } else {
+                if (virAsprintf(&src->hosts[i].port, "%d", DEFAULT_GLUSTER_PORT) < 0)
+                    goto error;
+            }
+        }
+    }
+
+    ret = 0;
+
+ error:
+    virJSONValueFree(object);
+    virJSONValueFree(server);
+    virJSONValueFree(file);
+    virJSONValueFree(json);
+
+    return ret;
+}
+
+#endif /* WITH_STORAGE_GLUSTER */
 
 static int
 virStorageSourceParseBackingURI(virStorageSourcePtr src,
@@ -2534,6 +2739,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.7.4




More information about the libvir-list mailing list