[PATCH 03/25] util: storage: Add parser for qemu's "json" backing pseudo-protocol

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

 



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 6016a3b..46bbfb5 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -1355,6 +1355,14 @@ mymain(void)
                        "<source protocol='nbd' name='blah'>\n"
                        "  <host name='example.org' port='6000'/>\n"
                        "</source>\n");
+    TEST_BACKING_PARSE("json:", NULL);
+    TEST_BACKING_PARSE("json:asdgsdfg", NULL);
+    TEST_BACKING_PARSE("json:{}", NULL);
+    TEST_BACKING_PARSE("json: { \"file.driver\":\"blah\"}", NULL);
+    TEST_BACKING_PARSE("json:{\"file.driver\":\"file\"}", NULL);
+    TEST_BACKING_PARSE("json:{\"file.driver\":\"file\", "
+                             "\"file.filename\":\"/path/to/file\"}",
+                       "<source file='/path/to/file'/>\n");

  cleanup:
     /* Final cleanup */
-- 
2.9.0

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]