qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [libvirt RFC PATCH 02/10] util: storage: Add parser for qem


From: Peter Krempa
Subject: [Qemu-block] [libvirt RFC PATCH 02/10] util: storage: Add parser for qemu's "json" backing pseudo-protocol
Date: Fri, 15 Jul 2016 15:46:35 +0200

Add a modular parser that will allow to parse 'json' backing definitions
that are supported by qemu. The initial implementation adds support for
the 'file' driver.
---
 src/util/virstoragefile.c | 87 +++++++++++++++++++++++++++++++++++++++++++----
 tests/virstoragetest.c    |  8 +++++
 2 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 0fa9681..826e4ba 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -43,6 +43,7 @@
 #include "viruri.h"
 #include "dirname.h"
 #include "virbuffer.h"
+#include "virjson.h"

 #define VIR_FROM_THIS VIR_FROM_STORAGE

@@ -2514,10 +2515,80 @@ virStorageSourceParseBackingColon(virStorageSourcePtr 
src,
 }


+static int
+virStorageSourceParseBackingJSONPath(virStorageSourcePtr src,
+                                     virJSONValuePtr json,
+                                     int type)
+{
+    const char *path;
+
+    if (!(path = virJSONValueObjectGetString(json, "file.filename"))) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("missing 'filename' field in JSON backing volume "
+                         "definition"));
+        return -1;
+    }
+
+    if (VIR_STRDUP(src->path, path) < 0)
+        return -1;
+
+    src->type = type;
+    return 0;
+}
+
+
+struct virStorageSourceJSONDriverParser {
+    const char *drvname;
+    int (*func)(virStorageSourcePtr src, virJSONValuePtr json, int opaque);
+    int opaque;
+};
+
+static const struct virStorageSourceJSONDriverParser jsonParsers[] = {
+    {"file", virStorageSourceParseBackingJSONPath, VIR_STORAGE_TYPE_FILE},
+};
+
+
+static int
+virStorageSourceParseBackingJSON(virStorageSourcePtr src,
+                                 const char *json)
+{
+    virJSONValuePtr root;
+    const char *drvname;
+    size_t i;
+    int ret = -1;
+
+    if (!(root = virJSONValueFromString(json)))
+        return -1;
+
+    if (!(drvname = virJSONValueObjectGetString(root, "file.driver"))) {
+        virReportError(VIR_ERR_INVALID_ARG, _("JSON backing volume defintion "
+                                              "'%s' lacks driver name"), json);
+        goto cleanup;
+    }
+
+    for (i = 0; i < ARRAY_CARDINALITY(jsonParsers); i++) {
+        if (STREQ(drvname, jsonParsers[i].drvname)) {
+            ret = jsonParsers[i].func(src, root, jsonParsers[i].opaque);
+            goto cleanup;
+        }
+    }
+
+    virReportError(VIR_ERR_INTERNAL_ERROR,
+                   _("missing parser implementation for JSON backing volume "
+                     "driver '%s'"), drvname);
+
+ cleanup:
+    virJSONValueFree(root);
+    return ret;
+}
+
+
 virStorageSourcePtr
 virStorageSourceNewFromBackingAbsolute(const char *path)
 {
+    const char *json;
     virStorageSourcePtr ret;
+    int rc;

     if (VIR_ALLOC(ret) < 0)
         return NULL;
@@ -2531,13 +2602,15 @@ virStorageSourceNewFromBackingAbsolute(const char *path)
         ret->type = VIR_STORAGE_TYPE_NETWORK;

         /* handle URI formatted backing stores */
-        if (strstr(path, "://")) {
-            if (virStorageSourceParseBackingURI(ret, path) < 0)
-                goto error;
-        } else {
-            if (virStorageSourceParseBackingColon(ret, path) < 0)
-                goto error;
-        }
+        if ((json = STRSKIP(path, "json:")))
+            rc = virStorageSourceParseBackingJSON(ret, json);
+        else if (strstr(path, "://"))
+            rc = virStorageSourceParseBackingURI(ret, path);
+        else
+            rc = virStorageSourceParseBackingColon(ret, path);
+
+        if (rc < 0)
+            goto error;
     }

     return ret;
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index e2ca0b6..aa56b61 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1353,6 +1353,14 @@ mymain(void)
                        "<source protocol='nbd' name='blah'>\n"
                        "  <host name='example.org' port='6000'/>\n"
                        "</source>\n");
+    TEST_BACKING_PARSE(5, "json:", NULL);
+    TEST_BACKING_PARSE(6, "json:asdgsdfg", NULL);
+    TEST_BACKING_PARSE(7, "json:{}", NULL);
+    TEST_BACKING_PARSE(8, "json: { \"file.driver\":\"blah\"}", NULL);
+    TEST_BACKING_PARSE(9, "json:{\"file.driver\":\"file\"}", NULL);
+    TEST_BACKING_PARSE(10, "json:{\"file.driver\":\"file\", "
+                                 "\"file.filename\":\"/path/to/file\"}",
+                       "<source file='/path/to/file'/>\n");

  cleanup:
     /* Final cleanup */
-- 
2.8.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]