From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33149) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1alx4I-0005M2-GY for qemu-devel@nongnu.org; Fri, 01 Apr 2016 07:16:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1alx4E-0001k9-J3 for qemu-devel@nongnu.org; Fri, 01 Apr 2016 07:16:46 -0400 Received: from mail-qk0-x22f.google.com ([2607:f8b0:400d:c09::22f]:34181) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1alx4E-0001k5-Df for qemu-devel@nongnu.org; Fri, 01 Apr 2016 07:16:42 -0400 Received: by mail-qk0-x22f.google.com with SMTP id r184so1724692qkc.1 for ; Fri, 01 Apr 2016 04:16:42 -0700 (PDT) Sender: =?UTF-8?B?TWFyYy1BbmRyw6kgTHVyZWF1?= From: marcandre.lureau@redhat.com Date: Fri, 1 Apr 2016 13:16:14 +0200 Message-Id: <1459509388-6185-5-git-send-email-marcandre.lureau@redhat.com> In-Reply-To: <1459509388-6185-1-git-send-email-marcandre.lureau@redhat.com> References: <1459509388-6185-1-git-send-email-marcandre.lureau@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [PATCH 04/18] char: add wait support for reconnect List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Yuanhan Liu , "Michael S. Tsirkin" , Ilya Maximets , jonshin@cisco.com, Tetsuya Mukawa , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= From: Marc-André Lureau Until now, 'wait' was solely used for listening sockets. However, it can also be useful for 'reconnect' socket kind, where the first open must succeed before continuing. This allows for instance (with other support patches) having vhost-user wait for an initial connection to setup the vhost-net, before eventually accepting new connections. Signed-off-by: Marc-André Lureau --- qemu-char.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 8702931..3e25c08 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3659,7 +3659,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, Error **errp) { bool is_listen = qemu_opt_get_bool(opts, "server", false); - bool is_waitconnect = is_listen && qemu_opt_get_bool(opts, "wait", true); + bool is_wait = qemu_opt_get_bool(opts, "wait", is_listen); bool is_telnet = qemu_opt_get_bool(opts, "telnet", false); bool do_nodelay = !qemu_opt_get_bool(opts, "delay", true); int64_t reconnect = qemu_opt_get_number(opts, "reconnect", 0); @@ -3696,7 +3696,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, sock->has_telnet = true; sock->telnet = is_telnet; sock->has_wait = true; - sock->wait = is_waitconnect; + sock->wait = is_wait; sock->has_reconnect = true; sock->reconnect = reconnect; sock->tls_creds = g_strdup(tls_creds); @@ -4350,7 +4350,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, bool do_nodelay = sock->has_nodelay ? sock->nodelay : false; bool is_listen = sock->has_server ? sock->server : true; bool is_telnet = sock->has_telnet ? sock->telnet : false; - bool is_waitconnect = sock->has_wait ? sock->wait : false; + bool is_wait = sock->has_wait ? sock->wait : false; int64_t reconnect = sock->has_reconnect ? sock->reconnect : 0; ChardevCommon *common = qapi_ChardevSocket_base(sock); QIOChannelSocket *sioc = NULL; @@ -4424,7 +4424,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, } sioc = qio_channel_socket_new(); - if (s->reconnect_time) { + if (s->reconnect_time && !is_wait) { qio_channel_socket_connect_async(sioc, s->addr, qemu_chr_socket_connected, chr, NULL); @@ -4433,7 +4433,7 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, goto error; } s->listen_ioc = sioc; - if (is_waitconnect) { + if (is_wait) { trace_char_socket_waiting(chr->filename); tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr); } @@ -4443,9 +4443,24 @@ static CharDriverState *qmp_chardev_open_socket(const char *id, QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL); } } else { - if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { - goto error; - } + do { + Error *err = NULL; + + if (qio_channel_socket_connect_sync(sioc, s->addr, &err) < 0) { + if (reconnect) { + trace_char_socket_reconnect_error(chr->label, + error_get_pretty(err)); + error_free(err); + continue; + } else { + error_propagate(errp, err); + goto error; + } + } else { + break; + } + } while (true); + tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); } -- 2.5.5