[sheepdog] [PATCH 09/13] nbd: add GUri-based URI parsing version

Marc-André Lureau marcandre.lureau at redhat.com
Thu Jul 9 21:42:30 CEST 2020


Signed-off-by: Marc-André Lureau <marcandre.lureau at redhat.com>
---
 block/nbd.c        | 86 +++++++++++++++++++++++++++++++++++-----------
 util/Makefile.objs |  2 +-
 2 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index faadcab442b..fdc4a53a98f 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -31,7 +31,10 @@
 #include "qemu/osdep.h"
 
 #include "trace.h"
+#ifndef HAVE_GLIB_GURI
 #include "qemu/uri.h"
+#endif
+#include "qemu/error-report.h"
 #include "qemu/option.h"
 #include "qemu/cutils.h"
 #include "qemu/main-loop.h"
@@ -1513,71 +1516,112 @@ static int nbd_client_connect(BlockDriverState *bs, Error **errp)
 /*
  * Parse nbd_open options
  */
-
 static int nbd_parse_uri(const char *filename, QDict *options)
 {
+    const char *p, *scheme, *server, *socket = NULL;
+    int port;
+    bool is_unix;
+
+#ifdef HAVE_GLIB_GURI
+    g_autoptr(GUri) uri = NULL;
+    g_autoptr(GHashTable) params = NULL;
+    g_autoptr(GError) err = NULL;
+
+    uri = g_uri_parse(filename, G_URI_FLAGS_ENCODED_QUERY, &err);
+    if (!uri) {
+        error_report("Failed to parse NBD URI: %s", err->message);
+        return -EINVAL;
+    }
+
+    p = g_uri_get_path(uri);
+    scheme = g_uri_get_scheme(uri);
+    server = g_uri_get_host(uri);
+    port = g_uri_get_port(uri);
+#else
     g_autoptr(URI) uri = NULL;
     g_autoptr(QueryParams) qp = NULL;
-    const char *p;
-    bool is_unix;
 
     uri = uri_parse(filename);
     if (!uri) {
         return -EINVAL;
     }
 
+    p = uri->path ? uri->path : "";
+    scheme = uri->scheme;
+    server = uri->server;
+    port = uri->port;
+#endif
     /* transport */
-    if (!g_strcmp0(uri->scheme, "nbd")) {
+    if (!g_strcmp0(scheme, "nbd")) {
         is_unix = false;
-    } else if (!g_strcmp0(uri->scheme, "nbd+tcp")) {
+    } else if (!g_strcmp0(scheme, "nbd+tcp")) {
         is_unix = false;
-    } else if (!g_strcmp0(uri->scheme, "nbd+unix")) {
+    } else if (!g_strcmp0(scheme, "nbd+unix")) {
         is_unix = true;
     } else {
         return -EINVAL;
     }
-
-    p = uri->path ? uri->path : "";
-    if (p[0] == '/') {
-        p++;
+#ifdef HAVE_GLIB_GURI
+    params = g_uri_parse_params(g_uri_get_query(uri), -1,
+                                "&;", G_URI_PARAMS_NONE, &err);
+    if (err) {
+        error_report("Failed to parse NBD URI query: %s", err->message);
+        return -EINVAL;
     }
-    if (p[0]) {
-        qdict_put_str(options, "export", p);
+    if ((is_unix && g_hash_table_size(params) != 1) ||
+        (!is_unix && g_hash_table_size(params) != 0)) {
+        return -EINVAL;
     }
-
+    if (is_unix) {
+        socket = g_hash_table_lookup(params, "socket");
+    }
+#else
     qp = query_params_parse(uri->query);
     if (qp->n > 1 || (is_unix && !qp->n) || (!is_unix && qp->n)) {
         return -EINVAL;
     }
+    if (is_unix) {
+        if (!g_str_equal(qp->p[0].name, "socket")) {
+            return -EINVAL;
+        }
+        socket = qp->p[0].value;
+    }
+#endif
+    if (p[0] == '/') {
+        p++;
+    }
+    if (p[0]) {
+        qdict_put_str(options, "export", p);
+    }
 
     if (is_unix) {
         /* nbd+unix:///export?socket=path */
-        if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) {
+        if (server || port > 0) {
             return -EINVAL;
         }
         qdict_put_str(options, "server.type", "unix");
-        qdict_put_str(options, "server.path", qp->p[0].value);
+        qdict_put_str(options, "server.path", socket);
     } else {
         QString *host;
         g_autofree char *port_str = NULL;
 
         /* nbd[+tcp]://host[:port]/export */
-        if (!uri->server) {
+        if (!server) {
             return -EINVAL;
         }
 
         /* strip braces from literal IPv6 address */
-        if (uri->server[0] == '[') {
-            host = qstring_from_substr(uri->server, 1,
-                                       strlen(uri->server) - 1);
+        if (server[0] == '[') {
+            host = qstring_from_substr(server, 1,
+                                       strlen(server) - 1);
         } else {
-            host = qstring_from_str(uri->server);
+            host = qstring_from_str(server);
         }
 
         qdict_put_str(options, "server.type", "inet");
         qdict_put(options, "server.host", host);
 
-        port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);
+        port_str = g_strdup_printf("%d", port > 0 ? port : NBD_DEFAULT_PORT);
         qdict_put_str(options, "server.port", port_str);
     }
 
diff --git a/util/Makefile.objs b/util/Makefile.objs
index cc5e37177af..5a162178ae9 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -73,7 +73,7 @@ util-obj-y += qemu-timer.o
 util-obj-y += thread-pool.o
 util-obj-y += throttle.o
 util-obj-y += timed-average.o
-util-obj-y += uri.o
+util-obj-$(call lnot,$(HAVE_GLIB_GURI)) += uri.o
 
 util-obj-$(CONFIG_LINUX) += vfio-helpers.o
 util-obj-$(CONFIG_INOTIFY1) += filemonitor-inotify.o
-- 
2.27.0.221.ga08a83db2b



More information about the sheepdog mailing list