Re: [Qemu-block] [PATCH v5 06/13] block/nbd: Accept SocketAddress

2016-10-25 Thread Kevin Wolf
Am 25.10.2016 um 15:11 hat Max Reitz geschrieben:
> Add a new option "server" to the NBD block driver which accepts a
> SocketAddress.
> 
> "path", "host" and "port" are still supported as legacy options and are
> mapped to their corresponding SocketAddress representation.
> 
> Signed-off-by: Max Reitz 

Reviewed-by: Kevin Wolf 



[Qemu-block] [PATCH v5 06/13] block/nbd: Accept SocketAddress

2016-10-25 Thread Max Reitz
Add a new option "server" to the NBD block driver which accepts a
SocketAddress.

"path", "host" and "port" are still supported as legacy options and are
mapped to their corresponding SocketAddress representation.

Signed-off-by: Max Reitz 
---
 block/nbd.c   | 175 +++---
 tests/qemu-iotests/051.out|   4 +-
 tests/qemu-iotests/051.pc.out |   4 +-
 3 files changed, 117 insertions(+), 66 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index cdab20f..a778692 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -32,6 +32,9 @@
 #include "qemu/uri.h"
 #include "block/block_int.h"
 #include "qemu/module.h"
+#include "qapi-visit.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qint.h"
@@ -44,7 +47,8 @@ typedef struct BDRVNBDState {
 NbdClientSession client;
 
 /* For nbd_refresh_filename() */
-char *path, *host, *port, *export, *tlscredsid;
+SocketAddress *saddr;
+char *export, *tlscredsid;
 } BDRVNBDState;
 
 static int nbd_parse_uri(const char *filename, QDict *options)
@@ -131,7 +135,8 @@ static bool nbd_has_filename_options_conflict(QDict 
*options, Error **errp)
 if (!strcmp(e->key, "host") ||
 !strcmp(e->key, "port") ||
 !strcmp(e->key, "path") ||
-!strcmp(e->key, "export"))
+!strcmp(e->key, "export") ||
+strstart(e->key, "server.", NULL))
 {
 error_setg(errp, "Option '%s' cannot be used with a file name",
e->key);
@@ -205,50 +210,81 @@ out:
 g_free(file);
 }
 
-static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
+static bool nbd_process_legacy_socket_options(QDict *output_options,
+  QemuOpts *legacy_opts,
+  Error **errp)
 {
-SocketAddress *saddr;
+const char *path = qemu_opt_get(legacy_opts, "path");
+const char *host = qemu_opt_get(legacy_opts, "host");
+const char *port = qemu_opt_get(legacy_opts, "port");
+const QDictEntry *e;
 
-s->path = g_strdup(qemu_opt_get(opts, "path"));
-s->host = g_strdup(qemu_opt_get(opts, "host"));
-s->port = g_strdup(qemu_opt_get(opts, "port"));
+if (!path && !host && !port) {
+return true;
+}
 
-if (!s->path == !s->host) {
-if (s->path) {
-error_setg(errp, "path and host may not be used at the same time");
-} else {
-error_setg(errp, "one of path and host must be specified");
+for (e = qdict_first(output_options); e; e = qdict_next(output_options, e))
+{
+if (strstart(e->key, "server.", NULL)) {
+error_setg(errp, "Cannot use 'server' and path/host/port at the "
+   "same time");
+return false;
 }
-return NULL;
 }
-if (s->port && !s->host) {
-error_setg(errp, "port may not be used without host");
-return NULL;
+
+if (path && host) {
+error_setg(errp, "path and host may not be used at the same time");
+return false;
+} else if (path) {
+if (port) {
+error_setg(errp, "port may not be used without host");
+return false;
+}
+
+qdict_put(output_options, "server.type", qstring_from_str("unix"));
+qdict_put(output_options, "server.data.path", qstring_from_str(path));
+} else if (host) {
+qdict_put(output_options, "server.type", qstring_from_str("inet"));
+qdict_put(output_options, "server.data.host", qstring_from_str(host));
+qdict_put(output_options, "server.data.port",
+  qstring_from_str(port ?: stringify(NBD_DEFAULT_PORT)));
 }
 
-saddr = g_new0(SocketAddress, 1);
+return true;
+}
 
-if (s->path) {
-UnixSocketAddress *q_unix;
-saddr->type = SOCKET_ADDRESS_KIND_UNIX;
-q_unix = saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
-q_unix->path = g_strdup(s->path);
-} else {
-InetSocketAddress *inet;
-
-saddr->type = SOCKET_ADDRESS_KIND_INET;
-inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
-inet->host = g_strdup(s->host);
-inet->port = g_strdup(s->port);
-if (!inet->port) {
-inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
-}
+static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, Error **errp)
+{
+SocketAddress *saddr = NULL;
+QDict *addr = NULL;
+QObject *crumpled_addr = NULL;
+Visitor *iv = NULL;
+Error *local_err = NULL;
+
+qdict_extract_subqdict(options, , "server.");
+if (!qdict_size(addr)) {
+error_setg(errp, "NBD server address missing");
+goto done;
 }
 
-s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
+crumpled_addr