From patchwork Wed Mar 5 00:38:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 326554 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 719312C020F for ; Wed, 5 Mar 2014 11:40:55 +1100 (EST) Received: from localhost ([::1]:49469 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKztF-0004CC-95 for incoming@patchwork.ozlabs.org; Tue, 04 Mar 2014 19:40:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53643) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKzsc-0003rH-Sz for qemu-devel@nongnu.org; Tue, 04 Mar 2014 19:40:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WKzsV-0000Vk-RC for qemu-devel@nongnu.org; Tue, 04 Mar 2014 19:40:14 -0500 Received: from mail-qa0-x22a.google.com ([2607:f8b0:400d:c00::22a]:56913) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKzsV-0000VP-Kx for qemu-devel@nongnu.org; Tue, 04 Mar 2014 19:40:07 -0500 Received: by mail-qa0-f42.google.com with SMTP id k15so324641qaq.15 for ; Tue, 04 Mar 2014 16:40:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=yqwEfe5ldU4UrdTiMEQHty7AyDvPnUq7s7Npx/oDX60=; b=EsMPO/6AEo+wf6+C+52Qtwi/kJa5iNqx3VZCKHK1bDNXtDCYj9sDCVkSUvxjIWlVcr 7kHPmemWCSkXufZ5ZNw/dyG3UAFbYnV6H6EVvFicgr5q2iAvMDYSEUo7H/yR8eAtaY63 p19JM8VHvrkFTv+FXBjbzY4LXsxtM3Jn/5V3mZGuXizgbq5FMsIvtboxuZ1R+IP0gGSs CUhMyRQxWMWwh5Z1ce/2A9ZMIiw5bPl3Ca/RrBjcgsttRPtgDiO0H1FiLIwb7Ba5utPb ohlAh1gn8OGzALQ2HIP8q4VTFfNvW5EeOrEa33uYtylVCHq2GjRFCAS0RGY2HLflwkuO azUA== X-Received: by 10.224.165.83 with SMTP id h19mr427819qay.27.1393980007199; Tue, 04 Mar 2014 16:40:07 -0800 (PST) Received: from t430.minyard.home (pool-173-57-152-84.dllstx.fios.verizon.net. [173.57.152.84]) by mx.google.com with ESMTPSA id fn10sm1600848obb.12.2014.03.04.16.40.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Mar 2014 16:40:06 -0800 (PST) Received: from t430.minyard.home (t430.minyard.home [127.0.0.1]) by t430.minyard.home (8.14.7/8.14.7) with ESMTP id s250dstd009907; Tue, 4 Mar 2014 18:40:04 -0600 Received: (from cminyard@localhost) by t430.minyard.home (8.14.7/8.14.7/Submit) id s250diuU009896; Tue, 4 Mar 2014 18:39:44 -0600 From: minyard@acm.org To: qemu-devel@nongnu.org Date: Tue, 4 Mar 2014 18:38:53 -0600 Message-Id: <1393979937-9082-4-git-send-email-minyard@acm.org> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1393979937-9082-1-git-send-email-minyard@acm.org> References: <1393979937-9082-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c00::22a Cc: bcketchum@gmail.com, Corey Minyard , hwd@huawei.com, afaerber@suse.de, mst@redhat.com Subject: [Qemu-devel] [PATCH 3/7] qemu-char: Wait until socket connect to report connected X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Corey Minyard The socket code was reporting that a socket connection was connected as soon as the connect call was issued. If the connection failed, it would then report it was not connected. With the reconnect code, it's better to wait until the connection is actually operational before reporting that the socket is connected. Signed-off-by: Corey Minyard --- qemu-char.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index d9838aa..6d6dd36 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2310,9 +2310,10 @@ static CharDriverState *qemu_chr_open_udp(CharDriverState *chr, QemuOpts *opts) typedef struct { GIOChannel *chan, *listen_chan; + int waitsrc; guint listen_tag; int fd, listen_fd; - int connected; + enum { TCP_NOT_CONNECTED, TCP_WAITING_CONNECT, TCP_CONNECTED } state; int max_size; int do_telnetopt; int do_nodelay; @@ -2325,7 +2326,7 @@ static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len) { TCPCharDriver *s = chr->opaque; - if (s->connected) { + if (s->state == TCP_CONNECTED) { return io_channel_send(s->chan, buf, len); } else { /* XXX: indicate an error ? */ @@ -2337,7 +2338,7 @@ static int tcp_chr_read_poll(void *opaque) { CharDriverState *chr = opaque; TCPCharDriver *s = chr->opaque; - if (!s->connected) + if (s->state != TCP_CONNECTED) return 0; s->max_size = qemu_chr_be_can_write(chr); return s->max_size; @@ -2482,7 +2483,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) uint8_t buf[READ_BUF_LEN]; int len, size; - if (!s->connected || s->max_size <= 0) { + if (s->state != TCP_CONNECTED || s->max_size <= 0) { return TRUE; } len = sizeof(buf); @@ -2491,7 +2492,7 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque) size = tcp_chr_recv(chr, (void *)buf, len); if (size == 0) { /* connection closed */ - s->connected = 0; + s->state = TCP_NOT_CONNECTED; if (s->listen_chan) { s->listen_tag = g_io_add_watch(s->listen_chan, G_IO_IN, tcp_chr_accept, chr); } @@ -2518,17 +2519,48 @@ CharDriverState *qemu_chr_open_eventfd(CharDriverState *chr, int eventfd) } #endif -static void tcp_chr_connect(void *opaque) +static gboolean tcp_wait_connect(GIOChannel *source, + GIOCondition condition, + gpointer opaque) { CharDriverState *chr = opaque; TCPCharDriver *s = chr->opaque; - s->connected = 1; + if (s->state != TCP_WAITING_CONNECT) { + return FALSE; + } + if (condition & G_IO_ERR || condition & G_IO_HUP) { + /* The connected failed */ + s->state = TCP_NOT_CONNECTED; + g_io_channel_unref(s->chan); + s->chan = NULL; + closesocket(s->fd); + s->fd = -1; + return FALSE; + } + + s->state = TCP_CONNECTED; if (s->chan) { chr->fd_in_tag = io_add_watch_poll(s->chan, tcp_chr_read_poll, tcp_chr_read, chr); } qemu_chr_be_generic_open(chr); + return FALSE; +} + +static void tcp_chr_connect(void *opaque) +{ + CharDriverState *chr = opaque; + TCPCharDriver *s = chr->opaque; + + s->state = TCP_WAITING_CONNECT; + if (s->chan) { + /* Wait until write becomes ready before reporting connected. */ + s->waitsrc = g_io_add_watch(s->chan, + G_IO_OUT | G_IO_HUP | G_IO_ERR, + tcp_wait_connect, + chr); + } } #define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c; @@ -2650,7 +2682,7 @@ static CharDriverState *qemu_chr_open_socket_fd(CharDriverState *chr, s = g_malloc0(sizeof(TCPCharDriver)); - s->connected = 0; + s->state = TCP_NOT_CONNECTED; s->fd = -1; s->listen_fd = -1; s->msgfd = -1; @@ -2695,7 +2727,6 @@ static CharDriverState *qemu_chr_open_socket_fd(CharDriverState *chr, s->do_telnetopt = 1; } } else { - s->connected = 1; s->fd = fd; socket_set_nodelay(fd); s->chan = io_channel_from_socket(s->fd);